How to make Gradle choose a different version of C compiler?

I am a Gradle newbie and just starting to explore the different features that is provided for building C sources. My project requires the use of a sparc-rtems-gcc compiler variant. Using the toolChains container, I tried to use the path option to set a path for Gradle to pick up the Gcc compiler but I get the result as tool chain unavailable. Here is an excerpt of my build.gradle.

model {

toolChains {
	gcc(Gcc) {
		path "/opt/rtems/version_number/bin/"
	}
}

It is within this that my compiler invocation resides with the name sparc-rtems-gcc. How do I make Gradle compile my sources using this command?
Also note that by default Gradle chooses the gcc compiler which is present in my $PATH variable without issues.

I haven’t looked at changing the path for GCC, but looking at this sample you might need to provide the full path to the binary, instead of the folder.

    gcc(Gcc) {
        // Uncomment to use a GCC install that is not in the PATH
        // path "/usr/bin/gcc"
    }

I have given the path as opt/rtems/version_number/bin/sparc-rtems-gcc and still I get the error as

Could not find C compiler ‘gcc’.

Hi Ganesh,

Thanks for raising this documentation limitation. The feature exists but seems to not be documented through the DSL docs.

To choose a different version of the C compiler you need to configure the GccPlatformToolChain through the toolChains configuration. You can use eachPlatform if you want to do the modification for every platform or target if you want to do the modification only for a single platform.

When configuring your gcc toolchain, you use the Gcc type. This type has a common base class with Clang which is GccCompatibleToolChain. The method of interest is the search path, the target configuration and the configuration for all platforms. Below is an example using the search path and eachPlatform that should give you the intended result:

apply plugin: 'c'

model {
  toolChains {
    gcc(Gcc) {
      path "/opt/rtems/version_number/bin"
      eachPlatform {
        cCompiler.executable = "sparc-rtems-gcc"
      }
    }
  }
  components {
    main(NativeLibrarySpec)
  }
}

This is probably more tricky than it should be. Feel free to raise an issues with proposed improvement on the Github issue page. I opened an issue for you regarding the missing documentation.

Don’t hesitate to ask more question,

Daniel

Hi Daniel,

Thanks. I have made the changes. I have a couple more questions with respect to this.

  1. For configuring the linker, do I just have to add the line linker.executable = "sparc-rtems-ld" within eachPlatform?
  2. I don’t see an options.txt file within build directory, maybe because my gcc version is a 3.x version. But I see from the logs that an -m64 option is given to the compiler invocation by default. How did it come here and how can I remove it? My compilation fails on the unknown -m64 flag.

Hi Ganesh,

  1. You are correct. This is how it should work. Tell me if it doesn’t work.

  2. Gradle as a partial model of the platform and will try to detect 64-bit. In the event of such a detection, Gradle will add default parameters as this code shows. In your case, you are targetting sparc architecture. Try something like the following when defining your platform for sparc:

    apply plugin: 'c’
    model {
    platforms {
    mySparc {
    architecture ‘sparc’
    }
    }
    }

This modling is a bit limited for now so I encourage you to open some issues on Github in order to clearly capture any improvement we should consider.

Thanks,

Daniel

Hi,

I am not clear on the second point yet. When I make a definition like the sample you have provided, I just get the error as

No tool chain is available to build for platform ‘mySparc’:
- Tool chain ‘gcc’ (GNU GCC): Don’t know how to build for platform ‘mySparc’.

Is there some sort of methodology to specifically define how the compiler or linker will be invoked? I have a problem when it tries to link the generated objects. It by default adds an option -m32 to the sparc-rtems-ld command but my linker does not support that emulation and hence the command fails. How do I overcome this?

Hi Ganesh,

You are right, there was some information missing. Here is the complete code for this:

apply plugin: 'c'

model {
  platforms {
    mySparc {
      architecture "sparc"
    }
  }
  toolChains {
    gcc(Gcc) {
      path "/opt/rtems/version_number/bin"
      target("mySparc") {
        cCompiler.executable = "sparc-rtems-gcc"
      }
    }
  }
  components {
    main(NativeLibrarySpec) {
      targetPlatform "mySparc"
    }
  }
}

Notice the targetPlatform for the component which is noted here in the user guide. Also, notice the change from eachPlatform to target for the GCC toolchain. The eachPlatform configuration will configure only the supported platform as specified here. Instead, we specify a new supported platform for the toolchain as well as configuring that new one. You can find more information about this here in the user guide.

Thanks,

Daniel

1 Like