如何使用CMake命令/设计一个共享库,使用更高的包括
How to order/design a shared library with CMake that use higher includes
目前我有一个大约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>
现在的问题是,编译器不知道在库中查找包含的<> ,例如在foo中的Header.h包含。bar指向${CMAKE_CURRENT_SOURCE_DIR}/Header.h
,但CMAKE_CURRENT_SOURCE_DIR
是应用程序的路径,而不是库
所以我必须添加库的目录,编译器可以找到库的其他头文件(库中的头文件通过<>而不是"在库中包含另一个头文件)
所以我以这样的方式结束:
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../ ${CMAKE_CURRENT_SOURCE_DIR}/../MyLibrary)
现在Bar.h可以找到foo/foo .h,否则就会出错。这个更难看
所以我的问题:是否有一个好的/棘手的方法来解决这个问题在CMake ?或者谁能给我一些关于更好的项目结构的建议?解决方案必须在MSVC、GCC和clang下运行。
如果你考虑你的库安装后的样子,你可能会得到一些关于结构的提示。例如:
<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>)
我所做的是解决这个问题是有一个顶级的CMakeLists.txt设置变量,将指向项目目录的顶部。在您的示例中,这将是包含Application和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 )
然后在你的子目录cmakelist中,你可以像这样添加include路径:
include_directories( ${my_app_src_top}/MyLibrary )
我也只是在顶层定义了一个项目CMakeLists.txt。在这种情况下,您可能能够引用${PROJECT_SOURCE_DIR},但如果您在子目录中定义项目,那么我认为这将根据您构建的最后一个子目录进行重置。
我认为有了这个结构,你应该能够
#include <foo/Foo.h>
#include <bar/Bar.h>
另外,您可能希望在每个子目录的include_directories中添加。/。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 在cuda线程之间共享大量常量数据
- 如何从具有移动语义的类对象中生成共享指针
- 在c代码之间共享数据的最佳方式
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- 为什么 cmake 许可证<>样式不包括?
- 将静态库链接到不带-fPIC的共享库中
- 计算平均值,不包括上次得分
- 为什么std::互斥需要很长的、非常不规则的时间来共享
- 从多个源构造一个对象,包括一个对象向量
- 使用Boost Interprocess创建托管共享内存需要很长时间
- 无法在Ubuntu上将共享库与Eclipse链接
- 包括从C++存档 (.a) 到共享库的对象
- 包括带有 CMake 的共享库 (.so)
- qt共享库,包括外部头文件
- 如何使用CMake命令/设计一个共享库,使用更高的包括
- 无法在运行时加载动态共享库,包括C++中的另一个共享库