在跨平台项目中,我使用了许多第三方库。我最终决定将他们的源代码包含到我的存储库中,而不需要在每个平台上再次下载它们。这是许可证允许的。
要包含这些库中的标头,我需要指定它们的文件路径。有些库在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标志。但是,我认为编译器必须以某种方式了解这种技术,才能实现这一点。
答案 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)
简短的回答是“不”。
有几种不同的选择:
#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"
格式。