如何在 Linux 上将 CMake 二进制路径传递给 C++?

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

我的项目有这个简化的目录结构:

+-src
| +-CMakeLists.txt
+-example
| +-CMakeLists.txt
+-_builds
| +-win
| | +-src
| | +-example
| +-linux
| | +-src
| | +-example
+-CMakeLists.txt

example/CMakeLists.txt
中,我使用依赖于平台的编译器将着色器编译到相应的
_builds/*/example
目录中,然后将路径传递给 C++ 代码,如下所示:

target_compile_definitions(vulkan_tutorial PRIVATE EXAMPLE_BIN_DIR=${CMAKE_CURRENT_BINARY_DIR})

在 C++ 中我这样做:

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define GET_EXAMPLE_BIN_DIR() TOSTRING(MYLIB_EXAMPLE_BIN_DIR)

std::cout << GET_EXAMPLE_BIN_DIR() << std::endl;

在 Windows 上,这按我的预期工作,并且打印

D:/Dev/mylib/_builds/win/example

但是,在 Ubuntu 虚拟机上它会打印

/mnt/hgfs/dev/mylib/_builds/1/example
。所以linux这个词被替换为1。为什么呢?怎么解决?

我将我的项目命名为

mylib
只是为了这个问题。它的真实名称是不同的,以防万一。它很简单,仅包含几个核心 ASCII 字符,仅下划线字母。

我检查了二进制目录结构是否包含名为 1 的文件夹。没有。它包含上面列出的内容。我搜索了类似的 CMake 变量但没有找到任何解决方案。我还意识到,如果出现语法错误,CMake 会显示整个命令。滥用这个,我检查了我的 CMake 构建命令,发现它看起来不错。它包含这个:

-DEXAMPLE_BIN_DIR=/mnt/hgfs/dev/mylib/_builds/linux/example

整个命令行看起来像这样(我没有简化这个,不是为了隐藏任何可能的错误):

/bin/x86_64-linux-gnu-g++-9 -DMYLIB_ASSERT_TO_CERR -DMYLIB_ENABLE_EXCEPTIONS -DMYLIB_EXAMPLE_BIN_DIR=/mnt/hgfs/dev/mylib/_builds/linux/example -DMYLIB_LINKED_WITH_VULKAN -DMYLIB_LOGLEVEL=3 -DMYLIB_PRINT_CONFIG -I/mnt/hgfs/dev/mylib/include -I/mnt/hgfs/dev/mylib/third_party/glad2/include -I/mnt/hgfs/dev/mylib/_builds/linux/_deps/glfw-src/include -I/mnt/hgfs/dev/mylib/_builds/linux/_deps/glm-src -g -std=gnu++17 -MD -MT example/CMakeFiles/vulkan_tutorial.dir/vulkan.cpp.o -MF example/CMakeFiles/vulkan_tutorial.dir/vulkan.cpp.o.d -o example/CMakeFiles/vulkan_tutorial.dir/vulkan.cpp.o -c /mnt/hgfs/dev/mylib/example/vulkan.cpp

c++ cmake preprocessor-directive
1个回答
0
投票

linux
被定义为
1
MYLIB_EXAMPLE_BIN_DIR
中的部分字符串在字符串化之前会被扩展。如果您希望宏成为字符串,只需将其作为字符串传递给编译器即可,然后您可以跳过字符串化,并保证不会得到任何奇怪的扩展:

-DMYLIB_EXAMPLE_BIN_DIR=\"/mnt/hgfs/dev/mylib/_builds/linux/example\"
#include <iostream>

#define GET_EXAMPLE_BIN_DIR() MYLIB_EXAMPLE_BIN_DIR

int main()
{
    std::cout << GET_EXAMPLE_BIN_DIR() << std::endl;
}

https://godbolt.org/z/ev4aq4eMx 要在 cmake 中执行此操作:

target_compile_definitions(vulkan_tutorial PRIVATE EXAMPLE_BIN_DIR="${CMAKE_CURRENT_BINARY_DIR}")
© www.soinside.com 2019 - 2024. All rights reserved.