Here’s my situation…
-
We’re using define symbols to support multiple android platforms (i.e. GOOGLE_PLAY, KINDLE, etc.)
-
We have multiple projects in Cloud Build (i.e. MyAppGooglePlay and MyAppKindle)
-
The platform define symbols are set in the Advanced Settings for each Cloud Build project
-
Our developers need the define symbols to be in the android player settings locally, so they can make sure everything compiles for the platform they’re working on
-
If a developer has GOOGLE_PLAY in the their player settings and commits it by accident, then later someone builds the Kindle project in Cloud Build, both GOOGLE_PLAY and KINDLE define symbols will exist
Its difficult to make absolutely sure nobody commits the define symbols by mistake, so it would be great if there were either an option in the Advanced Settings to remove define symbols, or the ability to do it programatically via editor scripting in the Pre-Export callback (I tried this, it doesn’t work).
Unless I missed something, there’s currently no way to remove a define symbol in Cloud Build.
Is there a way to do this? Is this something Unity could add?
1 Like
Thanks for the feedback, I have noted it. The only thing you could do is to add the defines into the .rps files. We override those during the build process. We apply the player defines and per platform defines. But I can not recommend this as you loose the overview on what is defined. Rather I would suggest to make a pre process script to remove them.
Thanks, David
I tried using a preprocess script to remove them, but it doesn’t work. Changing the define symbols triggers a recompile, but Cloud Build doesn’t seem to wait for the recompile to finish before continuing.
In my preprocess function, I have something like this (pseudo code):
RemoveDefine(“FOO”);
AddDefine(“BAR”);
#if FOO
DoFoo();
#elif BAR
DoBar();
#endif
When FOO is defined in the player settings in my project, DoFoo() runs and DoBar() does not (the opposite of what I want).
I tried adding:
while (EditorApplication.isCompiling) {
// wait
}
But that just hangs the editor (as I would expect), locally and in cloud build.
I understand that this is a difficult problem – I don’t know how you’d wait for the recompile. That’s why I was suggesting some way of overriding the project define symbols (instead of just appending to them) in cloud build’s advanced build settings. That way, the correct define symbols would be set before the preprocess function runs, and the recompile issue would be avoided.
How do you remove the defines? I would suggest those but I don’t know if you can remove defines though. But any code that runs is always running in the editor so it’s probably not the best way to do it. You might go with a solution without preprocessors where you just rely on custom UCB defines - so locally you would use something like GOOGLE_PLAY but on UCB you would use UCB_GOOGLE_PLAY or something similar. I know it’s a little bit of code duplication that way, but works around your issues between local / cloud. Or you adjust your ignore file so it does not commit the player settings at all for the team members.
Yeah, I was using GetScriptingDefineSymbolsForGroup
to get the define symbols string, using some regex to remove stuff and then writing it back to the player settings with SetScriptingDefineSymbolsForGroup
.
We thought about having separate defines for local builds and cloud builds, but it makes the conditionals a big mess. To weed out what’s in the player settings, you have to do something like:
#if UCB_FOO || (!UNITY_CLOUD_BUILD && FOO)
// …
#endif
vs:
#if FOO
// …
#endif
Yuck.
We can’t add ProjectSettings.asset to the .gitignore file, because it has other stuff in there that definitely needs to be in source control (all the iOS/Android settings, etc.). The compiler defines are just a few lines in a file that has lots of other necessary stuff.
Right now, the least bad solution we have found is to implement a git pre-commit hook, that looks for the defines in PlayerSettings.asset and aborts the commit if it finds them (which prevents anyone from committing them accidentally). Git hooks are a whole other topic, but the main problem is that they need to be setup per-clone of the repo. Each time you clone the repo, on each developer’s computer you have to setup the hooks again.
It would be much easier (and more reliable), if there were a checkbox in the advanced build settings that told cloud build to clear the define symbols from the project settings before injecting it’s own.
I would not completely ignore the ProjectSettings.asset for every user. Just add the file manually once it get’s updated with the necessary data. You could still go with the .rps files if you don’t like to change your code.
Could you add an option to build configurations to clear define symbols defined in project settings?
4 Likes
I would also like this feature. Maybe the easiest is to not have an option to add defines but to just completely override the entire symbol defines string with your own string.
We again ran into an issue with this and spent hours doing a workaround. So our case:
- We are using PreprocessBuild to clear all code defines from PlayerSettings
- We wanted to use another PreprocessBuild to exclude some non managed plugins based on code defines in release, this was simply working in Unity Editor. The problem in the Cloud is the if we clear PlayerSettings from all code defines in PreExport method or PreprocessBuild callback they won’t be applied for other PreprocessBuilds, only before the game is built.
This means we have to write our code defines in a way that we disable things out rather than enabling them. This seems to work in PreprocessBuild since my guess is that Unity Cloud doesn’t inject the config code defines into PlayerSettings but rather directly to the pre- and build process. More documentation on the whole process would be very helpful.
So please add a checkbox for build configs to clear PlayerSettings code defines before any code is ran and make a proper documentation on what is done and when. We are strongly considering in investing in our own CI server as working with Unity Cloud really takes our resources.
I’m also wrestling with this issue. The Steamworks.NET plugin requires DISABLESTEAMWORKS to be disabled, which we use in the repository because it makes development easier. In a Steam build, I have to remove this symbol and replace it with others. Doing this in the pre-export method (using PlayerSettings) doesn’t work, because based on the log the code already appears to go through compilation before the method, and fails before the pre-export even gets a chance to do anything.
What I’m missing is a place to definitively set the custom symbols before anything else happens.
2 Likes
@David-Berger We’re seeing the same problem with our Demo / Full game set up. If someone in the team adds the DEMO #define and accidentally commits ProjectSettings.asset, it messes up the build system and messes up everyone’s work. We need some form of “local” defines which are stored outside of ProjectSettings.asset (that way we could add that local file to .gitignore).
Not sure if this is completely relevant but @ollieblanks from Unity posted a script to remove all defines from the project settings (so the cloud build defines from the config are the only ones used). How is Production vs Development best set up using Cloud Build? - Unity Services - Unity Discussions