包含路径的字符串连接

问题描述 投票:0回答:4

有没有办法连接 2 个字符串文字以形成包含路径?

代码存根:

#define INCLUDE_DIR "/include"
#include INCLUDE_DIR "/dummy.h"

看看这个问题,答案指向不同的方向(编译器命令行)。 这里提到了,貌似不太可能,但是我想知道这个话题是否已经挖够了

(我确实有一个与此相关的用例,请仅将您的答案/评论集中在这个问题上。)

c++ c include c-preprocessor
4个回答
1
投票

看来这确实是不可能的。我将在这里报告Eric Postpischil的回答的相关部分(他似乎不再活跃了)。

编译器将在

#include
行上进行宏替换(每个 C 2011 [N1570] 6.10.2 4),但语义尚未完全定义并且 不能用于在没有附加的情况下连接文件路径组件 C 实施的协助。所以这一切可以让你 do 是一些提供完整路径的简单替换,例如:

#define MyPath "../../path/to/my/file.h"
#include MyPath

文档链接。特别是本节对便携式解决方案没有留下太多希望:

预处理标记序列之间的方法 一个

<
和一个
>
预处理标记对或一对
"
字符 组合成单个标头名称预处理标记是 实现定义的。


为了完整起见,也许可以使用https://stackoverflow.com/a/27830271/2436175尝试一些东西。当我有空的时候我会调查一下......


0
投票

我不确定这是否正是您想要的,但无论如何。

#define DECORATE(x)             <x>
#define MAKE_PATH(root, file)   DECORATE(root file)

#define SYS_DIR(file)           MAKE_PATH(sys/, file)
#define ARPA_DIR(file)          MAKE_PATH(arpa/, file)


#include SYS_DIR(types.h)
#include SYS_DIR(socket.h)
#include ARPA_DIR(inet.h)

请注意,生成的文件名包含额外的空格 -

<sys/ types.h>
,因此它可能不是交叉编译器解决方案。但至少对我来说它可以在 GCC 4.8 / 4.9 的 Linux 主机上运行。

附注如果有人可以用其他编译器检查这个片段,那就太好了,例如MSVC。


0
投票

简单地避免空格和连接(##)并使用 < > 它使一切变得更简单:

#include <QtCore/QtGlobal>

#define QT_VERSION_PREFIX QT_VERSION_MAJOR.QT_VERSION_MINOR.QT_VERSION_PATCH

#define _CONCATE(a, c) <a/QT_VERSION_PREFIX/a/private/c>
#include _CONCATE(QtWidgets, qwidgettextcontrol_p.h)

0
投票

GCC 和 MSVC 上已确认的解决方案

尽管有很多人声称这是“不可能”的(至少以任何相当便携的方式)-但它是可以做到的!当你看到解决方案时,一切都不再那么痛苦...... 这就是我从上到下为一个用例所做的事情,在该用例中,我希望允许从一个主项目构建一组相互依赖的库,然后将其(作为标头+二进制文件)移植到具有可变目录布局的其他项目/ 包括路径。

    首先,客户端项目将定义设置为“顶级”配置文件路径。有条件地,如果包含路径规则需要该项目,则为包含标头的(包含相对路径)目录提供定义。这可以通过 CMake、QMake、make 等来完成。
  • 配置文件包含一些友好的宏设置,用于查找特定库的标头。
  • 然后,实现包含动态配置文件路径并调用宏来查找其他库路径。
CMake 驱动定义示例

target_compile_definitions(${TARGET_NAME} PUBLIC MY_CONFIG_PATH=\"my_core/include/myconfig.h\") target_compile_definitions(${TARGET_NAME} PUBLIC MY_CORE_INC_PATH=my_core/include)

(替代)定义示例

-DMY_CONFIG_PATH=\"my_core/include/myconfig.h\" -DMY_CORE_INC_PATH=my_core/include

myconfig.h 示例

#define MY_STR( X ) __MY_STR( X ) #define __MY_STR( X ) #X #define MY_PATH_CAT( X, Y ) X/Y #ifdef MY_CORE_INC_PATH # define MY_CORE_INCLUDE( FILE ) \ MY_STR( MY_PATH_CAT( MY_CORE_INC_PATH, FILE ) ) #else # define MY_CORE_INCLUDE( FILE ) MY_STR( FILE ) #endif

实施

#include MY_CONFIG_PATH #include MY_CORE_INCLUDE( something.h )

额外注意:

我发现,当在 Qt 框架中使用它时,解析包含路径的宏会在生成 .moc 文件或执行一些其他类型的需要源解析的 Qt / Qt Creator 魔法时造成麻烦。但是,库的内部结构和非 Qt 相关的库标头仍然可以很好地使用此类宏。

© www.soinside.com 2019 - 2024. All rights reserved.