六月 21, 2017

解决mingw中gcc生成静态库,另一个动态库或exe使用此静态库的问题

Written by

注意:以下都是基于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变量。

如此设置后,完美解决问题!

 

Category : C/C++

Tags :

发表评论

电子邮件地址不会被公开。

Proudly powered by WordPress and Sweet Tech Theme