CMake和静态链接 [英] CMake and Static Linking

查看:1528
本文介绍了CMake和静态链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在项目中使用CMake,我试图静态链接一些库。
我设置了:

 设置(BUILD_SHARED_LIBS OFF)
设置(CMAKE_EXE_LINKER_FLAGS-static-libgcc -static-libstdc ++ -static)
set_target_properties(icarus PROPERTIES LINK_SEARCH_END_STATIC 1)



目前项目导入:

  libPocoNet.a 
libPocoUtil.a
libPocoXML.a
libPocoFoundation.a
libmysqlclient.a
libmysqlpp.a
libcrypto ++。a
CUDA

找到所有库,当做动态/共享链接时,它们工作正常。
我也尝试设置编译标志:

  set(GCC_CXX_FLAGS $ {GCC_CXX_FLAGS}-static-libgcc  - static-libstdc ++ -static)

但没有效果。
虽然我在编译时没有遇到任何问题,但是在上面的库中发现的调用,链接会抛出很多未定义的引用错误,例如:

 未定义引用`mysql_thread_init'
未定义引用`mysql_real_query'
未定义引用`pthread_mutex_unlock'
未定义引用`Poco :: ErrorHandler: :handle()'

不是按照特定的顺序, >

看看GCC的最后一行:

  / usr / bin / c ++ -g -g -static-libgcc -static-libstdc ++ -static [* .cpp文件列表] 
-o icarus -rdynamic /usr/local/lib/libPocoFoundation.a / usr / local / lib / libPocoNet.a
/usr/local/lib/libPocoUtil.a /usr/local/lib/libPocoXML.a
-Wl,-Bstatic -lmysqlclient -lmysqlpp -lcrypto ++

这让我想到:


  1. Poco库链接为动态,并且没有-Wl-Bstatic标志?

  2. mysqlclient,mysqlpp和crypto ++似乎设置为静态链接,但仍然会出现错误

  3. ol>

    所以,有人可以向我解释一下:


    1. 使用CMake的静态链接

    2. 是否需要设置CMAKE_EXE_LINKER_FLAGS?

    3. 我应该强制静态链接上述库, ?

    请原谅我,如果这些太多或太本地化的问题,我没有尝试过,我不能

    解决方案

    我已经通过使用以下方法解决了我的问题:

     #动态/共享库
    ...
    #Static start
    set_target_properties(icarus PROPERTIES LINK_SEARCH_START_STATIC 1 )
    set_target_properties(icarus PROPERTIES LINK_SEARCH_END_STATIC 1)
    set(CMAKE_FIND_LIBRARY_SUFFIXES.a)
    #Static Libs
    ...
    #Set链接器标志
    set(CMAKE_EXE_LINKER_FLAGS-static-libgcc -static-libstdc ++)

    c $ c> -static 这会创建其他大问题,并且可以基本上混合静态和动态库。



    只要静态库是正确的,只要满足静态库的依赖性,我得到一个ELF,它加载什么是动态的(即在我的情况下,mysqlclient,libmysql ++)和静态其他所有(crypto ++,PocoNet,PocoUtil,PocoXML,PocoFoundation)。



    请记住静态链接库有自己的依赖。使用readelf -d应用程序检查我的调试应用程序,我看到:

     偏移0x508f88的动态部分包含28个条目:
    标签类型名称/值
    0x0000000000000001(NEEDED)共享库:[libmysqlpp.so.3]
    0x0000000000000001(NEEDED)共享库:[libmysqlclient.so.18]
    0x0000000000000001库:[libm.so.6]
    0x0000000000000001(NEEDED)共享库:[libc.so.6]
    0x0000000000000001(NEEDED)共享库:[ld-linux-x86-64.so.2 ]
    0x0000000000000001(NEEDED)共享库:[libpthread.so.0]

    pthread是由Poco :: Runnable导入的,libm是用于数学操作等等。
    我仍​​然不知道这是否正确的方式使用CMake部分静态链接。



    在Debian打包库的情况下,如crypto ++,mysql ++,mysqlclient,只是找到* .a库工作,但是在Poco库的情况下,它只能得到库的完整路径和名称,但不是标志, -Bdynamic 只能通过使用以上行关闭。



    注意:Poco可以没有 -static-libstdc ++



    我希望这可以帮助任何人停留在类似的东西。 p>

    I'm using CMake in a project, and I'm trying to statically link some libraries. I've set:

    set(BUILD_SHARED_LIBS OFF)
    set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")
    set_target_properties(icarus PROPERTIES LINK_SEARCH_END_STATIC 1)
    

    And I've made sure when looking for the actual libraries that I have the *.a version of them.

    Currently the project imports:

    libPocoNet.a 
    libPocoUtil.a 
    libPocoXML.a 
    libPocoFoundation.a 
    libmysqlclient.a 
    libmysqlpp.a 
    libcrypto++.a 
    CUDA
    

    All libraries are found, and when doing a dynamic/shared linkage, they work fine. I have also tried to set compilation flags:

    set(GCC_CXX_FLAGS ${GCC_CXX_FLAGS} "-static-libgcc -static-libstdc++ -static")
    

    But to no avail. While I get no issues while compiling, linkage is throwing alot of undefined reference errors for calls found in the above libraries, i.e:

    undefined reference to `mysql_thread_init'
    undefined reference to `mysql_real_query'
    undefined reference to `pthread_mutex_unlock'
    undefined reference to `Poco::ErrorHandler::handle()'
    

    Not in that particular order, and numerous errors for each library.

    Looking at the last line of GCC I see:

    /usr/bin/c++   -g -g  -static-libgcc -static-libstdc++ -static [list of *.cpp files]
    -o icarus -rdynamic /usr/local/lib/libPocoFoundation.a /usr/local/lib/libPocoNet.a
    /usr/local/lib/libPocoUtil.a /usr/local/lib/libPocoXML.a 
    -Wl,-Bstatic -lmysqlclient -lmysqlpp -lcrypto++
    

    Which makes me wonder:

    1. Why are Poco libraries linked as -rdynamic, and there is no -Wl -Bstatic flag? As if they are skipped/excluded from static linkage.
    2. mysqlclient, mysqlpp and crypto++ seem to be set for static linkage, yet I still get errors

    So, could someone please explain to me:

    1. How do I setup for partial static linkage using CMake
    2. Is CMAKE_EXE_LINKER_FLAGS the only one I need to set?
    3. Should I be forcing static linking for mentioned libraries but not for entire project?

    Please excuse me if those are too many or too localized questions, I haven't tried this before, and I can't seem to find much info on the net.

    解决方案

    I've managed to solve my problem by using the following:

    #Dynamic/Shared Libs
    ...
    #Static start
    set_target_properties(icarus PROPERTIES LINK_SEARCH_START_STATIC 1)
    set_target_properties(icarus PROPERTIES LINK_SEARCH_END_STATIC 1)
    set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
    #Static Libs
    ...
    #Set Linker flags
    set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
    

    This works without passing a -static which creates other big issues, and can essentially mix static and dynamic libraries.

    As long as the order of static libraries is correct, and as long as dependencies of static libraries are satisfied, I get an ELF which loads what are are dynamic (i.e. in my case mysqlclient, libmysql++) and static all the rest (crypto++, PocoNet, PocoUtil, PocoXML, PocoFoundation).

    Bear in mind that static linked libraries have their own dependencies. Examining my debug application using readelf -d app, I see:

    Dynamic section at offset 0x508f88 contains 28 entries:
      Tag        Type                         Name/Value
     0x0000000000000001 (NEEDED)             Shared library: [libmysqlpp.so.3]
     0x0000000000000001 (NEEDED)             Shared library: [libmysqlclient.so.18]
     0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
     0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
     0x0000000000000001 (NEEDED)             Shared library: [ld-linux-x86-64.so.2]
     0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
    

    I know that pthread is imported by Poco::Runnable, libm is for math operations, etc. I am still unaware if this is the right way to use CMake for partial static linking.

    In the case of Debian packaged libraries, such as crypto++, mysql++, mysqlclient, simply finding the *.a library worked, but in case of Poco Libraries, which only got me the full path and name of the library, but not a flag, -Bdynamic could only be turned off by using the above lines.

    Note: Poco could not be linked statically, without -static-libstdc++

    I hope this helps anyone stuck at something similar.

    这篇关于CMake和静态链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆