Frage

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?

War es hilfreich?

Lösung 2

I solved it like this:

The User can specify an additional variable -DSTATIC_LINKING=TRUE. Then, the script looks like this. (Only the important parts for the static linking and compilation are shown!)

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

Andere Tipps

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top