Adding distinct Xcode resources for multiple executables using CMake - xcode

Background: I'm using CMake to configure a project that builds a combination of libraries and applications. Each application uses resource files such as images and text files that are unique to that application. Xcode understands the concept of resource files and can correctly copy them into the application bundle. If I were creating a project with exactly one application, there would be no problem: I can use CMake's set_source_files_properties(... PROPERTIES MACOSX_PACKAGE_LOCATION Resources) to tell Xcode to put the files into the bundle's Resources directory, such that a later call to [[NSBundle mainBundle] pathForResource:...] will correctly find them. (The pathForResource method searches the "Resources" directory by default.) The files also appear in the Resources group within the Xcode project.
Question: The problem appears when I include multiple applications in the CMake project. Each project needs to copy its own, distinct resource files into its own bundle's Resources directory. Therefore each application needs a distinct Resource group in Xcode in which to hold these files and from which to copy them. Yet these distinct directories must all be named "Resources." Ideally, each application-specific folder within Xcode would have its own unique "Resources" subdirectory with all of its needed resources. What actually happens is that the project has a single, shared Resources directory into which all the resource files are collected, and the project-specific "Resources" subdirectory contains only that application's info.plist file. Because all applications' resources are tossed into the same group, and because name collisions can occur (two projects with distinct files that have the same name), project bundles don't get the correct resource files.
Has anyone found a way to use CMake to setup an Xcode project that supports multiple applications with distinct resources? Or some other workaround?

My solution works for me but maybe this is not satisfying for you.
What I do is a simple copy files post build step where I copy my resources directly into the built Target.app.
The problem with my approach is that the files don't show up in the Xcode project.
Here is how I do it :
I override the ADD_EXECUTABLE macro. Inside, it evaluates the resource variable ${target}_RESOURCES.
So in my CMakeLists.txt for my target I collect some directories and resource files and store them as list in my target depending resource variable.
The following custom command is in my macro (could be anywhere, actually):
ADD_CUSTOM_COMMAND( TARGET ${target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -DFILES_LIST="${${target}_RESOURCES}" -DDESTINATION="\${TARGET_BUILD_DIR}/\${FULL_PRODUCT_NAME}" -DEXCLUDE_EXT=".svn .git CVS .DS_Store" -P ${ROOT_DIR}/cmake/scripts/copyFiles.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
COMMENT "Copying resource files and directories to iOS App Bundle..." )
It calls my copy files script (Maybe there is a better way to add that custom build step):
SEPARATE_ARGUMENTS( FILES_LIST )
FOREACH( ENTRY ${FILES_LIST} )
MESSAGE( "copying: ${ENTRY} to ${DESTINATION}" )
FILE( COPY ${ENTRY} DESTINATION ${DESTINATION} PATTERN "${EXCLUDE_EXT}" EXCLUDE )
ENDFOREACH( ENTRY )
It works for me. I don't really care if the resources show up in the XCode project.
But I still would like to know.
Are there are any problems or issues when not having the files in Xcode?

Related

premake5: add files to "Copy Bundle Resources" build phase

I have some image files I need to add to an Xcode project. I need the files to be included in the Copy Bundle Resources build phase. I also need Type to be set to Data to avoid any compression or processing by Xcode.
Is this possible with premake5?
You can use a filter to select the files and then do an embed action
filter "files:%{prj.name}/Res/**"
buildaction "Embed"
This example adds all of the files in the Res folder to the Copy Bundle Resources. Although XCode won't show them in the Copy Bundle Resources list they should still show up in the target directory after you build and run the project.
https://github.com/premake/premake-core/wiki/buildaction

Create archive without Xcode

I am building an Xcode project from console over ssh (I can use only xcodebuild command), but there are no schemes in the project (user forgot to make schemes shared). xcodebuild allows to pass "archive" parameter only if building scheme (-scheme), but that is not an option for me.
So the question is: is it possible to create archive using only target?
I investigated .xcarchive directory, it contains Info.plist file (which contains information about application), dSYMs directory (containing myapp.dSYM) and Products/Applications (containing myapp.app) directory. I also noted that the file size of binary in .xcarchive's .app is 2 times smaller than in .app that is in Release directory. I guess it is because of code signage.
Can I simply copy files from Release directory (.app and .dSYM) to .xcarchive and create Info.plist there to create archive? Or are there any other steps that I must take?
yes, archives are only folders you can make yourself.
look at ANY archive and try to replicate the folder structure. (changing the appname as required)

What is the difference between Copy Bundle Resources and Copy Files for Xcode build phases?

Could someone explain the difference between the Copy Bundle Resources phase of Xcode and a Copy Files phase? When would I use "Copy Files"?
Copy Bundle Resources phase copies files that you want to be available in your bundle (.app). On the other hand Copy Files phase copies files to other (standard) locations accessible from your application (for example to /Library/Fonts) giving you also the option to copy them only when installing. You can also see relevant documentation here
Xcode Copy Files vs Copy Bundle Resources
Copy Files - Copies files from a project to an external specified location.
It is useful, for example, when you are creating an Objective-C Static Library where you should expose .modulemap[About] or/and umbrella.h[About] files
Copy Bundle Resources - Copies files that support your source code into internal structure. If you want to make sure the files you added will get copied to the application bundle
It is useful, when you are creating an app where you can add images and other resources
Vocablurary

How to Specify Active Folder for ExternalBuildToolExecution on Xcode 4?

When using a make for an external build system on Xcode 4x, how to specify the active folder?
The active folder appears on the first line cd/
ExternalBuildToolExecution Action
cd /Users/myName/Documents/Xcode/myProject
setenv ACTION
By default, it is the folder of the project, i.e. /Users/myName/Documents/Xcode/myProject.
However, when the project is created by a template, the Xcode project adds a layer:
/Users/myName/Documents/Xcode/myProjec contains myProject.xcodeproject and another folder named
/Users/myName/Documents/Xcode/myProject/myProject with all the source code inside.
So I need to specify /Users/myName/Documents/Xcode/myProject/myProject
An alternative solution would consist on defining the Directory in a Target, but the question What is the key in Xcode template to define Directory in a Target? remains unanswered.

Xcode 4.2 — add derived files to project

I'm using bison parser generator in my Xcode 4 project. I've written custom build rule for generating C++-source file from *.y grammar file:
/usr/local/bin/bison
--defines="${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.hpp"
--output="${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.cpp"
--verbose "${INPUT_FILE_PATH}"
As you can see, Xcode places generated files in $DERIVED_FILES_DIR folder. Now I need to export generated header file grammar.hpp with object files as library.
The problem is that Xcode doesn't allow export files, that aren't included in project.
The first solution, as it seems, is to create a group with absolute path set to $DERIVED_FILES_DIR. Well, it actually works until I change my build settings to build Release configuration, since $DERIVED_FILES_DIR is dependent on build settings.
The second solution is somehow set group path to literally variable, i.e.
path = $DERIVED_FILES_DIR
So far I've found two possible ways to do it: How to reference files with environment variables? and File references relative to DERIVED_FILE_DIR in Xcode. Either way doesn't work for me.
Maybe someone knows better way to add generated files to project?
Your best options are:
Generate the files in your SRCROOT
Generate the files in BUILT_PRODUCTS_DIR
These both have "Relative to..." options that should allow you to add the files to your project.
I ended up generating files in ${SRCROOT} directory with custom make build target using Makefile that handles regenerating derived files. I just added these generated files to project, and made all actual build target depend on this make target.

Resources