Force CMake to use static libraries

邮差的信 提交于 2019-12-30 18:49:06

问题


[Shamelessly cross-posted from the CMake help list]

I'm trying to create binaries as statically as possible. The fortran code I've got has got X11 and quadmath as dependencies, and I've come across a number of issues (maybe each of these issues should be in a different question?):

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

Using these, CMake attempts to build every program statically (as expected) - however, it fails because I don't have Xaw.a - I can't find out whether this actually should exist. I have installed the latest libxaw7-dev which I was expecting to fix it. One option would be to compile the X11 libraries myself, but I don't really want to do that...

  • 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
    

results in

-- 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.

However, as you might have noticed, I set the location of the libquadmath.a; when I build a program which doesn't use X11 but does use quadmath when I use

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

then the program does compile successfully (running ldd reports 'not a dynamic executable') - does this mean that the bug has been fixed, or does it only work because I set the location in CMake?


回答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.




回答2:


I guess your questions are not that much related, I don't know the answer for all of them.

For your static linking problems, since you're using GCC, you can pass multiple -static and -dynamic flags to it:

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

I don't know why Xaw.a isn't available on your system, probably because the package maintainer of your Linux distribution didn't really make them available.

Also, compiling everything static might make things not compatible between all distros out there and you cripple the ability for others to use improved, up-to-date libraries with your program, it might not be what you want.

If you intend to make a self-contained package of your program, it might be better just to include the shared libraries you used together, like Dropbox and many other proprietary applications do (Humble Bundle games are other example).



来源:https://stackoverflow.com/questions/18891290/force-cmake-to-use-static-libraries

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!