英文:
Is the output location of CMake's add_custom_command different on Windows and Linux?
问题
I'm using add_custom_command()
in CMakeLists.txt
in a project of mine. I seem to have worked it out nicely for building on Linux, but for when I try and build on Windows, something strange happens.
Here's a snippet from a subdirectory's CMakeLists.txt
in my project:
add_executable(vectorAddMMAP modified_cuda_samples/vectorAddMMAP/vectorAddMMAP.cpp)
add_custom_command(
OUTPUT vectorAddMMAP_kernel.fatbin
COMMAND ${CMAKE_CUDA_COMPILER}
-fatbin ${CCBIN_ARGUMENT}
--generate-code arch=compute_${CMAKE_CUDA_ARCHITECTURES},code=sm_${CMAKE_CUDA_ARCHITECTURES}
-o ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vectorAddMMAP_kernel.fatbin
${CMAKE_CURRENT_SOURCE_DIR}/modified_cuda_samples/vectorAddMMAP/vectorAdd_kernel.cu
MAIN_DEPENDENCY modified_cuda_samples/vectorAddMMAP/vectorAdd_kernel.cu
... and this is the output I get on a Windows release from 2019, with MS Visual Studio 16 2019. (lines broken for readability)
C:\Program Files (x86)\Microsoft Visual Studio19\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(241,5):
warning MSB8065: Custom build for item "..\..\examples\modified_cuda_samples\vectorAddMMAP\vectorAdd_kernel.cu" succeeded,
but specified output "d:\a\cuda-api-wrappers\cuda-api-wrappers\build\examples\vectoraddmmap_kernel.fatbin" has not been
created. This may cause incremental build to work incorrectly.
[D:\a\cuda-api-wrappers\cuda-api-wrappers\build\examples\do_build_vectorAddMMAP_kernel.vcxproj]
I don't understand how this can be possible. The custom command creates ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vectorAddMMAP_kernel.fatbin
. And add_custom_command
's implied directory for relative path is ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
, right? So how can the file be missing if the compilation succeeded?
英文:
I'm using add_custom_command()
in CMakeLists.txt
in a project of mine. I seem to have worked it out nicely for building on Linux, but for when I try and build on Windows, something strange happens.
Here's a snippet from a subdirectory's CMakeLists.txt
in my project:
add_executable(vectorAddMMAP modified_cuda_samples/vectorAddMMAP/vectorAddMMAP.cpp)
add_custom_command(
OUTPUT vectorAddMMAP_kernel.fatbin
COMMAND ${CMAKE_CUDA_COMPILER}
-fatbin ${CCBIN_ARGUMENT}
--generate-code arch=compute_${CMAKE_CUDA_ARCHITECTURES},code=sm_${CMAKE_CUDA_ARCHITECTURES}
-o ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vectorAddMMAP_kernel.fatbin
${CMAKE_CURRENT_SOURCE_DIR}/modified_cuda_samples/vectorAddMMAP/vectorAdd_kernel.cu
MAIN_DEPENDENCY modified_cuda_samples/vectorAddMMAP/vectorAdd_kernel.cu
... and this is the output I get on a Windows release from 2019, with MS Visual Studio 16 2019. (lines broken for readability)
C:\Program Files (x86)\Microsoft Visual Studio19\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(241,5):
warning MSB8065: Custom build for item "..\..\examples\modified_cuda_samples\vectorAddMMAP\vectorAdd_kernel.cu" succeeded,
but specified output "d:\a\cuda-api-wrappers\cuda-api-wrappers\build\examples\vectoraddmmap_kernel.fatbin" has not been
created. This may cause incremental build to work incorrectly.
[D:\a\cuda-api-wrappers\cuda-api-wrappers\build\examples\do_build_vectorAddMMAP_kernel.vcxproj]
I don't understand how this can be possible. The custom command creates ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/vectorAddMMAP_kernel.fatbin
. And add_custom_command
's implied directory for relative path is ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
, right? So how can the file be missing if the compilation succeeded?
答案1
得分: 1
> 并且add_custom_command
隐含的相对路径目录是${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
,对吗?
错误。
请查看add_custom_target
的OUTPUT
参数的文档,其中指定:
> 如果输出文件名是相对路径,则其绝对路径是相对于:
>
> - 对应于当前源目录的构建目录(CMAKE_CURRENT_BINARY_DIR
),或者
>
> - 当前源目录(CMAKE_CURRENT_SOURCE_DIR
)。
>
> 除非在当前目录的其他位置明确提到源树中的路径作为绝对源文件路径,否则首选构建目录中的路径。
而且这仅仅是针对OUTPUT
参数的说明。如果在add_custom_command
的文档中搜索"relative"一词,您会看到大多数参数都有自己的规定,其中大多涉及到CMAKE_CURRENT_BINARY_DIR
。
故事的寓意:始终阅读CMake文档,了解在特定上下文中相对路径相对于哪里。
顺便说一下,CMAKE_RUNTIME_OUTPUT_DIRECTORY
没有一个已经设置的默认值。如果尝试使用一个没有设置值的变量,CMake的默认行为就是将变量引用评估为空字符串。这可能与您最初认为的Linux机器上命令似乎起作用的原因有关。
还请注意,还有一种称为$<TARGET_FILE_DIR:tgt>
的生成器表达式,您可以像这样使用$<TARGET_FILE_DIR:vectorAddMMAP>/vectorAddMMAP_kernel.fatbin
,将fatbin创建为与vectorAddMMAP目标的输出文件相对路径的同级文件系统路径。
英文:
> And add_custom_command's implied directory for relative path is ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
, right?
Wrong.
See the docs for the OUTPUT
parameter of add_custom_target
, which state:
> If an output file name is a relative path, its absolute path is determined by interpreting it relative to:
>
> - the build directory corresponding to the current source directory (CMAKE_CURRENT_BINARY_DIR
), or
>
> - the current source directory (CMAKE_CURRENT_SOURCE_DIR
).
>
> The path in the build directory is preferred unless the path in the source tree is mentioned as an absolute source file path elsewhere in the current directory.
And that's just for the OUTPUT
parameter. If you just search for the word "relative" in the docs for add_custom_command
, you'll see that most parameters there have their own specification, most involving CMAKE_CURRENT_BINARY_DIR
.
Moral of the story: Always read the CMake docs for what relative paths are taken relative to in a given context.
And by the way, CMAKE_RUNTIME_OUTPUT_DIRECTORY
does not have a already-set default value. If you attempt to use a variable with no set value, the default behaviour of CMake is to just evaluate the variable reference to an empty string. That probably has something to do with the reason why your command appears to work on your Linux machine according to how you originally thought things worked.
Note also that there is such a thing as the $<TARGET_FILE_DIR:tgt>
generator expression, which you can use like $<TARGET_FILE_DIR:vectorAddMMAP>/vectorAddMMAP_kernel.fatbin
to create a fatbin as a filesystem-pathwise-sibling to the output file of your vectorAddMMAP target.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论