0

I'm in the process of converting a rather huge project to a Windows 10 Store app. I've gotten it to compile and now can't get past several APPX1101 errors - "Payload contains two or more files with the same destination path". The files are .xml files part of the project, e.g. "baseDir\Assets\foo\timers.xml" and "baseDir\Assets\bar\timers.xml". Different files and different paths.

The solution and projects are created by CMake (3.72). The cmake files have been modified to support creating a Windows 10 store app platform config.

It appears that the directory tree has been flattened and files are overlapping. But how or why eludes me. Every UWP project I've seen contains an "Assets" folder under the main project but this one does not. I see files such as Logo.png and SplashScreen.png in folder named "Resource Files". The files causing the errors are under the folder named "Assets" which existed before this was a UWP project.

Primarily: How can I fix this error? Did I misconfigure CMake?

Additionally: How to avoid directory flattening? There are a few hundred data files taking up a few hundred megabytes used by the program. Will I need to add each of them to the solution to be packaged?

Updates:

I've gleaned more info but not enough to fully satisfy the question. The directory flattening in the output occurs due to how the files are added to the project via CMake and how the original Windows product was packaged. The XML files are added to the project with a full path in the .vcxproj. The .vcxproj.filters also use a full path to the file and a filter like "Data\foo". The desktop Windows version didn't need to care since it knew where to find it's data relative to the executable and was packaged by an external tool.

I've manually added an "Assets" filter and modified the .vcxproj and .vcxproj.filters files. The .vcxproj file needed a property added to the file's include. This uses relative paths and gets rid of the APPX1101 duplicate error.

.vcxproj

<XML Include="..\Base\Assets\foo\Data\timers.xml">
  <Link>Assets\foo\Data\timers.xml</Link>
</XML>

.vcxproj.filters

<XML Include="..\Base\Assets\foo\Data\timers.xml">
  <Filter>Assets\foo</Filter>
</XML>

Update 2

From what I can tell, it's not possible to get CMake to add a <Link> to XML and other .vcxproj Include types. I went through the latest CMake source code (3.8rc). The <XML Include> is added to the .vcxproj in cmVisualStudio10TargetGenerator::WriteExtraSource() in cmVisualStudio10TargetGenerator.cxx. Other types have the option to set the flag to add the <Link> but XML and other data types do not have code to set the flag.

The only options I can see are modifying CMake source or reworking the project to add data files using relative paths that match the same <Filter> for the matching Include in the vcxproj.filters file. This is only a problem with CMake. Visual Studio 2015/2017 have no problem adding assets above your tree. The MS UWP examples on GitHub do it to share common data between sample projects.

ChocoBilly
  • 409
  • 3
  • 10
  • Have you tried the solution in this [question](http://stackoverflow.com/questions/38593840/payload-contains-two-or-more-files-with-the-same-destination-path-system-diagno), ensure the references' version have no conflicts. But based on your exception, it seems like there are two sample xml file in your payload, could you compile your project in Visual Studio? – Franklin Chen - MSFT Feb 16 '17 at 09:25
  • And could you please share how you set the Assets files in your CMakeLists.txt file? `set(ASSET_FILES ${ASSET_FILES}....` – Franklin Chen - MSFT Feb 16 '17 at 09:55
  • @FranklinChen-MSFT I've narrowed it down to how the assets are added. The CMake files used to create the .sln were adapted from a Win64 version that worked and shipped. Evidently some things got missed. The solution compiles with no errors. The problem occurs in the link phase. I'll update the question with info I've learned that may help clarify. – ChocoBilly Feb 16 '17 at 20:51
  • ASSET_FILES are still the same as the Windows project which explains why I don't have the typical "Assets" filter in the project. With verbose output I could see the files being added with no path causing the conflict. I created an Assets filter then manually edited the .vcxproj to add a to a path relative to "Assets" to the file's – ChocoBilly Feb 16 '17 at 21:02

1 Answers1

1

It's been a while and I'm posting this as an answer in case someone else runs into this problem. I'm not marking it accepted because I find the workaround rather weak. My knowledge of CMake is limited and my understanding of Universal Windows apps even less.

The primary issue is that by design, CMake does not build a relocatable solution. i.e. you can't xcopy a Windows solution to another tree and expect it to work as you would would with one generated from within the Visual Studio IDE.

The second issue is that this was a huge pre-existing project already targeting multiple platforms. And by huge, I mean it ships on a dual layer blu-ray disc. The location of asset files was fixed and was above the location of the CMake build folder. This caused files to be stripped of their path when added to the layout whenever their location was not under the expected assets folder.

There is no way in the current CMake (3.8) to add a <link> tag to the include in the project file. And CMake creates the include tag with the full path to the file not a relative one by design.

The workaround I came up with was to add a step to the batch file that invokes CMake to edit the .vcproj and vcproj.filters files to change the fixed asset paths relative ones and then added another step to create a symbolic link/junction (SysInternals.com) under the build folder to the location where the assets were. The assets now appear as being under the expected asset folder are now added correctly to the layout.

As I said, not ideal but it works. The real solution would be to re-organize all the data but this is not something that can happen for this project when a vast amount of data is generated from different script, tools, sources and contributors.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
ChocoBilly
  • 409
  • 3
  • 10
  • There still does not appear to be a better soluton, than to symlink and generate Includes. Our variation of it is to have a separate vcxproj listing all assets, and make it referenced by main project via cmake (3.14, 3.15 seem to work, others might not). mklink /J can be used to make a junction to assets directory under that project filetree, and there is any number of options to generate its Include content. – Андрей Вахрушев Dec 12 '19 at 09:55