我正在使用 ISPC 编译 .ispc 文件并使用 CMake 将它们链接到我的 C++ 项目。 ISPC 的一个怪癖是它生成 C++ 代码要包含的头文件。为了便于构建它,我的所有 ISPC 文件都位于一个静态库中。我的 C++ 代码的核心位于依赖于 ISPC 库的静态库中。最后,我的项目可执行文件是一个单独的项目,它链接到核心 C++ 代码(这是用于单元测试,但这与这里无关)。
这是我的文件结构:
src/
|
+ core/
| |
| +--CMakeLists.txt
| +--core_code.cpp
| |
| + ispc/
| |
| +--CmakeLists.txt
| +--simd_code.ispc
|
+ runner/
|
+--CMakeLists.txt
+--main.cpp
我的CMakeLists文件的相关部分如下
# src/CMakeList.txt
add_subdirectory(core)
add_subdirectory(runner)
# src/core/CMakeLists.txt
add_library(CoreLib STATIC)
target_sources(CoreLib PUBLIC core_code.cpp)
# Add ISPC dependent code
add_subdirectory(ispc)
target_link_libraries(CoreLib PUBLIC IspcLib)
target_include_directories(CoreLib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
# I believe I need to specify another include dirs here - where the ISPC headers are generated
# src/core/ispc/CMakeLists.txt
add_library(IspcLib STATIC simd_code.ispc)
# No include dirs or link libs since the ispc code is stand-alone
# src/runner/CMakeLists.txt
add_executable(ProjectExe main.cpp)
target_link_libraries(ProjectExe PRIVATE CoreLib)
令人惊讶的是,我能够构建我的 CoreLib 目标(core_code.cpp 包括
simd_code_ispc.h
,生成的标头)。查看make文件,它在构建核心目标时指定的包含目录是
C:\\...\MyProject\cmake-build-debug\src\core\ispc\CMakeFiles\IspcLib.dir\\.\
果然是 ISPC 生成文件的地方。
我无法构建依赖于核心的跑步者目标,并出现找不到 #include simd_code_ispc.h
的错误。
我知道我可以将此目录硬编码到我的包含中,但我正在寻找我应该如何做到这一点;以一种不特定于我的机器的方式,仍然允许我重新安排我的项目结构,并且将在构建和安装期间工作。
我在网上看到了一些使用自定义命令的示例(包括这个堆栈交换帖子) 但 CMake 在 3.19 中添加了 ISPC 集成,所以我更愿意使用它。
使用目标的属性
ISPC_HEADER_DIRECTORY
(CMake文档):
# You may need to add ISPC to project's languages if you mix languages
project(TEST_ISPC LANGUAGES ... ISPC)
# Add `.ispc` as regular sources files.
add_library(ispc_lib STATIC simple.ispc)
# `.ispc` header files are generated in `ISPC_HEADER_DIRECTORY`
target_include_directories(ispc_lib PUBLIC $<TARGET_PROPERTY:ISPC_HEADER_DIRECTORY>)
# Now, linking targets can include generated `.ispc` header files.
add_executable(test_ispc some_source_file.cpp ...)
target_link_libraries(test_ispc PRIVATE ispc_lib)
以下属性可用:
ISPC_HEADER_DIRECTORY
,或全局 CMAKE_ISPC_HEADER_DIRECTORY
(默认 CMAKE_CURRENT_BINARY
)(请参阅 CMake 文档。ISPC_HEADER_SUFFIX
,或全局 CMAKE_ISPC_HEADER_SUFFIX
(默认 _ispc.h
)(请参阅 CMake 文档。ISPC_INSTRUCTION_SETS
每个目标,或 CMAKE_ISPC_INSTRUCTION_SETS
全局(如果我们遵循 ispc 的文档,默认应该是最有能力的)(请参阅 CMake 文档。如果您想更改属性,请使用:
set_target_property(ispc_lib PROPERTIES ISPC_HEADER_DIRECTORY ...)