【问题标题】:CMake: Static and dynamic linking based on BUILD_TYPECMake:基于 BUILD_TYPE 的静态和动态链接
【发布时间】:2013-03-09 10:53:14
【问题描述】:

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

场景如下:我希望项目有几种不同的构建类型,如debugrelease 等,还有一种称为cluster 的自定义构建类型,它将-static 添加到GCC针对 GSL 和 libconfig 的 .a 库的标志和链接,我假设它们存在。

到目前为止,我的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)

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

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

【问题讨论】:

    标签: linker cmake libconfig


    【解决方案1】:

    根据 cmake documentation,cmake 使用变量 BUILD_SHARED_LIBS 来确定 add_library() 的默认值。

    如果您设置为 ON,cmake 将假定所有 add_library() 调用将作为

    add_library(target SHARED lib1 lib2 ...)
    

    例如,cmake 命令行上的 -DBUILD_SHARED_LIBS=ON 之类的内容可能会满足您的要求。

    【讨论】:

      【解决方案2】:

      我是这样解决的:

      用户可以指定一个附加变量-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)
      

      【讨论】:

        猜你喜欢
        • 2023-03-05
        • 2013-06-04
        • 1970-01-01
        • 2017-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-08
        • 2010-09-15
        相关资源
        最近更新 更多