强制CMake使用静态库

7

[从CMake帮助列表无耻地跨贴]

我正在尽可能静态地创建二进制文件。 我有一个Fortran代码,它具有X11和quadmath依赖项,并且我遇到了许多问题(也许每个问题应该是不同的问题?):

  • My variables are currently

    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库,但我不想这样做...
  • if I comment out only set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static"), then CMake compiles everything, but uses shared libraries for every program, even though I specify the location of .a X11 libraries in my find_library() calls. I was expecting CMake to use the .a files where it could and then only use shared libraries - is there a way to force this behaviour?

  • does anyone know yet of a fix for the bug described here: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46539; whereby gfortran seemingly can't statically link libquadmath? I tried the fix using gcc but I can't get CMake to recognise the libgfortran flag:

    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 会报告“不是动态可执行文件”)——这意味着 bug 已经被修复了吗?还是只是因为我在 CMake 中设置了位置才起作用?

2个回答

1
我遇到了类似的问题。原来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的完整路径。

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游戏是另一个例子)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接