WINDOWS_EXPORT_ALL_SYMBOLS vcxproj command failing

I just tried using CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS. when I run cmake build, I get an error saying

C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(152,5): error MSB3073: The command "setlocal [C:\User
s\davdf\code\mine\okiidoku\cpp\build\Debug\libs\okiidoku\okiidoku.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(152,5): error MSB3073: cd C:\Users\davdf\code\mine\ok
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(152,5): error MSB3073: if %errorlevel% neq 0 goto :cm
End [C:\Users\davdf\code\mine\okiidoku\cpp\build\Debug\libs\okiidoku\okiidoku.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(152,5): error MSB3073: C: [C:\Users\davdf\code\mine\o
kiidoku\cpp\build\Debug\libs\okiidoku\okiidoku.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(152,5): error MSB3073: if %errorlevel% neq 0 goto :cm
End [C:\Users\davdf\code\mine\okiidoku\cpp\build\Debug\libs\okiidoku\okiidoku.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(152,5): error MSB3073: "C:\Program Files\CMake\bin\cm
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(152,5): error MSB3073: if %errorlevel% neq 0 goto :cm
End [C:\Users\davdf\code\mine\okiidoku\cpp\build\Debug\libs\okiidoku\okiidoku.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(152,5): error MSB3073: :cmEnd [C:\Users\davdf\code\mi
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(152,5): error MSB3073: endlocal & call :cmErrorLevel
%errorlevel% & goto :cmDone [C:\Users\davdf\code\mine\okiidoku\cpp\build\Debug\libs\okiidoku\okiidoku.vcxproj]
code\mine\okiidoku\cpp\build\Debug\libs\okiidoku\okiidoku.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(152,5): error MSB3073: exit /b %1 [C:\Users\davdf\cod
e\mine\okiidoku\cpp\build\Debug\libs\okiidoku\okiidoku.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(152,5): error MSB3073: :cmDone [C:\Users\davdf\code\m
ine\okiidoku\cpp\build\Debug\libs\okiidoku\okiidoku.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(152,5): error MSB3073: if %errorlevel% neq 0 goto :VC
End [C:\Users\davdf\code\mine\okiidoku\cpp\build\Debug\libs\okiidoku\okiidoku.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(152,5): error MSB3073: :VCEnd" exited with code -1073
741819. [C:\Users\davdf\code\mine\okiidoku\cpp\build\Debug\libs\okiidoku\okiidoku.vcxproj]

I noticed there’s a command line that just says “C:”.

It seems weird. If I remove it, I stop getting the error. I did a bit of shallow searching through the cmake repo. Nothing seems wrong with AddSymbolExportCommand(...). I notice the call to this->GeneratorTarget->GetPreLinkCommands() right before the usage of AddSymbolExportCommand. I assume that’s where the “C:” is being added. I searched for calls to AddPreLinkCommand and found all the AddCustomCommandToTarget calls and at that point I think I’m out of my depth.

I’m on Windows 10, I just upgraded to Visual Studio Build Tools 2022 17.1.6. I’m using cmake 3.23.1 installed from chocolatey. That’s the same one being used by the vcproj command (C:\Program Files\CMake\bin\cmake.exe).

Note: after getting past this error, I start getting errors about ‘unresolved external symbol "__declspec(dllimport)’, (my cli target not being able to link to my shared library target) but I think that’s just a problem with my setup that I need to figure out.

I suspect that somewhere is a path with \ that escapes the first character after it and confuses things. Are there any \-using paths in your cache file?

In my CMakeCache.txt there is this line

//Command to build the project
MAKECOMMAND:STRING="C:\Program Files\CMake\bin\cmake.exe" --build . --config "${CTEST_CONFIGURATION_TYPE}"

I also did a --trace-expand. I searched the output for “C:” and found these

In a function called “GetDefaultWindowsPrefixBase”

C:/Program Files/CMake/share/cmake-3.23/Modules/CMakeGenericSystem.cmake(116):  set(_PREFIX_ENV_VAR ProgramFiles )
C:/Program Files/CMake/share/cmake-3.23/Modules/CMakeGenericSystem.cmake(118):  if(C:\Program Files STREQUAL  )
C:/Program Files/CMake/share/cmake-3.23/Modules/CMakeGenericSystem.cmake(122):  else()
C:/Program Files/CMake/share/cmake-3.23/Modules/CMakeGenericSystem.cmake(124):  if(C:\Program Files STREQUAL C:\Program Files )
C:/Program Files/CMake/share/cmake-3.23/Modules/CMakeGenericSystem.cmake(127):  if(NOT x64 STREQUAL x64 )
C:/Program Files/CMake/share/cmake-3.23/Modules/CMakeGenericSystem.cmake(147):  if(NOT C:\Program Files STREQUAL  )
C:/Program Files/CMake/share/cmake-3.23/Modules/CMakeGenericSystem.cmake(148):  file(TO_CMAKE_PATH C:\Program Files _base )
C:/Program Files/CMake/share/cmake-3.23/Modules/CMakeGenericSystem.cmake(155):  set(CMAKE_GENERIC_PROGRAM_FILES C:/Program Files PARENT_SCOPE )
C:/Program Files/CMake/share/cmake-3.23/Modules/Platform/WindowsPaths.cmake(32):  foreach(v ProgramW6432 ProgramFiles ProgramFiles(x86) )
C:/Program Files/CMake/share/cmake-3.23/Modules/Platform/WindowsPaths.cmake(33):  if(DEFINED ENV{ProgramW6432} )
C:/Program Files/CMake/share/cmake-3.23/Modules/Platform/WindowsPaths.cmake(34):  file(TO_CMAKE_PATH C:\Program Files _env_programfiles )
C:/Program Files/CMake/share/cmake-3.23/Modules/Platform/WindowsPaths.cmake(35):  list(APPEND _programfiles C:/Program Files )
C:/Program Files/CMake/share/cmake-3.23/Modules/Platform/WindowsPaths.cmake(36):  unset(_env_programfiles )
C:/Program Files/CMake/share/cmake-3.23/Modules/Platform/WindowsPaths.cmake(33):  if(DEFINED ENV{ProgramFiles} )
C:/Program Files/CMake/share/cmake-3.23/Modules/Platform/WindowsPaths.cmake(34):  file(TO_CMAKE_PATH C:\Program Files _env_programfiles )
C:/Program Files/CMake/share/cmake-3.23/Modules/Platform/WindowsPaths.cmake(35):  list(APPEND _programfiles C:/Program Files )
C:/Program Files/CMake/share/cmake-3.23/Modules/Platform/WindowsPaths.cmake(36):  unset(_env_programfiles )
C:/Program Files/CMake/share/cmake-3.23/Modules/Platform/WindowsPaths.cmake(33):  if(DEFINED ENV{ProgramFiles(x86)} )
C:/Program Files/CMake/share/cmake-3.23/Modules/Platform/WindowsPaths.cmake(34):  file(TO_CMAKE_PATH C:\Program Files (x86) _env_programfiles )
C:/Program Files/CMake/share/cmake-3.23/Modules/Platform/WindowsPaths.cmake(35):  list(APPEND _programfiles C:/Program Files (x86) )
C:/Program Files/CMake/share/cmake-3.23/Modules/Platform/WindowsPaths.cmake(36):  unset(_env_programfiles )
C:/Program Files/CMake/share/cmake-3.23/Modules/CTest.cmake(232):  build_command(MAKECOMMAND_DEFAULT_VALUE CONFIGURATION ${CTEST_CONFIGURATION_TYPE} )
C:/Program Files/CMake/share/cmake-3.23/Modules/CTest.cmake(234):  set(MAKECOMMAND "C:\Program Files\CMake\bin\cmake.exe" --build . --config "${CTEST_CONFIGURATION_TYPE}" CACHE STRING Command to build the project )
C:/Program Files/CMake/share/cmake-3.23/Modules/CTest.cmake(239):  set(DEFAULT_CTEST_CONFIGURATION_TYPE  )

I tried searching for non-escape_identity cmake escape sequences but there weren’t any in the trace.

That certainly doesn’t seem good. Do things work if you replace it with forward slashes?

I changed the line the CMakeCache.txt file to use forward slashes and I still got the “C:” line in the vcxproj command element. I’m assuming I shouldn’t (or in other cases just can’t) change the cmake files I see in the --trace-expand log that are not defined in my own project. Let me know if there’s anything specific I should try with respect to this.

Remember how I said that when I remove that “C:” line from the vcxproj command element, I stop getting the command error, but then I get errors saying that when building my cli target, it can’t resolve the symbols from my library target? There’s something new I noticed: I just opened the exports.def file that got created and it’s empty. When I try manually running the pre-link command that cmake is trying to run:

cmake -E __create_def C:/Users/.../exports.def C:/Users/.../objects.txt

It exits with segfault and no other message. Nothing seems wrong about the contents of my objects.txt file. It lists full paths to the object file of my project.

whoops. I got a reply autoremoved because I was editing it too much and it got filtered as spam. It should be back once reviewed. Sorry about that. Continuing on what I was saying there, though, I may have found a bug? when I manually run the cmake -E __create_def command the first time, it exits with SegFault. But if I run it again, it runs fine and then creates and empty file (which also isn’t what I expect, but at least it doesn’t segfault). Turns out it segfaults if the exports.def file isn’t already created. The first run that segfaults creates the file, and then the second run finds the file already existing.

Note: The generator I’m using is “Visual Studio 17 2022”. I don’t think that’s related to the problem. I wonder if it could possibly be this line in cmcmd.cxx that gets something time-related to the exports.def file. Maybe it’s expecting it to exist and not handling the case of it not existing?

I’m just going to add replies instead of editing old ones now.

Okay so I tried creating an empty exports.def file with a timestamp older than all the object files, and that also results in a segfault. It’s not only if the file doesn’t exist yet. It also exhibits the behaviour of no longer segfaulting (but still creating an empty file) the second time, since I guess the first time still changes the modification time of the file.

I think I may be having problems here because I don’t have an nm command on my path. It seems the default NmPath for bindexplib is “nm”.

Ah. I think the segfault is certainly worth a new issue at least. I’m not familiar enough with the create_defs bit to know whether nm is essential or not (probably is?).