gradle / gradle-native

The home of Gradle's support for natively compiled languages
https://blog.gradle.org/introducing-the-new-cpp-plugins
Apache License 2.0
93 stars 8 forks source link

Demonstrate a mixed C and C++ library #870

Open big-guy opened 6 years ago

big-guy commented 6 years ago

We have a sample for building C and several samples where we build C++.

If someone had a single library that used both, how would we do it in the current plugins?

zosrothko commented 6 years ago

@big-guy That's the case for the Poco library. At least 2 modules (XMLand PDF) are made of both C and C++ code source in the same src directory. There are as well in the same directory many include files.

ThadHouse commented 6 years ago

This would include mixed mode for all the supported languages, right? I have a C++ and Objective C++ mixed mode library in one of my projects that would need this as well.

lacasseio commented 6 years ago

Yes, whatever solution comes out of this will most likely be the solution for any other mixed language.

janjoerke commented 5 years ago

Are there any plans to support this in the foreseeable future? I am currently evaluating the use of native gradle for a bigger project and this is a real drawback.

lacasseio commented 5 years ago

We hope to take action on this soon. That doesn't mean it's not possible at the moment. It's all possible but requires more configuration than expected. There is two use case when it comes to mixing C and C++: 1) C and C++ projects are separated (C code compiled & linked with only C code and C++ code compiled & linked with only C++ code) and 2) C and C++ code is compiled and linked together. Which use case are you facing the most?

janjoerke commented 5 years ago

I found the workarounds for 1) and they work as described. I am looking for a way to compile and link C and C++ code together (2).

I have also not found a solution to how I could pass different compiler args depending on the sources, as I could find no concept of different sourceset as it was the case with the old model.

To be fair most of the time we are facing 1) with some old code also requiring 2) .

lacasseio commented 5 years ago

For compiling and linking C and C++ code together, you will need to create CCompile tasks manually. You can use something like the following:

application.binaries.configureEach { binary ->
    def cCompileTask = tasks.register("compile" + binary.name.capitalize() + "C", CCompile) {
        // Take configuration from C++ compile tasks
        toolChain = binary.compileTask.map { it.toolChain }
        targetPlatform = binary.compileTask.map { it.targetPlatform }
        includes.from binary.compileTask.map { it.includes }
        systemIncludes.from binary.compileTask.map { it.systemIncludes }

        // Configure the C source file location
        sources.from project.fileTree("src/main/c")

        // Must use another directory for proper up-to-date check
        objectFileDir = project.layout.buildDirectory.dir("objs/mainC")

        // Unfortunately, this doesn't use the Provider API yet. The impact is minimized by using the lazy task API
        macros = binary.compileTask.get().macros
        optimized = binary.compileTask.get().optimized
        debuggable = binary.compileTask.get().debuggable
        positionIndependentCode = binary.compileTask.get().positionIndependentCode
    }

    linkTask.get().with {
        source.from project.fileTree(cCompileTask.map { objectFileDir }
    }
}

As for different compiler args depending on the sources, could you expand on your use case? Most of the time we heard this use case was to change the optimization and debugging of some files during development. For that specific use case, we would provide a better solution than simply allowing users to configure whatever flag for each file. If you have another use case, we would be pleased to add it to our list.

janjoerke commented 5 years ago

Thanks a lot for the example. I will try that soon.

The use case I needed is simple, as all I wanted was to instruct the clang C++ compiler to treat C files as C code with '-x c'.

lacasseio commented 5 years ago

Then using CCompile vs CppCompile task type will take care of that flag handling.