注意:以下都是基于CMake来配置项目
现在有三个项目:libA,一个代码库项目;libB,使用libA的另一个动态库;exeC,一个使用libA的可执行程序。
按照正常设置,libA生成动态库,libB和exeC使用libA,都没问题,完美编译通过并可正常执行。但由于发布问题,libA不想发布到用户手中,所以想把libA做成静态库,libB封装libA,将libA静态链接到libB中,同样exeC静态链接libA到exeC中。
于是如下设置libA,在libA的add_library()中增加STATIC标志:
# Build library add_library(${target} STATIC ${sources} ${headers} #${rc_file} )
未做任何变化,libA能生成静态库,但是libB和exeC都报错:
exeC报的错:
[100%] Linking CXX executable ..\..\..\test_apid.exe CMakeFiles\test_api.dir/objects.a(main.cpp.obj): In function `main': E:/SerialPortDevice/source/demo/test_api/main.cpp:42: undefined reference to `__imp_CreateSerialPort' E:/SerialPortDevice/source/demo/test_api/main.cpp:45: undefined reference to `__imp_RegisterReceivedDataCallback' E:/SerialPortDevice/source/demo/test_api/main.cpp:48: undefined reference to `__imp_RegisterSerialPortStatusChangedCallback' E:/SerialPortDevice/source/demo/test_api/main.cpp:52: undefined reference to `__imp_OpenSerialPort' E:/SerialPortDevice/source/demo/test_api/main.cpp:71: undefined reference to `__imp_DestroySerialPort' E:/SerialPortDevice/source/demo/test_api/main.cpp:78: undefined reference to `__imp_GetSerialPortStatus'
libB的就不列出来了,这个好理解(没弄懂前还真不好理解 :-) ),就是还是在包含头文件时,头文件中的函数修饰符为import了:
// dynamic library #ifdef SERIALPORTRW_EXPORTS #define SERIALPORTRW_API __declspec(dllexport) #else #define SERIALPORTRW_API __declspec(dllimport) #endif
知道了原因,解决办法就有了:把函数修饰符置为空,因为静态函数导出时是不需要 _deckspec(dllexport)的,在头文件中增加一段定义,同时在CMake配置中声明SERIALPORTRW_STATIC变量:
导出的头文件中:
// dynamic library #ifdef SERIALPORTRW_EXPORTS #define SERIALPORTRW_API __declspec(dllexport) #else #define SERIALPORTRW_API __declspec(dllimport) #endif // static library #ifdef SERIALPORTRW_STATIC #undef SERIALPORTRW_API #define SERIALPORTRW_API // empty #endif
CMake中:
# # Compile definitions # target_compile_definitions(${target} PRIVATE #-DSERIALPORTRW_EXPORTS -DSERIALPORTRW_STATIC PUBLIC $<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:${target_upper}_STATIC_DEFINE> ${DEFAULT_COMPILE_DEFINITIONS} INTERFACE )
同样,在使用libA的项目中同样要定义SERIALPORTRW_STATIC变量。
如此设置后,完美解决问题!