Shared objects with libraries and directory inclusions in Cmake

1.6k Views Asked by At

I'm very new to Cmake, and I'm trying to use it as an alternative to this approach, which did not work fine.

My structure is actually simple, I have:

App/src/
App/src/so1
App/src/so2
App/src/so3

And in each App/src/soN folder, I have a .cpp file, that shall be compiled into a shared object. I know I must add a CMakeLists.txt file in each folder listed above, but I'm really lost with the library linkage and inclusion.

For example, suppose there are the following files under App/src/so1:

App/src/so1/so1.hpp
App/src/so1/so1.cpp

And the shared object so1.so requires -I /some/dir/include, and also needs to be linked to -L /some/other/dir/lib -l otherdirlib. What are the appropriate directives for to make this using CMake?

1

There are 1 best solutions below

4
On BEST ANSWER

EDIT:

Use file and GLOB_RECURSE:

GLOB_RECURSE will generate a list similar to the regular GLOB, except it will traverse all the subdirectories of the matched directory and match the files.

I advice you to rearrenge your files like this:

app/
 |_ src/
 |_ include/
 |_ CMakeLists.txt
so1/
 |_ src/
 |_ include/
 |_ CMakeLists.txt
so2/
 |_ src/
 |_ include/
 |_ CMakeLists.txt
so3/
 |_ src/
 |_ include/
 |_ CMakeLists.txt
CMakeLists.txt

The CMakeLists.txt in app folder:

SET (APP_NAME app)

# Print variables to stdout
MESSAGE ( STATUS )
MESSAGE ( STATUS "Configuring ${APP_NAME}:" )
MESSAGE ( STATUS )

# Source code files
FILE (GLOB_RECURSE SOURCE_FILES src/*.cpp include/*.h include/*.inl)

# Compiler options
IF (CMAKE_COMPILER_IS_GNUCXX)
  ADD_DEFINITIONS (-ansi -Wall -Wextra -Werror -pthread)
ENDIF ()

# Build application
ADD_EXECUTABLE (${APP_NAME} ${SOURCE_FILES})

TARGET_LINK_LIBRARIES (${APP_NAME}
  ${SO1_LIB}
  ${SO2_LIB}
  ${SO3_LIB}
)

INSTALL (TARGETS ${APP_NAME} RUNTIME DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE  OWNER_EXECUTE GROUP_READ GROUP_WRITE  GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)

The CMakeLists.txt in each lib folder would be something like this(change the LIB_OUTPUT_NAME in each file accordingly):

SET (LIB_OUTPUT_NAME so1)

# Print variables to stdout
MESSAGE ( STATUS )
MESSAGE ( STATUS "Configuring ${LIB_OUTPUT_NAME}:" )
MESSAGE ( STATUS )

# Source code, headers and test files
FILE (GLOB_RECURSE HEADER_FILES include/*.h include/*.inl)
FILE (GLOB_RECURSE SOURCE_FILES src/*.cpp include/*.h include/*.inl)
FILE (GLOB_RECURSE TEST_SRC_FILES tests/*.cpp tests/*.h tests/*.inl)

# Compiler options
IF (CMAKE_COMPILER_IS_GNUCXX)
  ADD_DEFINITIONS (-ansi -Wall -Wextra -Werror -pthread)
ENDIF ()

# Build library
ADD_LIBRARY (${LIB_OUTPUT_NAME} SHARED ${SOURCE_FILES})

Then in the main CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
PROJECT (App CXX)

# Set common variables
IF ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
  SET (BUILD_DIR build/release)
ELSE ()
  SET (BUILD_DIR build/debug)
ENDIF ()

# Print variables to stdout
MESSAGE ( STATUS )
MESSAGE ( STATUS "Building App:" )
MESSAGE ( STATUS "change a configuration variable with: cmake -D<Variable>=<Value>" )
MESSAGE ( STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}" )
MESSAGE ( STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}" )
MESSAGE ( STATUS "CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}" )
MESSAGE ( STATUS )

# Remove build directory on clean target
SET_DIRECTORY_PROPERTIES (PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${BUILD_DIR})

# Include directories
INCLUDE_DIRECTORIES (
  "app/include"
  "so1/include"
  "so2/include"
  "so3/include"
)

# Add common compiler flags
IF (CMAKE_COMPILER_IS_GNUCXX)
  SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CPP_FLAGS_RELEASE} -O2")
  SET(CMAKE_CXX_FLAGS_DEBUG  "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g)
ENDIF ()

# Build all dynamic Libraries
ADD_SUBDIRECTORY (smartmatic ${BUILD_DIR}/so1)
SET (SO1_LIB ${CMAKE_CURRENT_SOURCE_DIR}/${BUILD_DIR}/so1/so1.so)

ADD_SUBDIRECTORY (saes-runtime ${BUILD_DIR}/so2)
SET (SO2_LIB ${CMAKE_CURRENT_SOURCE_DIR}/${BUILD_DIR}/so2/so2.so)

ADD_SUBDIRECTORY (saes-devices ${BUILD_DIR}/so3)
SET (SO3_LIB ${CMAKE_CURRENT_SOURCE_DIR}/${BUILD_DIR}/so3/so3.so)

# Add dynamic lib to app build for linking.
ADD_SUBDIRECTORY (so1 ${BUILD_DIR}/so1)
SET (SO1_LIB  ${CMAKE_CURRENT_SOURCE_DIR}/${BUILD_DIR}/so1/so1.so)

ADD_SUBDIRECTORY (so2 ${BUILD_DIR}/so2)
SET (SO2_LIB  ${CMAKE_CURRENT_SOURCE_DIR}/${BUILD_DIR}/so2/so2.so)

ADD_SUBDIRECTORY (so3 ${BUILD_DIR}/so3)
SET (SO3_LIB  ${CMAKE_CURRENT_SOURCE_DIR}/${BUILD_DIR}/so3/so3.so)

# Build Application
ADD_SUBDIRECTORY (app ${CMAKE_CURRENT_SOURCE_DIR}/${BUILD_DIR}/app)

More information on:

http://www.cmake.org/cmake/help/cmake2.6docs.html