2013-03-20 2 views
2

Я разрабатываю небольшое программное обеспечение для моделирования, которое зависит от двух библиотек, 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. Дело в том, что оно по-прежнему связано с версиями libs .so, что заставляет gcc бросать ошибки. По крайней мере, сценарии FindLibConfig.cmake устанавливают как LIBCONFIG_LIBRARY, так и переменную LIBCONFIG_STATIC_LIBRARY, которую я мог бы использовать.

Что является самым элегантным или умным путем для достижения моей цели?

ответ

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

Acording в CMake documentation, CMake использует переменную BUILD_SHARED_LIBS для определения значения по умолчанию для add_library().

Если установлено значение ON CMake будет предполагать все add_library() вызов будет как

add_library(target SHARED lib1 lib2 ...) 

Например, что-то вроде -DBUILD_SHARED_LIBS = ON в командной строке CMake может делать то, что вы просите.