Home > OS >  How to include library from sibling directory in CMakeLists.txt for compilation
How to include library from sibling directory in CMakeLists.txt for compilation

Time:05-13

I am working on a C project as of recently and want to learn how to use CMake properly. The project consists of the following directory structure (as of now):

.
└── system
    ├── collections
    │   ├── bin
    │   ├── build
    │   ├── includes
    │   └── src
    └── private
        └── corelib
            ├── bin
            ├── build
            ├── includes
            └── src

Every directory including 'bin' sub-directories is a separate library. They contain a CMakeLists.txt each.

The plan is to link the libraries in such a way that, during development, no manual recompilation of 'corelib' should be required to receive updated code from it, while also ensuring that dependencies would be resolved once all libraries get compiled as SHARED libraries and put in a place such as 'usr/local/lib' or similar.

I have a dependency of library 'corelib' in library 'collections'. Trying to resolve said dependency, I have come up with the following CMakeLists.txt in 'collections':

cmake_minimum_required(VERSION 3.0.0)
project(collections VERSION 0.1.0 LANGUAGES C)
set(LIBRARY_OUTPUT_PATH ../bin)
add_subdirectory(../private/corelib ${LIBRARY_OUTPUT_PATH})
include_directories(./includes)
aux_source_directory(./src SOURCES)
add_library(collections SHARED ${SOURCES} main.c)

However, this does not produce the result I am looking for, as I get the following output on build:

[main] Building folder: collections 
[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /home/codeuntu/Repositories/netcore-c/src/system/collections/build --config Debug --target all -j 6 --
[build] gmake[1]: *** No rule to make target '../bin/all', needed by 'all'.  Stop.
[build] gmake[1]: *** Waiting for unfinished jobs....
[build] Consolidate compiler generated dependencies of target collections
[build] [ 50%] Built target collections
[build] gmake: *** [Makefile:91: all] Error 2
[build] Build finished with exit code 2

It seems this is the wrong way to go about it. Any help is greatly appreciated.

This is the CMakeLists.txt for 'corelib':

cmake_minimum_required(VERSION 3.0.0)
project(corelib VERSION 0.1.0 LANGUAGES C)
include_directories(./includes)
aux_source_directory(./src SOURCES)
set(LIBRARY_OUTPUT_PATH ../bin)
add_library(corelib SHARED ${SOURCES} main.c)

CodePudding user response:

Binary directory has to be a subdirectory of current dir, it can't be above ../bin. Use:

add_subdirectory(../private/corelib some_unique_name)

Overall, let's fix some issues. A more advanced CMake might look like this:

# system/CmakeLists.txt
add_subdirectory(private EXCLUDE_FROM_ALL)
add_subdirectory(collections)

# system/collections/CMakeLists.txt
cmake_minimum_required(VERSION 3.11)
project(collections VERSION 0.1.0 LANGUAGES C)
file(GLOB_RECURSE srcs *.c *.h)
add_library(collections ${srcs})
# Use only target_* intefaces
target_include_directories(collections PUBLIC
   ./includes
)
target_link_libraries(collections PRIVATE 
   corelib
)

# system/private/CMakeLists.txt
add_subdirectory(corelib)

# system/private/corelib/CMakeLists.txt
cmake_minimum_required(VERSION 3.11)
project(corelib VERSION 0.1.0 LANGUAGES C)
file(GLOB_RECURSE srcs *.c *.h)
add_library(corelib ${srcs})
target_include_directorieS(corelib PUBLIC ./includes)

# system/CMakePresets.json
{
    ... see documentation ...
    "configurePresets": [
      {
        ...
        "cacheVariables": {
          "BUILD_SHARED_LIBS": "1",
          "ARCHIVE_OUTPUT_DIRECTORY": "${binaryDir}/bin",
          "LIBRARY_OUTPUT_DIRECTORY": "${binaryDir}/bin",
          "RUNTIME_OUTPUT_DIRECTORY": "${binaryDir}/bin"
     }
}

I.e. overall, I do not think every project inside system wants to compile his own separate instance of corelib, rather one corelib should be shared. Just add corelib once, from anywhere. Note that it doesn't have to be in order - you can target_link_libraries on targets before they are defined.

  • Related