add_custom_command() with target as COMMAND does not work with a custom configuration (Visual Studio 2019)
I'm using CMake 3.14.5 and am working with Visual Studio 2019.
In my root CMakeLists.txt, I'm adding (via an included script) an extra configuration to my root project using the following commands:
# Additional configuration: DebugLocsim
if(CMAKE_CONFIGURATION_TYPES AND MSVC)
set(CMAKE_CXX_FLAGS_DEBUGLOCSIM "${CMAKE_CXX_FLAGS_DEBUG}")
set(CMAKE_C_FLAGS_DEBUGLOCSIM "${CMAKE_C_FLAGS_DEBUG}")
set(CMAKE_EXE_LINKER_FLAGS_DEBUGLOCSIM "${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
set(CMAKE_SHARED_LINKER_FLAGS_DEBUGLOCSIM "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUGLOCSIM "C:/Locsim/DLL/")
if (NOT "DebugLocsim" IN_LIST CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES "DebugLocsim;${CMAKE_CONFIGURATION_TYPES}" CACHE STRING "" FORCE)
endif()
set(CMAKE_MAP_IMPORTED_CONFIG_DEBUGLOCSIM Debug)
endif()
In a direct subdirectory, where I'm creating a static library, I'm using Google Protobuf via the following command:
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTOBUF_FILES})
where {PROTOBUF_FILES}
contains my two protobuf definition (.proto) files.
This works fine for the Debug and Release configurations (I'm not using the other two predefined ones), but not for the special DebugLocsim one. A look at the generated vcxproj file shows the direct cause:
<ItemGroup>
<CustomBuild Include="D:\Projects\locsim\modules\etcs\build_x86\CMakeFiles\f5d01e55a32d1ae818c62a2ed39eae56\TrainUnit_LV.pb.h.rule">
<Message Condition="'$(Configuration)|$(Platform)'=='DebugLocsim|Win32'">Running cpp protocol buffer compiler on TrainUnit_LV.proto</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='DebugLocsim|Win32'">setlocal
protobuf::protoc-NOTFOUND --cpp_out D:/Projects/locsim/modules/etcs/build_x86/protobuf -I D:/Projects/locsim/modules/etcs/protobuf D:/Projects/locsim/modules/etcs/protobuf/TrainUnit_LV.proto
if %errorlevel% neq 0 goto :cmEnd
:cmEnd
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
:cmErrorLevel
exit /b %1
:cmDone
if %errorlevel% neq 0 goto :VCEnd</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='DebugLocsim|Win32'">D:/Projects/locsim/modules/etcs/build_x86/CMakeFiles/f5d01e55a32d1ae818c62a2ed39eae56/TrainUnit_LV.pb.h.rule;D:\Projects\locsim\modules\etcs\protobuf\TrainUnit_LV.proto;protobuf::protoc-NOTFOUND;%(AdditionalInputs)</AdditionalInputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='DebugLocsim|Win32'">D:\Projects\locsim\modules\etcs\build_x86\protobuf\TrainUnit_LV.pb.h;D:\Projects\locsim\modules\etcs\build_x86\protobuf\TrainUnit_LV.pb.cc</Outputs>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='DebugLocsim|Win32'">false</LinkObjects>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Running cpp protocol buffer compiler on TrainUnit_LV.proto</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">setlocal
D:\Projects\locsim\x86\bin\protoc.exe --cpp_out D:/Projects/locsim/modules/etcs/build_x86/protobuf -I D:/Projects/locsim/modules/etcs/protobuf D:/Projects/locsim/modules/etcs/protobuf/TrainUnit_LV.proto
if %errorlevel% neq 0 goto :cmEnd
:cmEnd
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
:cmErrorLevel
exit /b %1
:cmDone
if %errorlevel% neq 0 goto :VCEnd</Command>
... more configurations ...
</ItemGroup>
The target protobuf::protoc
, which the protobuf_generate_cpp()
command uses internally, gets properly expanded to the executable path of the protoc compiler only for the predefined configurations. For the DebugLocsim configuration, it is being set to protobuf::protoc-NOTFOUND
.
Here's the relevant excerpt of the file protobuf-config.cmake
(in the function protobuf_generate()
, called by protobuf_generate_cpp()
):
add_custom_command(
OUTPUT ${_generated_srcs}
COMMAND protobuf::protoc
ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_protobuf_include_path} ${_abs_file}
DEPENDS ${_abs_file} protobuf::protoc
COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}"
VERBATIM )