强制CMake使用静态库

时间:2013-09-19 09:41:51

标签: gcc cmake static-libraries static-linking gfortran

[从CMake帮助列表中无耻地交叉发布]

我正在尝试尽可能静态地创建二进制文件。我得到的fortran代码已经将X11和quadmath作为依赖项了,我遇到了很多问题(也许这些问题中的每一个都应该是一个不同的问题?):

  • 我的变量目前是

    set(CMAKE_LIBRARY_PATH /usr/X11/lib /usr/X11/include/X11 ${CMAKE_LIBRARY_PATH})
    find_package(X11 REQUIRED)
    find_library(X11 NAMES X11.a PATHS /usr/X11/include/X11/ /usr/X11/lib)
    find_library(X11_Xaw_LIB NAMES Xaw Xaw /usr/X11/include/X11/ /usr/X11/lib ${X11_LIB_SEARCH_PATH})
    find_library(Xaw Xaw7 PATHS ${X11_LIB_SEARCH_PATH})
    
    set(CMAKE_LIBRARY_PATH /usr/lib/gcc/x86_64-linux-gnu/4.7 /usr/lib/gcc/x86_64-linux-gnu/4.7/x32 /usr/lib/gcc/x86_64-linux-gnu/4.7/32 ${CMAKE_LIBRARY_PATH})
    
    find_library(quadmath NAMES quadmath.a)
    
    set(BUILD_SHARED_LIBS ON)
    set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
    set(LINK_SEARCH_START_STATIC TRUE)
    set(LINK_SEARCH_END_STATIC TRUE)
    
    set(SHARED_LIBS OFF)
    set(STATIC_LIBS ON)
    
    set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
    
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
    

使用这些,CMake尝试静态地构建每个程序(如预期的那样) - 然而,它失败了,因为我没有Xaw.a - 我无法确定这是否真的应该存在。我已经安装了最新的libxaw7-dev,我希望能解决它。一种选择是自己编译X11库,但我真的不想这样做......

  • 如果我只注释set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static"),那么CMake会编译所有内容,但是会为每个程序使用共享库,即使我指定了.a X11的位置我的find_library()电话中的图书馆。我希望CMake尽可能使用.a文件,然后只使用共享库 - 有没有办法强制这种行为?

  • 是否有人知道此处描述的错误修复程序:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46539;因此gfortran似乎无法静态链接libquadmath?我尝试使用gcc修复但我无法让CMake识别libgfortran标志:

    cmake -DCMAKE_Fortran_COMPILER=gcc -DCMAKE_Fortran_FLAGS=-gfortran
    

结果

-- The Fortran compiler identification is unknown
-- Check for working Fortran compiler: /usr/bin/gcc
-- Check for working Fortran compiler: /usr/bin/gcc  -- broken
CMake Error at /usr/share/cmake-2.8/Modules/CMakeTestFortranCompiler.cmake:54 (message):
The Fortran compiler "/usr/bin/gcc" is not able to compile a simple test program.

然而,正如您可能已经注意到的那样,我设置了libquadmath.a的位置;当我构建一个不使用X11的程序但在使用时使用quadmath

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")

然后程序成功编译(运行ldd报告'不是动态可执行文件') - 这是否意味着错误已经修复,或者只是因为我在CMake中设置位置才有效?

2 个答案:

答案 0 :(得分:0)

我猜你的问题并没有多大关系,我不知道所有问题的答案。

对于静态链接问题,由于您使用的是GCC,因此可以向其传递多个-static和-dynamic标志:

set(CMAKE_EXE_LINKER_FLAGS "-static ${STATIC_LIBS} -dynamic ${EVERYTHING ELSE} -static ${MORE_STATIC_LIBS}")

我不知道为什么Xaw.a在您的系统上不可用,可能是因为您的Linux发行版的软件包维护者并没有真正使它们可用。

此外,编译所有静态内容可能会使所有发行版之间的内容不兼容,并且会削弱其他人在程序中使用改进的最新库的能力,这可能不是您想要的。

如果你打算制作一个自包含你的程序包,最好只包括你一起使用的共享库,比如Dropbox和许多其他专有应用程序(Humble Bundle游戏就是其他例子)。

答案 1 :(得分:0)

我遇到了类似的问题。事实证明,cmake隐含地链接了libgfortran和libquadmath。为了解决这个问题,我将以下内容放在我的顶级CMakeLists.txt中:

unset(CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES)

然后我可以使用以下方法再次明确链接库:

SET_TARGET_PROPERTIES(main_f PROPERTIES LINKER_LANGUAGE "C"
  LINK_FLAGS
  "/usr/local/Cellar/gcc/7.1.0/lib/gcc/7/libgfortran.a 
  /usr/local/Cellar/gcc/7.1.0/lib/gcc/7/libquadmath.a -lm -lgcc"
)

libgfortran的静态版本是必需的,因为共享库也依赖于libquadmath。添加的" -lm"和" -lgcc"引入这些库的系统动态版本。在mac系统上,你也想要使用你的libm.a的完整路径。

相关问题