Android Tutorial Conditional Compilation & Build Configurations

B4A v3.80 adds support for conditional compilation.

From Wikipedia:
In computer programming, conditional compilation is compilation implementing methods which allow the compiler to produce differences in the executable produced controlled by parameters that are provided during compilation.

Conditional compilation allows you to exclude parts of the code based on the selected build configuration. You can use it to create several applications from the same project. For example you can create one application with ads and another application without ads.

Build Configurations

The build configurations dialog is available under Project -> Build Configurations (Ctrl + B).

SS-2014-05-08_09.58.38.png


This dialog allows you to edit or add new configurations and to choose the current active configuration.
A build configuration is made of a package name and a set of conditional symbols.
The package name replaces the previously global package field. This means that you can produce APKs with different package names from the same project. Note that multiple configurations can share the same package name.

The conditional symbols define the active compiler symbols. This allows you to exclude parts of the code based on the chosen build configuration.
You can set multiple symbols separated with commas.

There are several built-in symbols:
- B4A: B4A, DEBUG and RELEASE. Either DEBUG or RELEASE will be active based on the deployment mode.
- B4J: B4J, DEBUG, RELEASE, UI or NON_UI (based on the app type)
- B4i: B4I, DEBUG, RELEASE

Code Exclusion

With the conditional compilation feature you can exclude any code you like from the code editor, manifest editor and designer script (any text can be excluded, including complete subs and attributes).
Excluded code will not be parsed and will be effectively removed before it reaches the compiler.
Note that the manifest editor and designer script will not visualize the excluded code. However it still works properly.

The code exclusion syntax:

SS-2014-05-08_10.19.51.png


B4X:
#If [symbol]
...
#End If

Each build configuration holds a set of symbols. Multiple configurations can share all or some of the symbols. This makes it possible to include or exclude code in several different configurations.

Starting from B4A v5, B4J v3 and B4i v2 more complex expressions are supported.
For example:
B4X:
#If FULL and Not(WITH_ADS)
'Do something
#Else If WITH_ADS OR (TRIAL And IN_APP)
'...
#Else
'...
#End If
 
Last edited:

stevel05

Expert
Licensed User
This is brilliant, it took me about an hour to create a pro and lite version of a fair sized app, it would have taken much longer to rip out the necessary code, and I'd have to maintain two separate versions. I could have done it before with flags and if-then's, but this adds a level of security in that the lite version won't have any of the pro version code.

Beta testing is all well and good, but you can't really tell until you try it in a real situation.

Thanks Erel:) Another huge step forward.
 

John H. Guillory

Member
Licensed User
O.k. You've definitely got me wanting to upgrade! But I want to make sure I understand a few things here...
Someone quoted it saying you could specify multiple symbols separated by ','. I'm understanding this to mean in the compile dialog box, I can specify eg:

GOOGLE, TRIAL, BETA

Then, in my code, I could do something like:

#if GOOGLE
Activity.LoadLayout("Gmain")
#end if
#if AMAZON
Activity.LoadLayout("Amain")
#end if
#if BETA
MsgBox("Warning, the following is Beta Test Code. DO NOT DISTRIBUTE IT!","Warning")
#end if
#if TRIAL
MsgBox("Please Consider registering this software","Trial Version")
#end if


Or, are you saying I can use:
#if GOOGLE, TRIAL
Activity.LoadLayout("gmain")
#end if

I'm guessing the first one...
 

susu

Well-Known Member
Licensed User
In my Pro version I need to use library "ABC", in my Default version I do not use it. So is it right if I check library "ABC" in Libs tab and add these code?

B4X:
#If Pro
Dim abc As ABC
#End If
 

susu

Well-Known Member
Licensed User
The library will be referenced in all configurations. However the object (and permissions) will only be added to "pro" builds.

But all the libraries will be added to apk file? I made FREE version with 2 ad networks => file size 10MB. The PRO version without ad by using this code:
#If Free
Dim ad1 as AdNetwork1
Dim ad2 as AdNetwork2
#End If

The PRO version is still 10MB. After uncheck 2 ad network libraries on Libs tab => File size is only 8MB.
 

tonyp

Member
Licensed User
B4A v3.80 adds support for conditional compilation.

There is no support for #Else (it is related to the code editor lexer implementation). You can however achieve the same result by adding the same symbol to all other build configurations.

How about a negated condition? For example, for the opposite of #IF PAID to have #IF NOT PAID which should be true if PAID symbol is not defined. This would alleviate some of the problems of the missing #ELSE
 

Graeme Tacon

Member
Licensed User
I was trying to use the conditional symbols of DEBUG and NODEBUG for different versions of my app, but it doesn't work ! Lines within both tags are brought in, regardless of whether my build configuration has DEBUG or NODEBUG.
 

kiki78

Active Member
Licensed User
Thank you Erel for this great improvement.
May you add RELEASE_OBFUSCATED symbol in future release ?
I also like Filippo (#31) suggestion.

Thanks
 

nwhitfield

Active Member
Licensed User
I'd quite like a #define option, so that instead of adding lots of extra keywords to every build configuration, I could have something at the top of my Main module like

#if privateBuild
#define noads
#define fullversion
#end if

If there were an #undefine in there too, so you could throw in something like #undefine googleplay then that might go some way to solving some of the problems people have with the lack of an else; it wouldn't been too much hardship to restrict use of define and undefine to the module attributes section either
 

andrewj

Active Member
Licensed User
I'm not sure this is wotking 100% in the manifest editor. I have the following code:
B4X:
#If KITKAT
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19"/>
#End if
#If NORMAL
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="19"/>
#End If
However if I compile with the symbol NORMAL it is including the KITKAT line.

Any ideas?
Andrew
 

andrewj

Active Member
Licensed User
Cracked it!

The conditional compilation does not work inside a section of the manifest. It does work for complete sections, as follows:
B4X:
#If NORMAL
AddManifestText(
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="19"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:hardwareAccelerated="true"
    android:anyDensity="true"/>)
#End If

Andrew
 
Top