CMake:基于BUILD_TYPE的静态和动态链接
问题描述:
我正在开发一个小型仿真软件,它依赖于两个库,即GSL和libconfig。作为构建系统,我使用CMake。对于GSL和libconfig,我找到cmake文件并将它们复制到我项目的cmake/
目录中。CMake:基于BUILD_TYPE的静态和动态链接
的情况如下:我想这个项目有几个不同的生成类型,如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)
这增加了-static
编译器,当我使用-DCMAKE_BUILD_TYPE=cluster
。事情是,它仍然链接对库的.so
版本,这导致gcc抛出错误。至少FindLibConfig.cmake
脚本设置了一个LIBCONFIG_LIBRARY
和一个LIBCONFIG_STATIC_LIBRARY
变量,我可以使用它。
什么是最优雅或最聪明的方式来达到我的目标?
答
我解决了它这样的:
,用户可以指定一个额外的变量-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)
答
Acording向CMake documentation,cmake的使用变量BUILD_SHARED_LIBS确定add_library默认的()。
如果设置为ON的CMake将承担一切add_library()
的通话将被作为
add_library(target SHARED lib1 lib2 ...)
例如像-DBUILD_SHARED_LIBS = ON CMake的命令行可以做你的要求。