Create WindowsStore app with assets and asset folders

Sep 25, 2014 at 6:02 PM
Edited Sep 25, 2014 at 6:03 PM
I have a CMake script that creates a VS App project that I can install on my phone or PC (universal). How can I add the assets in their folders? For example, my folder structure looks like this:
Assets  -> Logo.png
        -> StoreLogo.png
        -> SomeFolder/AboutThisApp.txt
        -> Images/SomeImage.png
        -> Images/SomeOtherImage.png
cmake   -> some_files_i_need
src     -> Main.cpp
        -> App.h
        -> App.cpp
But when I create the project, all of the files inside of my Assets folder are added at the same place; all the subfolders are gone and files are placed in the same place.
This is how the generated VS looks like
Assets  -> Logo.png
        -> StoreLogo.png
        -> AboutThisApp.txt
        -> SomeImage.png
        -> SomeOtherImage.png
And the CMakeList looks like this
# This is where I look for all my assets
file(GLOB_RECURSE ASSETS_DIRECTORY "Assets/*.*")
set(CONTENT_FILES
  ${CMAKE_CURRENT_BINARY_DIR}/${APP_MANIFEST_NAME}
  ${ASSETS_DIRECTORY}
  )
# this is where they're added to the project
set_property(SOURCE ${CONTENT_FILES}         PROPERTY VS_DEPLOYMENT_CONTENT 1)
source_group("Assets" FILES ${CONTENT_FILES})
I need to keep the same folder structure inside of the app project.

Is this possible? thanks
Sep 26, 2014 at 5:47 AM
You have to call source_group() for each folder you want set up. You can write a macro or function that iterated your CONTENT_FILES, gets relative file path to the file, then calls source_group() with that relative path (I think you have to do a string replace on the path name to get the source_group name or something).
Oct 28, 2014 at 9:02 PM
Hi all!
I managed to get this working, reference: http://www.cmake.org/pipermail/cmake/2011-March/043207.html
The exact code I'm using is the following:
function(create_source_group sourceGroupName relativeSourcePath)
    FOREACH(currentSourceFile ${ARGN})
        FILE(RELATIVE_PATH folder ${relativeSourcePath} ${currentSourceFile})
        get_filename_component(filename ${folder} NAME)
        string(REPLACE ${filename} "" folder ${folder})
        if(NOT folder STREQUAL "")
            string(REGEX REPLACE "/+$" "" folderlast ${folder})
            string(REPLACE "/" "\\" folderlast ${folderlast})
            MESSAGE( STATUS "folder:         " "${sourceGroupName}\\${folderlast}"  )
            SOURCE_GROUP("${sourceGroupName}\\${folderlast}" FILES ${currentSourceFile})
        else(currentSourceFile ${ARGN})
            SOURCE_GROUP("${sourceGroupName}" FILES ${currentSourceFile})
        endif(NOT folder STREQUAL "")
    ENDFOREACH(currentSourceFile ${ARGN})
endfunction(create_source_group)

# more stuff here

file(GLOB_RECURSE ASSETS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Assets/*)
create_source_group("Assets" "${CMAKE_CURRENT_SOURCE_DIR}/Assets" ${ASSETS_DIRECTORY})
But now I have another issue, been trying to solve for hours now.
When the app builds and launches, the assets are copied to the root of the compiled app bundle, not to "Assets" folders or subfolders. I looked at the generated XML and found what's missing, for example, let's take a look at this (generated from CMake):
<None Include="C:\Users\my name here\Documents\project folder\Project Name\Assets\SomeFolder\AboutThisApp.txt">
    <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
    <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
    <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">true</DeploymentContent>
    <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'">true</DeploymentContent>
</None>
What's missing is a simple "Link" tag, so it should look like this:
<None Include="C:\Users\my name here\Documents\project folder\Project Name\Assets\SomeFolder\AboutThisApp.txt">
    <Link>Assets\SomeFolder\%(FileName)%(Extension)</Link>
    <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
    <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
    <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">true</DeploymentContent>
    <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'">true</DeploymentContent>
</None>
So, here's the question, how do I tell CMake to copy the files to their folders? The solution I've found is to use <Link></Link> but I don't know how to do this through CMake.

Thanks!
Pedro.
Coordinator
Oct 29, 2014 at 4:32 PM
Thanks for the report. Let me take a look at the code and see if Link is being handled.

~Gilles
Coordinator
Oct 30, 2014 at 7:10 PM
This would need to be added. I'll see what I can do to get this added to our fork.
Coordinator
Nov 1, 2014 at 6:49 AM
I've added the option in the assets branch.

Can you please try this release: https://cmakems.codeplex.com/releases/view/137218 and see if that works for you?

If it does, I'll add it our main branch and our multiplatform branch.

Thanks

~Gilles