MantisBT - CMake
View Issue Details
0013749CMakeCMakepublic2012-11-27 18:492013-05-06 09:32
jujjyl 
 
normalblockalways
closedduplicate 
MicrosoftWindows8 RT
CMake 2.8.10.1 
 
0013749: Cannot target Windows 8 RT from CMake without workarounds.
I tried to make CMake generate .vcxproj files that would build into Windows 8 RT application bundles. Not ARM, just on standard Win 8 RT, e.g. for Win 8 Store.

I use the -G "Visual Studio 11" generator.

The only support I found for this is to do

set_target_properties(project_name PROPERTIES VS_WINRT_EXTENSIONS TRUE)
add_definitions(-ZW)

(this was from http://stackoverflow.com/questions/13228829/is-it-possible-to-create-winrt-project-with-cmake [^] , I do not need the xaml files, so only steps 1 & 2 applied for me)

These step were not enough. This is what I found missing:

1. The .vcxproj should have an element "<AppContainerApplication>true</AppContainerApplication>" for the VC project that is to be deployed into an Win8 RT app. This is missing in the generated .vcxproj.

As a workaround, I use a sed script to add that line in an extra batch script that is run after cmake finished. The line reads:

sed -r -i "s#</ProjectName>#</ProjectName> <AppContainerApplication>true</AppContainerApplication>#g" ProjectFileGeneratedByCMake.vcxproj

2. When targeting Win8 RT, it is required that the project contains an app manifest ('Package.appxmanifest'), and a required set of logo images 'Logo.png', 'SmallLogo.png', 'SplashScreen.png' and 'StoreLogo.png'. Also (not 100% sure if is required for development) there is a signing key file.

I added these files manually to my source code folder. They need to be added into the VC project, so that VC bundles the image files to the build, and knows which manifest file to read. I tried to do this with the same way I add .cpp and .h files:

file(GLOB sourceFiles *.cpp)
set(sourceFiles ${sourceFiles} ${Win8RTBuildRoot}/Assets/SmallLogo.png)
set(sourceFiles ${sourceFiles} ${Win8RTBuildRoot}/Assets/StoreLogo.png)
set(sourceFiles ${sourceFiles} ${Win8RTBuildRoot}/Assets/SplashScreen.png)
set(sourceFiles ${sourceFiles} ${Win8RTBuildRoot}/Assets/Logo.png)
set(sourceFiles ${sourceFiles} ${Win8RTBuildRoot}/gfxapi_application_TemporaryKey.pfx)
set(sourceFiles ${sourceFiles} ${Win8RTBuildRoot}/Package.appxmanifest)
add_executable(projectName WIN32 ${sourceFiles})

This works in the sense that the files appear in the project. But they are defined wrong in .vcxproj, and VC gets confused and will say the files are missing even though they are there. The .vcxproj file will read

<None Include="Assets\SmallLogo.png" />
<None Include="Assets\StoreLogo.png" />
<None Include="Assets\SplashScreen.png" />
<None Include="Assets\Logo.png" />
<None Include="application_TemporaryKey.pfx" />
<None Include="Package.appxmanifest" />

If the files are added manually, they will instead read

<Image Include="Assets\SmallLogo.png" />
<Image Include="Assets\StoreLogo.png" />
<Image Include="Assets\SplashScreen.png" />
<Image Include="Assets\Logo.png" />
<None Include="application_TemporaryKey.pfx" />
<AppxManifest Include="Package.appxmanifest" />

As a workaround, I added two sed scripts that replace 'None' with 'Image' for .png files and with 'AppxManifest' for .appxmanifest files. Perhaps I did not know of the proper way to add these to VC project, or the support is missing? Perhaps CMake should always add image files as Image and .appxmanifest files as AppxManifest, as there is probably no reason to have None for these. (what other types might there be for which VC adds some other element than None, but cmake does not?)

These workaround sed scripts read:

sed -r -i "s/None Include=\"(.*)\.png\"/Image Include=\"\1\.png\"/g" ProjectFileGeneratedByCMake.vcxproj
sed -r -i "s/None Include=\"(.*)\.appxmanifest\"/AppxManifest Include=\"\1\.appxmanifest\"/g" ProjectFileGeneratedByCMake.vcxproj

With these three sed workarounds, the solution and project files can now be 'Deploy'ed as Win8 RT apps and run in Metro UI.
Suggestions:

1. Add a new magic string WIN8RT to be recognized by add_executable, like

add_executable(projectName WIN8RT ${sourceFiles})

This would be used instead of the magic string 'WIN32' to signal that the executable is to be a Win8 RT app.

When WIN8RT is specified, either
 a) omitting a .appxmanifest file from ${sourceFiles} is cmake generation error, or
 b) if custom .appxmanifest is omitted, a default one is automatically generated and used.

This is because when building as a win8 app, the build will fail if there is no manifest. Also, the build will fail if the required logo images are not present, so their addition should somehow be enforced as well.

2. Don't add image and appxmanifest items with the XML element <None> to the vcxproj, but add them with <Image> and <AppxManifest>.


If I did not find something and there is already an abstraction/mechanism to these issues, please let me know!
No tags attached.
duplicate of 0013511closed Brad King Add support for WinRT platforms and "metro" apps 
related to 0012930closed Brad King [patch] CMake does not support Visual Studio 11 WinRT project type 
related to 0013498closed  CMake does not fully support Visual Studio 11 WinRT project type 
related to 0013791closed Brad King CMake does not support generating projects for Windows Phone 8. 
Issue History
2012-11-27 18:49jujjylNew Issue
2012-11-28 08:33Brad KingRelationship addedrelated to 0012930
2012-11-28 08:33Brad KingRelationship addedrelated to 0013511
2012-11-28 08:34Brad KingRelationship addedrelated to 0013498
2012-11-28 08:43Brad KingStatusnew => backlog
2012-11-28 08:43Brad KingNote Added: 0031739
2012-12-13 15:42jujjylNote Added: 0031879
2012-12-13 16:15Brad KingRelationship addedrelated to 0013791
2012-12-18 08:01Brad KingRelationship replacedduplicate of 0013511
2012-12-18 08:01Brad KingNote Added: 0031916
2012-12-18 08:01Brad KingStatusbacklog => resolved
2012-12-18 08:01Brad KingResolutionopen => duplicate
2013-05-06 09:32Robert MaynardNote Added: 0032989
2013-05-06 09:32Robert MaynardStatusresolved => closed

Notes
(0031739)
Brad King   
2012-11-28 08:43   
Issues 0013511, 0013498, 0013749 are all asking for WinRT support in some form. The existing CMake features for it were contributed by a user in 0012930. No progress is being made on these issues by upstream CMake developers. Please propose patches.

There should be no new keyword arguments to add_executable. Any information needed can be added to a target with the "set_property(TARGET ...)" command.
(0031879)
jujjyl   
2012-12-13 15:42   
Additional requirement that has been uncovered is that if a VS2012 solution contains multiple projects that all deploy to a Windows 8 Store application, then the executable output directory, i.e. $(OutDir), must be unique for each of them. Currently this is not enforced, and if the executables are output in the same directory, they fail at the end of build step when Visual Studio generates an application build manifest "AppxManifest.xml" for each project, causing the generated manifests replace each other and only surviving the last one generated.

Visual Studio will complain something like "The manifest for this project refers to nonexisting file anotherprojectname.exe"

As a workaround, manually ensuring that the $(OutDir) parameter for each project in the solution is unique to that project resolves the issue.
(0031916)
Brad King   
2012-12-18 08:01   
Resolving as duplicate of 0013511.
(0032989)
Robert Maynard   
2013-05-06 09:32   
Closing resolved issues that have not been updated in more than 4 months.