使文件夹中的所有文件可被所有项目(子目录)访问

时间:2020-06-26 17:27:33

标签: c++ cmake linker

我的存储库中有多个项目(子目录)。所有项目都只有一个名为main.cpp的可执行文件,并且它们都使用带有common语句的#include文件夹中的库。文件夹结构如下:

root
|
├────common
|    ├──── example.h
|    ├──── example.cpp
|    ├──── *.h          # many header files
|    └──── *.cpp        # many source files
|
├────Project_A
|    ├──── CMakeLists.txt
|    └──── main.cpp
|
├────Project_B
|    ├──── CMakeLists.txt
|    └──── main.cpp
|
└──── CMakeLists.txt

这是我尝试编写 root的CMakeLists.txt

cmake_minimum_required (VERSION 3.8)
project ("root")

file(GLOB_RECURSE CommonLibs ${CMAKE_SOURCE_DIR}/common/*.cpp)
link_libraries(${CommonLibs})

add_subdirectory ("Project_A")
add_subdirectory ("Project_B")

Project_A的CMakeLists.txt

cmake_minimum_required (VERSION 3.8)
add_executable (Project_A "main.cpp")

Project_B的CMakeLists.txt

cmake_minimum_required (VERSION 3.8)
add_executable (Project_B "main.cpp")

但是,在运行任何项目时,都会出现此错误:

LNK1107 invalid or corrupt file: cannot read at 0x7AC, file example.h

我不认为文件已损坏,因为在我尝试在root的CMakeLists.txt中使用link_libraries()之前,我遇到了其他错误:

Unresolved external symbol SomeNamespace::ExampleClass::ExampleClass(bool)

可能的重复项

诸如this one之类的其他问题不能解决我的问题,因为它们通常使用更复杂的文件夹结构。还有一些问题试图仅针对单个项目,例如this one,但我有多个项目。

能否请您提供一个简洁的解决方案?

2 个答案:

答案 0 :(得分:2)

CMakeLists.txt添加到您的common/目录:

root
|
├────common
|    ├──── CMakeLists.txt <-------- Add this
|    ├──── example.h
....

common / CMakeLists.txt

file(GLOB_RECURSE CommonLibsFiles ${CMAKE_CURRENT_SRC_DIR}/*.cpp)
add_library(CommonLibs ${CommonLibsFiles})
...

根用户的CMakeLists.txt

...

### NO NEED FOR THESE
file(GLOB_RECURSE CommonLibs ${CMAKE_SOURCE_DIR}/common/*.cpp)
link_libraries(${CommonLibs})
###

add_subdirectory(common) #CommonLibs will now be visible to children directories
...

现在根据需要链接库。例如,项目A

Project_A的CMakeLists.txt

cmake_minimum_required (VERSION 3.8)
add_executable (Project_A "main.cpp")
target_link_libraries(Project_A PRIVATE CommonLibs) #link to common libs here,

所有创建的目标对象/变量或对 parent cmake文件可见的目标对象/变量,对于子对象可见。相反,事实并非如此。为了让孩子将变量展示给父母,他们需要明确指定PARENT_SCOPE

答案 1 :(得分:2)

顶级CMake中的以下几行意义不大:

file(GLOB_RECURSE CommonLibs ${CMAKE_SOURCE_DIR}/common/*.cpp)
link_libraries(${CommonLibs})

link_libraries()命令接受库目标,而不接受变量(例如CommonLibs)。您可以使用 CommonLibs变量来定义新的库目标,然后使用link_libraries()将库 target 链接到您的可执行文件:

file(GLOB_RECURSE CommonLibs ${CMAKE_SOURCE_DIR}/common/*.cpp)
# Add this line.
add_library(MyCommonLib SHARED ${CommonLibs})
link_libraries(MyCommonLib)

请注意,即使在CMake文档本身中,link_libraries()的使用通常也是不适用。您应该更喜欢使用MyCommonLibtarget_link_libraries链接到需要它的特定可执行文件。

target_link_libraries(Project_A PRIVATE MyCommonLib)