So I have a DLL that is being built with CMake that requires a specific manifest file to be embedded. In Visual Studio settings I can just add the manifest filename under Manifest Tool/Input and Ouput/Additional Manifest Files, and it works correctly. It seems like this is something that should be doable with CMake, but I have been unable to figure it out.
Any ideas on how I can accomplish this with CMake?
cmake-3.4 has now learned how to handle *.manifest files listed as source files.
https://cmake.org/cmake/help/v3.4/release/3.4.html#other
This was very helpful. Here's what I ended up doing for a DLL that needed an MSVCR90 manifest, your mileage may vary:
It's not possible to generate the
Additional Manifest Files
field in CMake (I checked the source code). So we have to be sneakier.Visual generates a manifest of its own ( yourapp.exe.manifest.intermediate ) and mixes it with yours. So we have to generate this manifest once, disable the generation, and use the generated manifest afterwards.
Generating the manifest :
This step is optional if you know how to write a complete manifest by yourself. If you're like the rest of the world :
Additional Manifest Files
)Disabling the generation :
Using the generated manifest afterwards :
This is done by a manual call to mt.exe (the manifest tool which is normally called after the linker... unless it's disabled) in a post-build step :
(You'll probably need to change $(TargetDir) to $(OutDir) depending on how you wrote your CMake; Use Visual's
Macros
button to see their values. And remember : #1 for executables, #2 for dlls)I just found out that you can merge multiple manifest files (or embedded manifests inside executables) into an existing manifest file (or executable) with mt.exe. This way, you don't have to disable automatic manifest generation of visual studio. You can just add new manifest data with mt.exe as a postbuild step. Example:
program.exe has embedded manifest:
dpiaware.manifest contains:
Run command:
Now program.exe contains embedded manifest:
I just went through this exercise myself, which is what brought me to this page. Calvin1602's answer pretty much lays out the solution, but I had to finagle the syntax a bit to make it work for me. Here are the exact commands that finally worked:
Note that you should use
#1
in themt.exe
command when the target is an application, and#2
when it's a DLL (at least, as far as I understand it--it didn't work for me until I changed the1
to a2
).Also, you can use
mt.exe
to extract the original manifest from the DLL if you want/need to. The command looks like this:It's not too hard to hand-edit the output if you have a manifest file for the dependency you want to merge in. But I sorta like Calvin1602's trick of having Visual Studio do it for you if you're using Visual Studio solution files rather than nmake.