如何在 CMakeLists.txt 中包含同级目录中的库进行编译

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

我最近在做一个C项目,想学习如何正确使用CMake。 该项目包含以下目录结构(截至目前):

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

包括'bin' 个子目录在内的每个目录都是一个单独的库。它们每个包含一个 CMakeLists.txt。

计划 link 库的开发过程中,不需要 手动 重新编译 'corelib' 来接收更新来自它的代码,同时还确保一旦所有库都被编译为共享库并放在诸如 'usr/local/lib' 或类似的地方。

我在库 'collections' 中依赖库 'corelib'。 为了解决上述依赖关系,我在 'collections':

中提出了以下 CMakeLists.txt
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)

但是,这不会产生我正在寻找的结果,因为我在构建时得到以下输出:

[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

看来这是错误的做法。非常感谢任何帮助。

这是CMakeLists.txt '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)

二进制目录必须是当前目录的子目录,不能在../bin之上。使用:

add_subdirectory(../private/corelib some_unique_name)

总的来说,让我们解决一些问题。更高级的 CMake 可能如下所示:

# 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"
     }
}

即总的来说,我认为 system 中的每个项目都不想编译自己的 单独的 corelib 实例,而是应该共享一个 corelib。只需添加 corelib 一次,从任何地方。请注意,它不必按顺序排列 - 您可以 target_link_libraries 在目标 之前 被定义。