Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do i build libraries in subdirectories using cmake?

Tags:

c++

cmake

My code is organized like this:

  • cpp
    • main.cpp (calls code from dataStructures/ and common/)
    • CMakeLists.txt (topmost CMakeLists file)
    • build
    • common
      • CMakeLists.txt (should be responsible for building common shared library)
      • include
        • utils.h
      • src
        • utils.cpp
      • build
    • dataStructures
      • CMakeLists.txt (build dataStructures shared library - dependent on common library)
      • include
        • dsLinkedList.h
      • src
        • dsLinkedList.cpp
      • build

build\ directories contain the built target. The actual code can be seen here: https://github.com/brainydexter/PublicCode/tree/master/cpp

As of now, CMakeLists.txt in each of the subdirectories build their own shared libraries. Topmost CMakeLists file then references the libraries and paths like this

Topmost CMakeLists.txt

cmake_minimum_required(VERSION 3.2.2)
project(cpp)

#For the shared library:
set ( PROJECT_LINK_LIBS libcppDS.dylib libcppCommon.dylib)
link_directories( dataStructures/build )
link_directories( common/build )

#Bring the headers, into the project
include_directories(common/include)
include_directories(dataStructures/include)

#Can manually add the sources using the set command as follows:
set(MAINEXEC main.cpp)

add_executable(testDS ${MAINEXEC})
target_link_libraries(testDS ${PROJECT_LINK_LIBS} )

How can I change the topmost CMakeLists.txt to go into subdirectories (common and dataStructures) and build their targets if they haven't been built, without me having to manually build the individual libraries ?

CMakeLists for common :

cmake_minimum_required(VERSION 3.2.2)
project(cpp_common)
set(CMAKE_BUILD_TYPE Release)

#Bring the headers, such as Student.h into the project
include_directories(include)

#However, the file(GLOB...) allows for wildcard additions:
file(GLOB SOURCES "src/*.cpp")

#Generate the shared library from the sources
add_library(cppCommon SHARED ${SOURCES})

dataStructures :

cmake_minimum_required(VERSION 3.2.2)
project(cpp_dataStructures)
set(CMAKE_BUILD_TYPE Release)

#For the shared library:
set ( PROJECT_LINK_LIBS libcppCommon.dylib )
link_directories( ../common/build )

#Bring the headers, such as Student.h into the project
include_directories(include)
include_directories(../common/include/)

#However, the file(GLOB...) allows for wildcard additions:
file(GLOB SOURCES "src/*.cpp")

#Generate the shared library from the sources
add_library(cppDS SHARED ${SOURCES})

Update:

This pull request helped me understand the correct way of doing this: https://github.com/brainydexter/PublicCode/pull/1

and commitId: 4b4f1d3d24b5d82f78da3cbffe423754d8c39ec0 on my git

like image 473
brainydexter Avatar asked Sep 17 '15 19:09

brainydexter


People also ask

How do I create a shared library in CMake?

To build everything, just place yourself into the build directory and run: /tmp/example/library/build $ cmake .. That's it, you should find mymath. h under /usr/local/include as well as libmymath.so under /usr/local/lib .

What does add library to CMake?

add_library(<name> <type> IMPORTED [GLOBAL]) Creates an IMPORTED library target called <name> . No rules are generated to build it, and the IMPORTED target property is True . The target name has scope in the directory in which it is created and below, but the GLOBAL option extends visibility.

What does add_subdirectory do in CMake?

Add a subdirectory to the build. Adds a subdirectory to the build. The source_dir specifies the directory in which the source CMakeLists.


1 Answers

You are only missing a simple thing: add_subdirectory. From the documentation:

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

Add a subdirectory to the build. The source_dir specifies the directory in which the source CMakeLists.txt and code files are located. If it is a relative path it will be evaluated with respect to the current directory (the typical usage), but it may also be an absolute path. The binary_dir specifies the directory in which to place the output files. If it is a relative path it will be evaluated with respect to the current output directory, but it may also be an absolute path.

http://www.cmake.org/cmake/help/v3.0/command/add_subdirectory.html

It does exactly what you need.

like image 97
ypnos Avatar answered Oct 31 '22 17:10

ypnos