目前我有一个大约30个班级的共享库。我的想法是将它们分组到子目录中,意味着子目录包含或多或少等于/具有相同内容的类(ui,utils,backend等)。
但是我遇到了一个典型的问题:我有一些在项目中共享的导出定义/常量,我的第一个问题是:如何在子目录中的头中包含这个头?
我经常看到#include ../Header.h
解决方案,但我的个人意见是,这非常难看。
所以我做了什么:
Application/
main.cpp
MyLibrary/
Header.h
foo/
Foo.h (#include <Header.h>
bar/
Bar.h (#include <Header.h> #include <foo/Foo.h>)
在我的库CMakeList中,我添加了include_directory
和MyLibrary目录的根目录。
我的应用程序可执行文件CMakeLists.txt看起来像这样(伪CMake)
project(application)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../)
add_executable(application main.cpp)
target_link_libraries(application mylibrary)
在main.cpp
我包括这样的内容:
#include <MyLibrary/Header.h>
#include <MyLibrary/bar/Bar.h>
现在的问题是,编译器不知道在哪里查找包含的&lt;&gt; INSIDE 库,例如foo.bar中的Header.h包含指向${CMAKE_CURRENT_SOURCE_DIR}/Header.h
- 但是CMAKE_CURRENT_SOURCE_DIR
是应用程序的路径而不是库
所以我必须添加库的目录,编译器可以找到该库的其他标题(库中的标题包含库中的另一个标题,通过&lt;&gt;而不是&#34;&#34 ;)
所以我最终得到这样的东西:
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../ ${CMAKE_CURRENT_SOURCE_DIR}/../MyLibrary)
现在Bar.h可以找到foo / Foo.h,否则会出错。而且这更难看了
所以我的问题:在CMake中解决这个问题是否有好的/棘手的方法?或者有人可以给我一些更好的项目结构吗?解决方案必须在MSVC,GCC和clang下运行。
答案 0 :(得分:2)
如果您考虑安装后库的外观,您可能会得到一些关于结构的提示。例如:
<install-prefix>/Foo/foo.hpp -> has `#include <Boo/boo.hpp>`
<install-prefix>/Boo/boo.hpp -> has `#include <Bar/bar.hpp>`
<install-prefix>/Bar/bar.hpp -> has `#include <Bar/details/utils.hpp>`
<install-prefix>/Bar/details/utils.hpp
在安装完成之前,这是可能的布局:
<source-dir>/Sources/Foo/foo.hpp
<source-dir>/Sources/Boo/boo.hpp
<source-dir>/3rdParty/Bar/bar.hpp
<source-dir>/3rdParty/Bar/details/utils.hpp
因此CMakeLists.txt
必须包含(或更好target_include_directories):
include_directories(<source-dir>/Sources)
include_directories(<source-dir>/3rdParty)
所以对于你的情况,恕我直言,它必须是这样的:
Application/
main.cpp
MyLibrary/
Header.h
foo/
Foo.h (#include <MyLibrary/Header.h>
bar/
Bar.h (#include <MyLibrary/Header.h> #include <MyLibrary/foo/Foo.h>)
答案 1 :(得分:0)
我为解决这个问题所做的是有一个顶级的CMakeLists.txt,它设置指向项目目录顶部的变量。在您的情况下,这将是包含应用程序和 MyLibrary 的目录。
ProjectRoot
CMakeLists.txt // top
Application/
CMakeLists.txt
main.cpp
MyLibrary/
CMakeLists.txt
Header.h
foo/
Foo.h (#include <Header.h>
bar/
Bar.h (#include <Header.h> #include <foo/Foo.h>)
# Top level cmakelists
project (myproject)
set (my_app_src_top "${CMAKE_CURRENT_SOURCE_DIR}" )
set (my_app_build_top "${CMAKE_CURRENT_BINARY_DIR}" )
add_subdirectory( MyLibrary )
add_subdirectory( Application )
然后在您的子目录CmakeLists中,您可以添加如下所示的包含路径:
include_directories( ${my_app_src_top}/MyLibrary )
我也只是在顶级CMakeLists.txt中定义一个项目。在这种情况下,您可以引用$ {PROJECT_SOURCE_DIR},但如果您在子目录中定义项目,那么我认为这将根据您构建的最后一个子目录重置。
我认为通过这种结构你应该能够
#include <foo/Foo.h>
#include <bar/Bar.h>
另外,您可能希望将./添加到每个子目录的include_directories。