-
Notifications
You must be signed in to change notification settings - Fork 514
/
BundleContents.md
286 lines (200 loc) · 10.9 KB
/
BundleContents.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# Content bundled in the app bundle
There are a few items that are automatically included during the build, and
that we're supposed to copy to the app bundle somehow:
* `@(None)` and `@(EmbeddedResource)` items with the `CopyToOutputDirectory` or the
`CopyToPublishDirectory` metadata set (to either `Always` or
`PreserveNewest`).
* `CopyToOutputDirectory` doesn't work with directories (for frameworks),
in that case `CopyToPublishDirectory` must be used.
* `@(Content)` and `@(BundleResource)` items (the `CopyToOutputDirectory` or
`CopyToPublishDirectory` metadata has no effect on these items).
* Runtime packs (our own, or the runtime itself (CoreCLR/MonoVM)). We have
some logic to detect this.
* The output from referenced projects (transitively).
* NuGets with a runtimes/RID/native directory. An aggravating issue here is
that NuGet will strip the relative path at some point ([dotnet publish with
a rid flattens Nuget package
files](https://github.com/dotnet/sdk/issues/9643)).
* The ResolvePackageAssets adds to the NativeCopyLocalItems group
* Then ResolveLockFileCopyLocalFiles adds it to ReferenceCopyLocalPaths
* And of course files added directly to `@(ResolvedFileToPublish)`.
The problem is that we have to decide where to place these files in the app
bundle.
For this purpose, we support the `PublishFolderType` metadata on items in the
`ResolvedFileToPublish` item group, and will place these files accordingly.
Below is a list of known/valid `PublishFolderType` values and the
corresponding action taken for each.
In all cases the relative directory is preserved (i.e. we don't follow the
behavior in [dotnet/sdk#9643](https://github.com/dotnet/sdk/issues/9643).
If the `PublishFolderType` metadata isn't set, we'll try to guess. If we guess
wrong, then developers can override the target location by:
* Setting `PublishFolderType=None` on items.
* Setting the `TargetPath` metadata on items to specify a different location
in the app bundle (if `PublishFolderType` is also set, the `TargetPath` path
is relative to the folder of the specified `PublishFolderType` value).
* The `Link` metadata can be used just like `TargetPath`.
* For some item groups it's also possible to set `CopyToOutputDirectory=Never`
on items that shouldn't be copied.
## The guessing
* `@(Content)` or `@(EmbeddedResource)` items: `PublishFolderType=Resource`
* `@(BundleResource)` items: `PublishFolderType=Resource`
* Assemblies and their related files (\*.dll, \*.exe, \*.pdb, \*.mdb,
\*.config):
* If the `PackageDebugSymbols` property is set to `true': `PublishFolderType=Assembly`.
* If the `PackageDebugSymbols` is set to something else: `PublishFolderType=None`.
* If the `PackageDebugSymbols` is not set: `PublishFolderType=None` for
release builds, `PublishFolderType=Assembly` otherwise.
* \*.xml: if there's an assembly with the same name (\*.exe or \*.dll), then `PublishFolderType=None`
* A \*.resources directory or a \*.resources.zip file next to an assembly with
the same name is treated as a third-party binding
(`PublishFolderType=AppleBindingResourcePackage`), and we handle it as such
(the exact details are not relevant for this discussion).
* Native frameworks (\*.framework/\*): `PublishFolderType=AppleFramework`
* Native xc frameworks (\*.xcframework/\*): `PublishFolderType=AppleFramework`
* Resources (*.jpg, *.png, ...?): `PublishFolderType=Resource`
* \*.framework.zip and \*.xcframework.zip:
`PublishFolderType=CompressedAppleFramework`
* \*.dylib: `PublishFolderType=DynamicLibrary`
* \*.so: `PublishFolderType=PluginLibrary`
* \*.a: `PublishFolderType=StaticLibrary`
* No other files are copied. We show a warning if we find any such files.
## Known/valid PublishFolderType values
### None
The item won't be copied to the app bundle.
### RootDirectory
The item will be copied to the root directory of the app bundle. The `Link`
metadata can be used to place an item in a subdirectory relative to the root
directory.
### Assembly
The item is copied to where the managed assemblies are located in the app
bundle.
The assembly will not be AOT-compiled (only assemblies that are reachable by
iterating recursively over all assembly references starting with the
executable assembly are AOT-compiled), and won't be executable on platforms
where AOT-compilation is required.
The target directory is:
* iOS, tvOS: the root directory of the app bundle
* macOS, Mac Catalyst: the `Contents/MonoBundle/` subdirectory (the
`MonoBundle` name can be customized if desired).
### Resource
Items are copied to where resources are located in the app bundle.
The target directory is:
* iOS, tvOS: the root directory of the app bundle
* macOS, Mac Catalyst: the `Contents/Resources/` subdirectory.
### AppleBindingResourcePackage
This is a third-party binding resource package, and the actual action
performed depends on the contents of the package (we'll link with static
libraries, link with and embed dynamic libraries and frameworks).
Setting the `TargetPath` or `Link` metadata has no effect these items.
### CompressedAppleBindingResourcePackaged
Treated as a zipped third-party binding resource (first unzipped, and then
treated as `AppleBindingResourcePackage`).
### AppleFramework
* If the item is a \*.framework or \*.xcframework directory, these directories
will be copied to the app bundle's Frameworks directory.
* If any of the item's containing directories is an \*.xcframework directory,
then select that directory instead.
* Otherwise, if any of the item's containing directories is a \*.framework
directory, then select that directory instead.
* This means that if a MyFramework.framework/MyFramework file is listed,
any other files in the MyFramework.framework directory will also be
copied to the app bundle.
* The order is important here: we're checking for \*.xcframework before
\*.framework, because the former will often contain the latter, and we
need to link with the former.
* Otherwise an error is shown.
We'll also link the native executable with the framework.
Setting the `TargetPath` or `Link` metadata has no effect these items.
### CompressedAppleFramework
The item is assumed to be a zip file containing one or more \*.framework or
\*.xcframework directories. The zip file will be decompressed, and the
\*.framework and \*.xcframework directories treated as `AppleFramework` items.
Setting the `TargetPath` or `Link` metadata has no effect these items.
### PlugIns
The target directory is:
* iOS, tvOS: the `PlugIns/` subdirectory.
* macOS, Mac Catalyst: the `Contents/PlugIns/` subdirectory.
### CompressedPlugIns
The item must be a zip file, which is decompressed, and then treated as
`PlugIns` (the contents of the zip file will be copied to the corresponding
`PlugIns` directory).
Setting the `TargetPath` or `Link` metadata has no effect these items.
If a plugin needs to be in a custom subdirectory, then put it in that
directory in the zip file.
## XpcServices
The target directory is:
* iOS, tvOS: the `XPCServices/` subdirectory.
* macOS, Mac Catalyst: the `Contents/XPCServices/` subdirectory.
### CompressedXpcServices
The item must be a zip file, which is decompressed, and then treated as
`XpcServices` (the contents of the zip file will be copied to the corresponding
`XPCServices` directory).
Setting the `TargetPath` or `Link` metadata has no effect these items.
If an xpc service needs to be in a custom subdirectory, then put it in that
directory in the zip file.
### DynamicLibrary
These are dynamic libraries (\*.dylib) files.
We will link with these libraries when linking the native executable.
The target directory is the same as for `Assembly`:
* iOS, tvOS: the root directory of the app bundle
* macOS, Mac Catalyst: the `Contents/MonoBundle/` subdirectory.
*Warning*: The App Store will reject any apps with \*.dylib files (for iOS and
tvOS, not for macOS or Mac Catalyst).
### PluginLibrary
These are plugins provided as un-versioned dynamic library (\*.so or \*.dylib) files.
An example are GStreamer plugins: `libgstogg.dylib`
We will _not_ link with these libraries when linking the native executable since
this type of plugins are loaded on demand at runtime.
The target directory is the same as for `DynamicLibrary`
*Warning*: The App Store will reject any apps with dynamic library files, for iOS and
tvOS plugins must be provided as static libraries.
### StaticLibrary
These are static libraries (\*.a) files.
We will link with these libraries when linking the native executable.
Static libraries are not copied to the app bundle.
### Unknown
We show a warning, and we don't copy the item to the app bundle (i.e. treat it
as `None`).
## Examples
### Example 1
```xml
<Content Update="MyImage.png" PublishFolderType="PlugIns" />
```
would put MyImage.png in MyApp.app/PlugIns/MyImage.png on iOS and tvOS, and
MyApp.app/Contents/PlugIns/MyImage.png on macOS and Mac Catalyst.
### Example 2
```xml
<Content Update="MyImage.png" PublishFolderType="PlugIns" Link="Subfolder/YourImage.png" />
```
would put MyImage.png in MyApp.app/PlugIns/Subfolder/YourImage.png on iOS and
tvOS, and MyApp.app/Contents/PlugIns/Subfolder/YourImage.png on macOS and Mac
Catalyst.
### Example 3
```xml
<Content Update="MyImage.png" Link="Resources/YourImage.png" />
```
would put MyImage.png in MyApp.app/Resources/YourImage.png on all platforms
(and that would be wrong for macOS and Mac Catalyst).
## FAQ
### I have a file I want to place in the app bundle. How do I do that?
If it doesn't fit any of the existing `PublishFolderType` values, you can add
it to the `None` items like this:
```xml
<None Include="MyFile.bin" CopyToPublishDirectory="Always" PublishFolderType="RootDirectory" />
```
### I want to put a file in a specific subdirectory, not related to any other content type
```xml
<None Include="MyFile.bin" CopyToOutputDirectory="PreserveNewest" PublishFolderType="RootDirectory" Link="Subfolder/MyFile.bin" />
```
### I don't want a file to be copied to the app bundle
The easiest way is to set `PublishFolderType` to `None`:
```xml
<EmbeddedResource Include="MyFile.bin" CopyToOutputDirectory="PreserveNewest" PublishFolderType="None" />
```
## References
* [.NET: What to do about files in ResolvedFileToPublish](https://github.com/xamarin/xamarin-macios/issues/12572)
* [[maccatalyst] NativeReference results in "bundle format is ambiguous (could be app or framework)"](https://github.com/xamarin/xamarin-macios/issues/12369)
* [[.NET 6] Files copies into MonoBundle get folder structure flattened](https://github.com/xamarin/xamarin-macios/issues/12386)
* [.NET: build fails when referencing BenchmarkDotNet](https://github.com/xamarin/xamarin-macios/issues/12418)
* [Having multiple .frameworks in a nuget package fails to build due to multiple info.plist files](https://github.com/xamarin/xamarin-macios/issues/12440)
* [Automatically include .framework or .a files in the NuGet's runtimes/ios/native folder](https://github.com/xamarin/xamarin-macios/issues/11667)