c重构为c++踩坑记录
CMakeList中的Project(xxx)
- 可以只起名,不限定语言,这样的话在add_library中添加的所有路径/文件都会被cmake解析到,例如:
project(aaa)
add_library(${SO_NAME} SHARED ${SRC}
src/main.cpp
src/test.c)
-
如果在project中限定语言,就表示只接受这几种类型的语言,其他语言的文件添加了也不会被cmake加载(实验:去掉括号中的C,并且在test.c中随便写点错误,并不会被编译器解析到)
project(aaa C CXX) -
头文件添加进来也没用,甚至也不会添加进include_path搜索
关键字
error: expected initializer before 'extern' __BEGIN_DECLS

- 多半是因为头文件的声明后面没加分号
编写gtest(so库连接到bin)踩坑
情况是:我的工程需要从c-->c++ 但是c++工程仍然需要调用一些c库的接口,这些c接口并没有在声明的时候加extern c, 于是我发现我的工程编译出来的so,如果被其他bin链接,会报错提示找不到符号

- 根因分析:c/c++工程的cmakelist,至少需要包含:
link_directories{
/pathA
/pathB
}
add_library(myProject SHARED main.cpp)
target_link_libraries(myProject libxxx.so yyy zzz)
- 其中 add_library就是编译为so,即libmyProject.so,add_executable是编译为bin
- 编译为so/bin的区别在于,编译为so时,只需确保连接的所有其他so库在link_directories中即可,但是编译为bin,还会校验符号表
- 符号表的查看方式: nm xxx/build/path/libmyProject.so (具体路径取决于build.sh 或 install命令指定)
我把我直接编译出来的so(没有原则性问题不会报错)查看一下符号表
nm ./build/libmyProject.so | grep func
发现显示为 T _Z20funcPKiPKdii

只要带有_Z修饰的就是表示被C++名称修饰过了,这就是问题所在!!
- 因为被名称修饰过,所以我的其余c++文件想要调用它就会在so符号表中找不到他,因为我调用的c库没有使用extern "C" 修饰它的声明。导致我调用的这个c接口在它所在的so中符号表为不带_Z的,但是因为我名称修饰他了,就相当于符号表变了,就找不到了!!!!

浙公网安备 33010602011771号