Search code examples
compilationcmakesubproject

Compiling and linking subproject library with CMake


I have 2 projects (prj1 and prj2). One (prj2) depends on the other (prj1) that is a static library. I arrive to compile them separately with CMake.

But I needed to integrate one (prj1) to the other one (prj2). So I would like CMake to compile the static library (prj1) before the other (prj2) and then link the static library. I tried things, but id did not work.

In prj2, externals/core is a git submodule (for non git users, you can see this directory as a copy-paste of prj1). I tried (without success) this CMakeLists.txt in prj2 "SDL2":

cmake_minimum_required(VERSION 2.8)


if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
    "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
  set(CMAKE_CXX_FLAGS       "-Wall -Wextra -Wformat=2 -Wpedantic -D_FORTIFY_SOURCE=2")
  set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
  # TODO
endif()

set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
# if (CMAKE_VERSION VERSION_LESS "3.1")
#   if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
#       CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
#     set (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
#   endif()
# else()
#   set(CMAKE_CXX_STANDARD 11)
# endif()

project(PlanetWars2dRT-SDL2)

# Version number
set(VERSION_MAJOR "0")
set(VERSION_MINOR "0")
set(VERSION_MICRO "0")

# Configure a header file to pass some of the CMake settings
# to the source code.
configure_file (
  "src/compilation_config.h.in"
  "${PROJECT_BINARY_DIR}/compilation_config.h"
  )
# Add the binary tree to the search path for include files
# so that we will find compilation_config.h
include_directories("${PROJECT_BINARY_DIR}")

set(LIBRARY_OUTPUT_PATH    lib/${CMAKE_BUILD_TYPE})
set(EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})

include_directories(src/)
file(
  GLOB_RECURSE
  source_files
  src/*
  )
add_executable(planet-wars-2d-rt-sdl2 ${source_files})

#include(ExternalProject)
#ExternalProject_Add(PlanetWars2dRT PREFIX externals/core/)
include_directories(externals/core/src/utils/ externals/core/src/specific/)
add_subdirectory(externals/core/)
#find_package(PlanetWars2dRT-core REQUIRED)

include(FindPkgConfig)
pkg_search_module(SDL2 REQUIRED sdl2)
pkg_search_module(SDL2GFX REQUIRED SDL2_gfx)
include_directories(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
target_link_libraries(
  planet-wars-2d-rt-sdl2
  planet-wars-2d-rt-core
  ${SDL2_LIBRARIES} ${SDL2GFX_LIBRARIES}
  )

That is a simplified version of the tree of prj2:

.
├── build (with CMake stuff generated with "cmake ..")
├── CMakeLists.txt
├── externals
│   └── core
│       ├── build (with CMake stuff generated with "cmake ..")
│       ├── CMakeLists.txt
│       ├── makefile
│       └── src
├── makefile
├── README.md
└── src
    ├── compilation_config.h.in
    └── planet-wars-2d-rt-sdl2.cpp

How can I compile the library of prj1 "core" in prj2 "SDL2" with CMake, and then link the library of prj1 with prj2 (again with CMake)?

If your solution does not work with a non GNU/Linux OS, it is not a big problem. Note: my PC is running on Debian GNU/Linux 8 "Jessie".

Regards.


Solution

  • Both project have a file "compilation_config.h". At compilation time, the wrong was taken so compilation failed, because the code used was #include "compilation_config.h" that was ambigous.

    So I created a "include/project-name" dir in both project and I changed the include path : "prj1/compilation_config.h" or "prj2/compilation_config.h". Thanks to that there was no ambiguity anymore, so it works now!