How do I get the "cpp" plugin to use gcc(1) instead of g++(1) for a C project?


(Steven Emmerson) #1

With the “cpp” plugin, gradle tries to use g++ to build my C project. It fails because C isn’t C++. I’ve tried using the “-x c” and “-std=gnu90” options of g++ to no avail.

How do I override the “cpp” plugin’s use of g++ and have it use gcc instead?


(michael.nikonov) #2

I’m just getting acquainted with Gradle, so I hope that, if I’ll make a mistake, more knowledgeable people will correct me. But I think it might be a configuration issue; in the project structure Gradle expects by default, C and C++ sources are contained at different paths, those being ‘src/${component name}/c’ and ‘src/${component name}/cpp’. I’ve just checked to be sure — it appears that files in ‘/c’ are compiled with gcc and not with g++.

If you have your own directory structure, I’d imagine you’ll want to separately specify directories where your C and C++ sources reside, like this:

apply plugin: 'cpp'
  sources {
  sample {
    cpp {
      // Paths for C++ sources.
    }
    c {
      // Paths for C sources.
    }
  }
}
  executables {
  sample {
    source sources.sample
  }
}

(Steven Emmerson) #3

Mikhail, I’m afraid your ‘sources.sample.c’ suggestion doesn’t work. My ‘build.gradle’ file

apply plugin: ‘cpp’

sources {

lib {

c {

include “lib/*.c”

}

}

}

libraries {

udunits2 {

source sources.lib

}

}

results in the following error:

~/udunits2/src: gradle udunits2SharedLibrary

FAILURE: Build failed with an exception.

  • Where:

Build file ‘/home/steve/udunits2/src/build.gradle’ line: 4

  • What went wrong:

A problem occurred evaluating root project ‘src’.

Cannot create a LanguageSourceSet named ‘c’ because this container does not support creating elements by name alone. Please specify which subtype of LanguageSourceSet to create. Known subtypes are: (None)

  • Try:

Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 1.066 secs


(Steven Emmerson) #4

@Mikhail I’m afraid your suggestion doesn’t work for the reason in my subsequent posting.


(michael.nikonov) #5

Could you tell what version of Gradle are you using? It appears that C/C++ support undergoes a major rewrite, so I’m preferring to be on the bleeding edge and using 1.9 nightly builds now. I’ve tried to create the following directory structure to resemble what you’re using:

lib
lib/source1.h
lib/source2.cc
lib/source1.c
lib/source2.h
build.gradle

And changed your ‘build.gradle’ file in the following way:

apply plugin: 'cpp'
sources {
  lib {
    c {
      source {
        srcDirs "lib"
        include "*.c"
      }
    }
  }
}
libraries {
  udunits2 {
    source sources.lib
  }
}

Note that element ‘c’ contains element ‘source’ nested in it; it can also contain ‘exportedHeaders’ at the same level where you specify headers exported by the library. Also, ‘include’ specifies the mask of source files to include while ‘srcDirs’ points to set of source directories to look at. I think that if you won’t specify ‘srcDirs’ here and leave mask as “lib/.c", then Gradle will look for files matching "lib/.c” in default source directory for component, that being “src/lib/c”; in other words, your source would have to be placed at src/lib/c/lib — probably not what you wanted.

So, with directory structure and ‘build.gradle’ as above, ‘gradle udunits2StaticLibrary --info’ yields following when compilation is run:

Executing task ':compileUdunits2StaticLibraryLibC' (up-to-date check took 0.024 secs) due to:
  Output file /home/ulenspiegel/24/build/objectFiles/udunits2StaticLibrary/libC has changed.
  Output file /home/ulenspiegel/24/build/objectFiles/udunits2StaticLibrary/libC/source1.o has been removed.
Starting process 'command '/usr/bin/gcc''. Working directory: /home/ulenspiegel/24/build/objectFiles/udunits2StaticLibrary/libC Command: /usr/bin/gcc -x c -c @/home/ulenspiegel/24/build/tmp/compileUdunits2StaticLibraryLibC/compiler-options.txt

In my case it appears that gcc is started to compile ‘source1.c’. At that, ‘source2.cc’ is not included in library at all because of include mask.


(Steven Emmerson) #6

It’s possible that I need to upgrade my gradle installation to the bleeding-edge because it doesn’t understand the ‘sources.lib.c’ member. The following ‘build.gradle’

apply plugin: ‘cpp’

sources {

lib {

c {

source {

srcDirs = “lib”

include “*.c”

}

}

}

}

libraries {

udunits2 {

source sources.lib

}

}

results in

~/udunits2/src: gradle udunits2SharedLibrary

FAILURE: Build failed with an exception.

  • Where:

Build file ‘/home/steve/udunits2/src/build.gradle’ line: 4

  • What went wrong:

A problem occurred evaluating root project ‘src’.

Cannot create a LanguageSourceSet named ‘c’ because this container does not support creating elements by name alone. Please specify which subtype of LanguageSourceSet to create. Known

subtypes are: (None)

  • Try:

Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log

output.

BUILD FAILED

Total time: 1.782 secs

~/udunits2/src: gradle --version


Gradle 1.7


Build time:

2013-08-06 11:19:56 UTC

Build number: none

Revision:

9a7199efaf72c620b33f9767874f0ebced135d83

Groovy:

1.8.6

Ant:

Apache Ant™ version 1.8.4 compiled on May 22 2012

Ivy:

2.2.0

JVM:

1.7.0_07 (Oracle Corporation 23.3-b01)

OS:

Linux 2.6.35.14-106.fc14.x86_64 amd64

What do you think?


(Steven Emmerson) #7

@Mikhail I’m using Gradle version 1.7. This might need upgrading. See my followup posting.


(michael.nikonov) #8

Steven, I think it’s indeed the case — you’re using Gradle 1.7 and, if I remember right, it was said in 1.8 release notes that syntax of specifying C/C++ source sets has been changed. So you’ll need either 1.8 or 1.9 for above script to work; you can get nightly here: http://www.gradle.org/nightly. Try and see if it works for you. I know using nightly builds isn’t the same as working with stable release, but C/C++ support seems to be evolving quite rapidly now and many things tend to change.


(Steven Emmerson) #9

Mikhail, your suggestion worked. Now I have to work on supporting flex(1) and bison(1). :frowning:


(michael.nikonov) #10

It might take writing a custom task, but I’m afraid I’m not yet versed enough with Gradle (and Groovy, in fact) to give any advice. I think it’s possible to run custom commands at will, since it’s all basically Groovy; if you’ve downloaded full Gradle distribution, you could try looking at example under samples/cpp/cpp-exe/build.gradle, where custom task is made for stripping binary after compilation. But maybe it’ll worth raising separate question on forum to ask how to do that in idiomatic way.