是否有像包含目录别名的概念?

时间:2014-02-18 07:49:00

标签: c++ include cmake cross-platform project

在跨平台项目中,我使用了许多第三方库。我最终决定将他们的源代码包含到我的存储库中,而不需要在每个平台上再次下载它们。这是许可证允许的。

要包含这些库中的标头,我需要指定它们的文件路径。有些库在name/include/name/file.h中有它们,但通常每个库都有不同的目录结构。

我想在代码中包含标题#include "name/file.h",其中 name 是库的名称。但我既不想修改库的目录结构,也不想将所有头文件复制到我所需结构的include目录中。

有没有办法定义包含目录别名?例如, Bullet Physics 的标题位于bullet/src Sqlite 的标题直接位于sqlite SFML 他们在sfml/include/SFML。我想指出这样的事情:

#alias "dependencies/bullet/src" "bullet"
#alias "dependencies/sqlite" "sqlite"
#alias "dependencies/sfml/include/SFML" "sfml"

因此#include "sfml/System.hpp"与<#include "dependencies/sfml/include/SFML/System.hpp"等同。

该技术不必处于预处理阶段。例如,它也可以是以正确方式生成项目的CMake标志。但是,我认为编译器必须以某种方式了解这种技术,才能实现这一点。

3 个答案:

答案 0 :(得分:5)

没有;最近的方法是命令行上-I选项的集合。

此外,如果您使用SFML,建议的表示法是#include "SFML/System.hpp";这就是你应该在你的代码中写的东西。然后修复编译环境以便编译中包含-Idependencies/sfml/include,或者使用符号链接(如果它们足够便携)来在包含项目的主目录中制作像SFML这样的子目录头。

当安装了像SFML这样的软件包时,标题将被放置到一个目录中 - 默认情况下通常为/usr/local/include,并且通常位于其下的子目录中。也就是说,会有一个包含SFML标头的目录/usr/local/include/SFML。其他软件包的机会也是如此。您应该在构建区域下的某个位置安装这些标头,以便可以正常找到标头 - 您只需指定找到标头的基本include目录。 (注意:当你安装Bullet Physics library时,标题会放在一个目录.../include/bullet下面,其下面有各种子目录,所以它也遵循这个约定。)

否则意味着打击系统,当你对抗系统时,你最终会失败。简单地顺其自然,这是一项艰巨的工作。

答案 1 :(得分:4)

简短的回答是“不”。

有几种不同的选择:

  • 符号链接 - 设置您自己的“myincludes”目录,然后将所有相关文件链接到它们的相对位置。
  • 为项目使用更复杂的-I选项。
  • 编写自己的预处理器(将给定的#include翻译成“实际位置的实际文件”,给出一些规则)
  • 调整相应项目的安装目录。
  • 不要执行上述任何操作,并使用实际文件系统中显示的名称。

我个人更喜欢“不要这样做”选项。一方面,移动/更改文件的方式很可能会使某些人感到困惑,第三方代码肯定不会以这种方式编写,因此您将无法使用其他人的代码来维护这种风格。

答案 2 :(得分:0)

我正在一次构建中构建所有内容(不在软件包中) 通过执行以下操作,我设法使用Cmake完全按照您的要求进行操作:

在最高的CMakeLists.txt中

set(TEMP_INCLUDE_DIR ${CMAKE_BINARY_DIR}/tempIncludes)
file(MAKE_DIRECTORY ${TEMP_INCLUDE_DIR})
target_include_directories(<TARGET_NAME> PUBLIC
  $<BUILD_INTERFACE:${TEMP_INCLUDE_DIR}>
)

这将在二进制目录中创建一个文件夹(在清理项目时将其删除,因此它不会修改您的实际文件夹结构,并且我假设您未使用源代码构建)

然后在CMakeLists.txt中找到目标库:

set(LIB_NAME <ThirdPartyLibraryName>)
set(INCLUDE_FOLDER <WhatEverThirdPartyIncludeDirectory>)
set(HEADER_FILES
    ${INCLUDE_FOLDER}/<Header1>.h
    ${INCLUDE_FOLDER}/<Header2>.h
)
file(COPY ${HEADER_FILES} DESTINATION ${TEMP_INCLUDE_DIR}/${LIB_NAME}/)

这将创建一个文件夹结构,将所有包含文件复制到标准目录中,使您可以使用所需的#include "name/file.h"格式。