When to use .xcconfig files - objective-c

I have just set up three different configurations in my project for debug preview and release. No in Xcode there is an option to specify different .xconfig files per configuration. I am now wondering in what circumstances they should/could be used and what their advantages are over just editing the build settings per configuration.

Use xcconfig files if you find yourself changing the same build settings for each project you create. Place the build settings you're changing in the xcconfig file. By using a xcconfig file you can avoid editing those build settings every time you create a project.
Having the option to use different xcconfig files for each build configuration allows you to place the debug build settings you're constantly changing in one xcconfig file and place the release build settings you're changing in another xcconfig file. Use multiple xcconfig files if the build settings you're changing have different values for debug and release builds or if you change some build settings only for debug builds and other build settings only for release builds.

It's not me who you asked about an example #Besi but I would like to explain why the BundleId change is useful at least for me.
When I have different requirements for "Development", "Ad Hoc", "App Store", for example I need to send Push Notifications, so the push certificate will be different depending on the version.
In this case I can make 3 different XCode schemes and depending on the chosen scheme, when compiling the bundle identifier will change so a different kind of version will result.
Add to this the fact you can use you xcconfig to choose the "Code Sign Identity", and practically every build setting you can imagine. This way is more correct than having different targets for each version and with different plist files and build settings, because you avoid duplication and you can customize the way the settings should override each other.
Sorry if this is very convoluted, I tried responding the original question in the process.

One way I've used xcconfig files is to set up different BundleId's for iPhone apps. That way you can have different apps with different features/servers enabled. Very helpful. It involves using a variable name for the BundleId.

Related

What is it called when an app set some configurations at build time?

A common pattern used to build applications/software (web, mobile, desktop) is to have multiple build configs like Dev, Stage and Production. Each one of these configs may overwrite multiple variables like the base url of a web service that is consumed by the application. These configs may be stored in multiple ways (.env file, a JSON config file, etc).
I was looking for a name for this pattern/practice and how to implement it on a VB.NET application. Most close thing I was able to found is using the app.config file to store app settings but this is missing the multiple environments part. I'm having some trouble looking for solutions since I don't know the proper term for this practice.
There's a Solution Configurations drop-down on the main toolbar. You would have already used it to select Debug or Release. You can open the Configuration Manager from there to create new build configurations.
You can then control what happens during the build process of a project for a particular configuration on the Build page of the project properties. You can also perform actions using build events, which you configure on the Build Events page of the project properties. Here's an example of a pre-build event commandline that I use to automatically select the appropriate config file for NLog:
IF EXIST "$(ProjectDir)nlog.$(ConfigurationName).config" XCOPY "$(ProjectDir)nlog.$(ConfigurationName).config" "$(ProjectDir)nlog.config" /Y

Modify IntelliJ custom properties in plugin tests

I develop plugin for IntelliJ. How can I modify custom properties for my plugin tests?
For example I want to set idea.max.content.load.filesize property to, say, 100MiB
These are system properties, so java.lang.System#setProperty
Depending on the properties you wish to modify, you may be able to use idea.properties, which contains the "default properties used to run IntelliJ IDEA" (per the link you provided). To modify the file, you go to Help > Edit Custom Properties... (see these steps).
For example, I used this approach to address a problem where my machine's security software was blocking plugins that used IntelliJ's default config directory (C:\Users<user>\AppData...).
This is the Windows OS default Application Data directory and is included in the paths scanned by the security software. By moving my idea.properties file to a different directory (c:/development/idea/caches/), not automatically scanned by the security software, my plugins were no longer blocked.
It's a different use case from what you're describing, but may be an approach worth looking into.

MsBuild: Forcing a rebuild when changing build configuration

I have a #if in a project that depends on which build configuration is selected (eg: Debug, QA, and other test environments). When a user changes the build configuration in VS2015/Xamarin Studio, I need the IDE to force a rebuild on this project when the user builds the solution. How do I do this? At the moment, rebuilding the solution will reuse the compiled dll's.
In other words, how do I set a project dirty after a user changes the build configuration to force a rebuild.
Make sure the Output path of the project is unique to the build configuration. Otherwise MsBuild will just compare the timestamp of the input files and the existing output files and will conclude that a rebuild is not required.
It is assumed that when two projects build a different configuration, that they also write to a different folder for this reason.
Normally the output location is set to .\bin\$(configuration) to ensure this is the default behavior.

In IntelliJ IDEA, how to copy non-source assets to output folder during build?

I have a project in IntelliJ IDEA, inside that a couple of modules and one of my modules has two build configurations. One of them needs to copy a <projectroot>/tools folder to its out/production/<BuildConfigurationName> folder. Can IDEA somehow automate this?
The accepted answer above is incorrect. IDEA can do this (without ant/gradle) via the artifacts system (accessed via Build menu or project settings). Any one artifact job copies multiple files/folders/build outputs to a chosen location (optionally jarred) and can be set to automatically run on make.
Artifacts can even be chained, i.e. output from one as input to another.
Can IDEA somehow automate this?
Not directly, no. Ultimately IDEA is an IDE and not a build tool. While it can do a lot during a build, it does not have the ability to copy non-source files to an alternate directory, let alone a dynamically named directory.
If you marked the tools directory as a source directory (and none of its contained file types were set in the "Ignore files and folder" setting at the bottom of the "File Types" settings dialog), IDEA would then copy the tools directory to the out directory. But renaming requires a more sophisticated build tool.
Ultimately, the "ideal" or "best practices" solution would be to build your project using a build tool like Maven, Gradle or Ant for which this type of thing would be a snap.
If that is not an option, or for some reason you really want IDEA to do the build, the best thing you could do is to write a simple Ant script to the copy for you. (Or possibly Gradle, I do not have much experience with Gradle yet. Maven could do it, but it'd be a bit cumbersome compared to Ant.) In any Run/Debug configurations, you can define the ant script target to run before or after the IDEA "make" in the Before Launch section. (You can set that as a default for any newly created configurations by configuring it in Defaults on the left). If you run your build manually, you can assign a shortcut to the ant build and then run it and the make in sequence. Alternatively, you could record a Macro (Edit > Macros) to run both in sequence and then (optionally) assign the macro a keyboard shortcut.

Maven best practice for generating artifacts for multiple environments [prod, test, dev] with CI/Hudson support?

I have a project that need to be deployed into multiple environments (prod, test, dev). The main differences mainly consist in configuration properties/files.
My idea was to use profiles and overlays to copy/configure the specialized output. But I'm stuck into if I have to generate multiple artifacts with specialized classifiers (ex: "my-app-1.0-prod.zip/jar", "my-app-1.0-dev.zip/jar") or should I create multiple projects, one project for every environment ?!
Should I use maven-assembly-plugin to generate multiple artifacts for every environment ?
Anyway, I'll need to generate all them at once so it seams that the profiles does not fit ... still puzzled :(
Any hints/examples/links will be more than welcomed.
As a side issue, I'm also wondering how to achieve this in a CI Hudson/Bamboo to generate and deploy these generated artifacts for all the environments, to their proper servers (ex: using SCP Hudson plugin) ?
I prefer to package configuration files separately from the application. This allows you to run the EXACT same application and supply the configuration at run time. It also allows you to generate configuration files after the fact for an environment you didn't know you would need at build time. e.g. CERT
I use the "assembly" tool to zip up each domain's config files into named files.
I would use the version element (like 1.0-SNAPSHOT, 1.0-UAT, 1.0-PROD) and thus tags/branches at the VCS level in combination with profiles (for environments specific things like machines names, user name passwords, etc), to build the various artifacts.
We implemented a m2 plugin to build the final .properties using the following approach:
The common, environment-unaware settings are read from common.properties.
The specific, environment-aware settings are read from dev.properties, test.properties or production.properties, thus overriding default values if necessary.
The final .properties files is written to disk with the Properties instance after reading the files in given order.
Such .properties file is what gets bundled depending on the target environment.
We use profiles to achieve that, but we only have the default profile - which we call "development" profile, and has configuration files on it, and we have a "release" profile, where we don't include the configuration files (so they can be properly configured when the application is installed).
I would use profiles to do it, and I would append the profile in the artifact name if you need to deploy it. I think it is somewhat similar to what Pascal had suggested, only that you will be using profiles and not versions.
PS: Another reason why we have dev/ release profiles only, is that whenever we send something for UAT or PROD, it has been released, so if there is a bug we can track down what the state of the code was when the application was released - it is easier to tag it in SVN than trying to find its state from the commit history.
I had this exact scenario last summer.
I ended up using profiles for each higher environment with classifiers. Default profile was "do no harm" development build. I had a DEV, INT, UAT, QA, and PROD profile.
I ended up defining multiple jobs within Hudson to generate the region specific artifacts.
The one thing I would have done differently was to architect the projects a bit differently so that the region specific build was outside of the modularized main project. That was it would simply pull in the lastest artifacts for each specific build rather than rebuild the entire project for each region.
In fact, when I setup the jobs, the QA and PROD jobs were always setup to build off of a tag. Clearly this is something that you would tailor to your specific workplace rules on deployment.
Try using https://github.com/khmarbaise/multienv-maven-plugin to create one main WAR and one configuration JAR for each environment.