我遇到的问题有点难以解释,但我会尝试用一种简单的方式(我对如何解决它没有更多的想法)。
嗯,基本上,我们在linux上有一个非常大的C ++项目。这个项目是用makefile编译的,但在新版本中我们将它迁移到CMake。 CMake版本编译正常,但加载库时的行为有点不同。
以下是该场景:我有一个包含以下文件的文件夹:
/appserver/appserver_cmake (the binary compiled using cmake)
/appserver/appserver_original (the binary compiled using the makefiles)
/appserver/dbsrv.so (the library the program is trying to load)
有一个名为“tTOPClient”的类,它在可执行文件内部和库内编译。这个想法是:如果库存在,程序应该执行库中的函数。否则,它应该执行自己的功能。
这是执行appserver_original时的堆栈:
bAdvplConn=0 '\000') at ../fatclient/clientconn.cpp:260
#1 0xb6396fe2 in tTOPClient::m4GLConnect (this=0x2075d858, server=0x2075e3d4 "(local)", environment=0x2075e404 "ORACLE",
user=0x203c6731 "user") at ../fatclient/clientconn.cpp:255
#2 0xb63a0f1d in v40TC_m4GLConnect (who=0x2075d858, toServer=0x2075e3d4 "(local)", init_prm=0x2075e404 "@!!@ORACLE/ora10g_v1002t", usr=0x203c6731 "user")
at ../fatclient/topapi40.cpp:63
#3 0x0866e49c in tTopDriver::APTC_Connect (this=0x2075e4d0, who=0x2075d858, toServer=0x2075e3d4 "(local)", conn_str=0x2075e404 "ORACLE",
usrname=0x203c6731 "user", nSeed=-1230926992) at ./lib/top.cpp:3718
#4 0x0866d0eb in tTopDriver::Connect (this=0x2075e4d0) at ./lib/top.cpp:3314
总之,调用顺序:
tTopDriver::Connect (inside the executable)
tTopDriver::APTC_Connect (inside the executable, will call a library's function)
v40TC_m4GLConnect (inside the library)
tTOPClient::m4GLConnect (inside the library)
当我运行“appserver_cmake”时,“APTC_Connect”正在调用库的“v40TC_m4GLConnect”,但是这个函数被称为可执行文件中的“tTOPClient :: m4GLConnect”,而不是内部的那个。
这是堆栈:
bAdvplConn=0 '\000') at /home/user/adv/trunk/topconnect/4.0/client/clientconn.cpp:207
#1 0x08abe8d2 in tTOPClient::m4GLConnect (this=0x20a1d528, server=0x20a1d78c "(local)", environment=0x20a1ffcc "ORACLE",
user=0x20600c69 "user") at /home/user/adv/trunk/topconnect/4.0/client/clientconn.cpp:202
#2 0xae1a0f1d in v40TC_m4GLConnect (who=0x20a1d528, toServer=0x20a1d78c "(local)", init_prm=0x20a1ffcc "ORACLE", usr=0x20600c69 "user")
at ../fatclient/topapi40.cpp:63
#3 0x08982730 in tTopDriver::APTC_Connect (this=0x209f0780, who=0x20a1d528, toServer=0x20a1d78c "(local)", conn_str=0x20a1ffcc "ORACLE",
usrname=0x20600c69 "user", nSeed=-1335784592) at /home/user/adv/trunk/lib/top.cpp:3718
#4 0x0898137f in tTopDriver::Connect (this=0x209f0780) at /home/user/adv/trunk/lib/top.cpp:3314
总结:
tTopDriver::Connect (inside the executable)
tTopDriver::APTC_Connect (inside the executable, will call a library's function)
v40TC_m4GLConnect (inside the library)
tTOPClient::m4GLConnect (inside the executable!!!)
有人知道可能导致这种不同行为的原因吗? makefile和CMakeLists太大了,不能在这里发布,但我比较了它们,它们看起来很相似。我试图做一个小例子,但我无法重现这个问题。
答案 0 :(得分:2)
cmake
和make
对生成的可执行文件没有直接影响,但只调用编译器。编译器结果由其输入参数完全指定,因此如果cmake
和make
输出相同的编译器调用,则生成的可执行文件应显示相同的行为。
简而言之:比较make
和cmake
的输出(您可能必须给cmake
一些标志,以便显示真实的调用而不是默认的无用进度指示器) ,并查看编译器调用不同的(grep
,sort
,diff
)。
答案 1 :(得分:1)
我还怀疑将不同的标志传递给编译器或链接器。我会编译所有内容,然后只触摸一个cpp文件并编译cmake构建,如下所示:
VERBOSE = 1 make -j1>登录cmake.txt
VERBOSE = 1导致显示传递给gcc的参数。然后使用旧的makefile进行编译
make -f Makefile.old>登录oldmakefile.txt
当您在两个编译器/链接器调用中找到不同的标志时,请查看以下cmake变量:
有关变量含义的信息在the cmake wiki
中