Right now I have 2 build targets: GooglePlay and Amazon. In the Java code, the code has some checks to see what it should do based on the build type. The problem is that each time you want to build for Amazon, you have to manually edit the source Java code to change the build type to Amazon. What would be the best way to generate a .java file during build time, before Java code is compiled? I guess I’m looking for something like Android, which generates R file, which you can access from code.
I don’t know about any layout requirements of a deliverable to be deployed on GooglePlay or Amazon.
However, I have made good experiences using Maven. You can use its property replacement mechanism (aka. “Filters”) to replace any kind of properties specified via Dollar-Curly-Brackets patterns in any of your source artifacts, either Java source files or property files or younameit. See this stackoverflow answer for a way to filter Java source files.
You can specify the concrete value to be replaced either within your build file using profiles, or as a command line argument when invoking the build, or inside a Java Properties file, which will be consulted during the build.
Maven will then generate or better “replace” the placeholders inside your source artifacts with the concrete value and use that as the javac input. Of course, it does not replace the files in-place, so it is not going to overwrite your original source file.
I avoid preprocessors wherever possible, as it interferes with other tools that expect well formed Java source.
You can achieve the same effect with:
- platform specific implementations of classes that are substituted in as part of the build process
- platform specific constants that alter behaviour of shared classes(the constants themselves being contained within the aforementioned platform specific classes)
You can even have a form of inheritance with your constants via hiding.
Ideally though, you should write your code in such a way as it’ll work on both platforms without need to rebuild it.
Completely agree. Maybe there is a way to dynamically detect the platform at runtime and then use polymorphism/inheritance (as you said) to wire the application’s module together for that particular path/platform?
That could be done concretely by providing a system property when the application is run on a particular platform, or maybe the JRE on the platform itself provides means (class availability or system property) to detect it?
I agree that this sounds like a job for maven.
Alternatively, you might just split up your builds into multiple projects: have a “core” project that contains all of the shared code, then have a “Google Play” project and an “Amazon” project that contains the code specific to those platforms. The Google Play and Amazon projects would each depend on the core project- that way, you only have to make changes to the core project to have it reflected on both platforms. Then when it comes time to build, just build both projects.
This is how libGDX sets up their builds for desktop, android, and web platforms.