CMake: Static and dynamic linking based on BUILD_TYPE

janoliver picture janoliver · Mar 20, 2013 · Viewed 16.4k times · Source

I am developing a small simulation software that depends on two libraries, the GSL and the libconfig. As a build system, I use CMake. For both the GSL and libconfig, I found cmake files and copied them into the cmake/ directory of my project.

The scenario is the following: I want the project to have several different build types, like debug, release, etc., but also a custom one called cluster, which adds -static to the GCC flags and links against the .a libraries of the GSL and the libconfig, which I assume exist.

My CMakeLists.txt looks like this so far:

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

This adds the -static to the compiler, when I use -DCMAKE_BUILD_TYPE=cluster. The thing is, that it still links against the .so versions of the libs, which causes gcc to throw errors. At least the FindLibConfig.cmake scripts sets both a LIBCONFIG_LIBRARY and a LIBCONFIG_STATIC_LIBRARY variable, which I could use.

What is the most elegant or smart way to reach my goal?

Answer

aled picture aled · Dec 17, 2013

Acording to cmake documentation, cmake uses the variable BUILD_SHARED_LIBS to determine the default for add_library().

If you set to ON cmake will assume all add_library() call will be as

add_library(target SHARED lib1 lib2 ...)

For example something like -DBUILD_SHARED_LIBS=ON on the cmake command line may do what you are asking.