CMake:基于BUILD_TYPE的静态和动态链接

jan*_*ver 3 linker cmake libconfig

我正在开发一个小型仿真软件,它依赖于两个库,GSL和libconfig.作为构建系统,我使用CMake.对于GSL和libconfig,我找到了cmake文件并将它们复制到cmake/我的项目目录中.

场景如下:我希望项目有几种不同的构建类型,比如debug,release等等,还有一个自定义的构建类型cluster,它会添加-static到GCC标志和链接.a到GSL和libconfig 的库,我假设存在.

CMakeLists.txt到目前为止我看起来像这样:

# version
SET(PACKAGE_VERSION "1.0")
SET(PACKAGE_NAME "INTERFACE")

PROJECT(interface C CXX)

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)


# dirs -----------------------------------------------------

SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")

FIND_PACKAGE(GSL REQUIRED)
INCLUDE_DIRECTORIES(${GSL_INCLUDE_DIRS})
SET(LIBS ${LIBS} ${GSL_LIBRARIES})

FIND_PACKAGE(LibConfig REQUIRED)
INCLUDE_DIRECTORIES(${LIBCONFIG_INCLUDE_DIRS})
SET(LIBS ${LIBS} ${LIBCONFIG_LIBRARIES})

CONFIGURE_FILE("res/config.h.in" "config.h")
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR})

SET_DIRECTORY_PROPERTIES(PROPERTIES 
    ADDITIONAL_MAKE_CLEAN_FILES "config.h"
)


# compilation ----------------------------------------------

ADD_EXECUTABLE( interface
    interface.c interface.h config.h
    helpers.c 
    output.c
    lattice.c 
    genetic.c
)

# optional CFLAGS
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -pedantic -std=c99")
SET(CMAKE_C_FLAGS_RELEASE "-O3 -ffast-math")
SET(CMAKE_C_FLAGS_CLUSTER "-O3 -ffast-math -static")
SET(CMAKE_C_FLAGS_DEBUG "-g")
SET(CMAKE_C_FLAGS_PROFILE "-g -ffast-math -pg")

TARGET_LINK_LIBRARIES(interface m ${LIBS})



# installation --------------------------------------------

INSTALL(TARGETS interface DESTINATION bin)
Run Code Online (Sandbox Code Playgroud)

-static当我使用时,这会添加到编译器中-DCMAKE_BUILD_TYPE=cluster.问题是,它仍然链接.so到libs 的版本,这会导致gcc抛出错误.至少FindLibConfig.cmake脚本设置了a LIBCONFIG_LIBRARYLIBCONFIG_STATIC_LIBRARY变量,我可以使用它.

达到目标的最优雅或最聪明的方法是什么?

ale*_*led 8

根据cmake 文档,cmake使用变量BUILD_SHARED_LIBS来确定add_library()的默认值.

如果设置为ON,则cmake将假定所有add_library()呼叫都为

add_library(target SHARED lib1 lib2 ...)
Run Code Online (Sandbox Code Playgroud)

例如,在cmake命令行上类似-DBUILD_SHARED_LIBS = ON的内容可能会按照您的要求执行.


jan*_*ver 5

我这样解决了:

用户可以指定其他变量-DSTATIC_LINKING=TRUE.然后,脚本看起来像这样.(仅显示静态链接和编译的重要部分!)

# determine, whether we want a static binary
SET(STATIC_LINKING FALSE CACHE BOOL "Build a static binary?")

# do we want static libraries?
# When STATIC_LINKING is TRUE, than cmake looks for libraries ending
# with .a. This is for linux only!
IF(STATIC_LINKING)
    SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
ENDIF(STATIC_LINKING)

# set -static, when STATIC_LINKING is TRUE and set LINK_SEARCH_END_STATIC
# to remove the additional -bdynamic from the linker line.
IF(STATIC_LINKING)
    SET(CMAKE_EXE_LINKER_FLAGS "-static")
    SET_TARGET_PROPERTIES(surface PROPERTIES 
        LINK_SEARCH_END_STATIC 1)
ENDIF(STATIC_LINKING)
Run Code Online (Sandbox Code Playgroud)