4

I am trying to find a way to write a conditional inside a .bp file.

I found a documentation here: https://android.googlesource.com/platform/build/soong/+/HEAD/README.md

It has a "How do I write conditionals?" part, which points to the art.go: https://android.googlesource.com/platform/art/+/master/build/art.go

Which is hardly an answer to the aforementioned question. It needs a lot more clarification than a simple link.

I have cc_binary in my Android.bp for the module (HAL) I develop.

cc_binary {
  name: "name",
  init_rc: ["script.rc"],
  vintf_fragments: ["fragments.xml"],
  relative_install_path: "path",
  srcs: ["src1.cpp", "src2.cpp", ...],
  shared_libs: ["sh_lib1", "sh_lib2", ...],
  tstic_libs: ["lib1", "lib2", ...],
}

I want to add a conditional cflag (-DCONDITIONAL), which will be set to 1 if environmental variable SOME_ENV_VAR is equal to "some_value".

I found a lot of examples of similar *.go files inside AOSP, but they turned out to be of no use for me, because I cannot simply apply practices described there to my case. I also failed to find any documentation about *.go files, which describes how to do stuff using them. I cannot even find something like "simplest example of usage".

Does anyone know is it even possible what I am trying to do here?

a_girl
  • 959
  • 7
  • 22

1 Answers1

6

In your project folder, create a "my_defaults.go" file, where you can define the logic that adds custom build flags based on environment variables or other conditions (which is basically what happens in the art.go that was given as an example).

package my_defaults

import (
    "android/soong/android"
    "android/soong/cc"
)

func globalFlags(ctx android.BaseContext) []string {
    var cflags []string

    if ctx.AConfig().Getenv("SOME_ENV_VAR") == "some_value" {
        cflags = append(cflags, "-DCONDITIONAL")
    }

    return cflags
}

func deviceFlags(ctx android.BaseContext) []string {
    var cflags []string

    return cflags
}

func hostFlags(ctx android.BaseContext) []string {
    var cflags []string

    return cflags
}

func myDefaults(ctx android.LoadHookContext) {
    type props struct {
        Target struct {
            Android struct {
                Cflags []string
                Enabled *bool
            }
            Host struct {
                Enabled *bool
            }
            Linux struct {
                Cflags []string
            }
            Darwin struct {
                Cflags []string
            }
        }
        Cflags []string
    }

    p := &props{}
    p.Cflags = globalFlags(ctx)
    p.Target.Android.Cflags = deviceFlags(ctx)
    h := hostFlags(ctx)
    p.Target.Linux.Cflags = h
    p.Target.Darwin.Cflags = h

    ctx.AppendProperties(p)
}

func init() {
    android.RegisterModuleType("my_defaults", myDefaultsFactory)
}

func myDefaultsFactory() android.Module {
    module := cc.DefaultsFactory()
    android.AddLoadHook(module, myDefaults)

    return module
}

In your Android.bp, declare the following module:

bootstrap_go_package {
    name: "soong-my_defaults",
    pkgPath: "android/soong/my/defaults",
    deps: [
        "soong",
        "soong-android",
        "soong-cc"
    ],
    srcs: [
        "my_defaults.go"
    ],
    pluginFor: ["soong_build"]
}

You can then use "my_defaults" instead of the usual "cc_defaults" in your Android.bp, e.g.

my_defaults {
  name: "my-defaults-instance"
  // Set some additional non-conditional cflags ...
}

cc_binary {
  name: "my_binary",
  defaults: ["my-defaults-instance"]
}
  • Hi.. In my case I need to include src files based on some global variables. How to add that conditional statement inside my_defaults node? Can you explain that – Venkatraman Oct 28 '20 at 10:40
  • Hi, I haven't tested this, but it should be possible to add a `Srcs []string` field to the `props` struct and then initialize it conditionally based on `Getenv` as in the example. The build system should then pick this up. I can try to go into more detail if you post a separate question, because posting multi-line code in comments is not supported. – f9c69e9781fa194211448473495534 Oct 28 '20 at 11:10
  • Would like to reframe the question for better understanding.. What we need to do inside my_defaults node just src[] itself is fine? will this src set will be included only when we have cflags set for that particular env variable? – Venkatraman Oct 28 '20 at 12:15
  • My understanding is that you have an environment variable `SOME_ENV` and you want to compile some source file `some_file.c` only when `SOME_ENV` is set. I don't know if you also want to set cflags based on the environment variable. In the go file, you would adapt the `type props struct` to have a `Srcs []string` field. If you do not need to adapt the cflags, you can remove those from the struct. Below the declaration of the struct, you would initialize the `Srcs` field based on `SOME_ENV`. So if `SOME_ENV` is set, set the `Srcs` field to e.g. `some_file.c`, else to some other value. – f9c69e9781fa194211448473495534 Oct 28 '20 at 13:23
  • In the bp file, you can then use the `my_defaults`. Note the soong build system will merge all properties together. So if the `Srcs` field in the go file is set to `some_file1.c` and in the bp file, you declare a binary that uses `my_defaults` and also declares its own `srcs: ["some_file2.c"]`, then this will not overwrite `my_defaults`, but both will be joined together. – f9c69e9781fa194211448473495534 Oct 28 '20 at 13:39
  • I tried something similar to this but it is not working. I would appreciate if someone can answer there https://stackoverflow.com/q/73667217/5038317 Thanks – Heitor Paceli Sep 29 '22 at 00:03