VS+CUDA: ProgramDataBaseFile is abs path, breaking CUDA if it contains space
We've just discovered an issue between the interaction of CMake (present in 3.21 and 3.23) and Visual Studio 2022 (not present in VS2019). Implicitly, this is with CUDA 11.7, but I doubt that's relevant.
If a user configures and builds our project which is a static library with a build directory, that has an absolute path containing a space, it will fail with the below error.
nvcc fatal : A single input file is required for a non-link phase when an outputfile is specified
The build string is long and complicated, but the offending statement is this, which I believe is automatic rather than something we've specified.
-Xcompiler "/EHsc /W4 /nologo /O2 /Fd"C:\Program Files\primage_usfd_model\usfd_model\build\_deps\flamegpu2-build\lib\Release\flamegpu.pdb" /FS /MD /GR"
It should be clear, that the "
for the nested string are not escaped.
With Visual Studio 2019, instead this statement has a relative path
-Xcompiler "/EHsc /W4 /nologo /O2 /Fdflamegpu.dir\Release\flamegpu.pdb /FS /MD /GR"
Likewise, Visual Studio 2022, without a space in the path, the quotes are omitted, so that also works.
Investigating this I've identified that CMake sets the C/C++ > Output Files > Program Database File Name
property differently.
- Visual Studio 2022 (via CMake):
$(OutDir)$(TargetName).pdb
- Visual Studio 2022 (default):
$(IntDir)vc$(PlatformToolsetVersion).pdb
- Visual Studio 2019 (via CMake):
$(IntDir)$(ProjectName).pdb
- Visual Studio 2019 (default):
$(IntDir)vc$(PlatformToolsetVersion).pdb
The change to $(OutDir)
feels like a mistake to me, this is an abs path, whereas $(IntDir)
is normally a relative path.
Your own docs for PDB_OUTPUT_DIRECTORY
state that there's different behaviour for static library targets, which is what our two reproducing examples are. Unclear if it affects other types.
Steps to reproduce
We're able to reproduce it with a simpler test repo. Be on Windows, Visual Studio 2022, CUDA 11.7, CMake 3.21+ (earlier CMake may fail too, but untested)
:: Put a space in the abs path
mkdir "new folder"
cd "new folder"
:: Grab the project
git clone https://github.com/ptheywood/cmake-docker-github-actions.git
cd cmake-docker-github-actions
mkdir build
cd build
:: Configure
cmake .. -A x64 -G"Visual Studio 17 2022"
:: Build
cmake --build . --config Release --target ALL_BUILD --verbose
This should then fail:
Project "C:\Users\rob\usfd_model\new folder\cmake-docker-github-actions\build\cdga\cdga.vcxproj" (3) is building "C:\Users\rob\usfd_model\new folder\cmake-docker-github-actions\build\cdga\cdga.vcxproj" (3:2) on node 1 (CudaBuildCore target(s)).
CudaBuildCore:
Compiling CUDA source file ..\..\src\cdga\Demo.cu...
cmd.exe /C "C:\Users\rob\AppData\Local\Temp\tmpf3f207b6a3c74d92a3589e5a3263b675.cmd"
"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\bin\nvcc.exe" -gencode=arch=compute_52,code=\"compute_52,compute_52\" -gencode=arch=compute_52,code=\"sm_52,compute_52\" --use-local-env -ccbin "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\bin\HostX64\x64" -x cu -I"C:\Users\rob\usfd_model\new folder\cmake-docker-github-actions\include" -I"C:\Users\rob\usfd_model\new folder\cmake-docker-github-actions\src" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\include" --keep-dir x64\Release -maxrregcount=0 --machine 64 --compile -cudart shared -std=c++17 -Xcompiler="/EHsc -Ob2" -D_WINDOWS -DNDEBUG -D"CMAKE_INTDIR=\"Release\"" -D_MBCS -DWIN32 -D_WINDOWS -DNDEBUG -D"CMAKE_INTDIR=\"Release\"" -Xcompiler "/EHsc /W1 /nologo /O2 /Fd"C:\Users\rob\usfd_model\new folder\cmake-docker-github-actions\build\lib\Release\cdga.pdb" /FS /MD /GR" -o cdga.dir\Release\Demo.obj "C:\Users\rob\usfd_model\new folder\cmake-docker-github-actions\src\cdga\Demo.cu"
C:\Users\rob\usfd_model\new folder\cmake-docker-github-actions\build\cdga>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\bin\nvcc.exe" -gencode=arch=compute_52,code=\"compute_52,compute_52\" -gencode=arch=compute_52,code=\"sm_52,compute_52\" --use-local-env -ccbin "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\bin\HostX64\x64" -x cu -I"C:\Users\rob\usfd_model\new folder\cmake-docker-github-actions\include" -I"C:\Users\rob\usfd_model\new folder\cmake-docker-github-actions\src" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\include" --keep-dir x64\Release -maxrregcount=0 --machine 64 --compile -cudart shared -std=c++17 -Xcompiler="/EHsc -Ob2" -D_WINDOWS -DNDEBUG -D"CMAKE_INTDIR=\"Release\"" -D_MBCS -DWIN32 -D_WINDOWS -DNDEBUG -D"CMAKE_INTDIR=\"Release\"" -Xcompiler "/EHsc /W1 /nologo /O2/Fd"C:\Users\rob\usfd_model\new folder\cmake-docker-github-actions\build\lib\Release\cdga.pdb" /FS /MD /GR" -o cdga.dir\Release\Demo.obj "C:\Users\rob\usfd_model\new folder\cmake-docker-github-actions\src\cdga\Demo.cu"
nvcc fatal : A single input file is required for a non-link phase when an outputfile is specified