Clang: *.manifest files listed as sources are ignored by GNU-like front-end on Windows
When building with clang (not clang-cl) on Windows, *.manifest files listed as sources for an executable or dll target are not embedded into the executable or dll.
Ideally, CMake would add something like the following to the link line:
-Xlinker /MANIFEST:EMBED -Xlinker /MANIFESTINPUT:manifest1.manifest -Xlinker /MANIFESTINPUT:manifest2.manifest ...
To reproduce
Compare the link lines generated by the following project with CMAKE_CXX_COMPILER=clang-cl.exe vs CMAKE_CXX_COMPILER=clang++.exe. (I'm assuming a Ninja generator.)
With clang-cl, the manifest file is respected -- the link is performed via cmake.exe -E vs_link_exe
, which appears to embed the manifests via mt.exe. With clang++, the manifest file is ignored.
CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
project(TestProj CXX)
add_executable(my_exe my_exe.cpp compatibility.manifest)
my_exe.cpp
int main() { return 0; }
compatibility.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--The ID below indicates application support for Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
</assembly>
Tested with CMake 3.21.2, LLVM 11.0.0, MSVC 19.29, Ninja 1.10.2
Workaround
Add the linker args manually:
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND MSVC_VERSION AND NOT MSVC)
target_link_options(my_exe PRIVATE
"LINKER:/MANIFEST:EMBED"
"LINKER:/MANIFESTINPUT:${CMAKE_CURRENT_SOURCE_DIR}/compatibility.manifest"
)
endif ()
Edited by Brad King