7

[从 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 会编译所有内容,会为每个程序使用共享库,即使我在调用中指定了.aX11 库的位置。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 中设置了位置而起作用?

4

2 回答 2

1

I was having a similar problem. Turns out that cmake was implicitly linking against libgfortran and libquadmath. To fix this I put the following in my top level CMakeLists.txt:

unset(CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES)

I could then explicitly link again the libraries using:

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"
)

The static version of libgfortran is necessary because the shared library also depends on libquadmath. The added "-lm" and "-lgcc" bring in the system dynamic versions of these libraries. On a mac system, you would want to use the full path to your libm.a as well.

于 2017-07-13T21:03:10.630 回答
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 游戏是其他示例)。

于 2014-04-22T19:59:00.407 回答