Gradle native libraries per toolchain

260 views Asked by At

I am working on a native code project which uses Gradle. The project builds well on Linux using gcc, including using prebuilt libraries, specifically openssl. Now I need to get it building on MacOS, using clang.

At the beginning of my model I have:

model { 
    repositories {
        libs(PrebuiltLibraries) {                     
            openssl {
                headers.srcDir "/usr/local/include/openssl"      
                headers.include "**/*.h"          
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("/usr/local/lib/libssl.a") 
                }
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("/usr/local/lib/libcrypto.a")
                }
                binaries.withType(SharedLibraryBinary) {
                    sharedLibraryFile = file("/usr/local/lib/libssl.so")
                }
                binaries.withType(SharedLibraryBinary) {
                    sharedLibraryFile = file("/usr/local/lib/libcrypto.so")
                }
            }
        }
    }
}
components {
    ...
}

Basically, I just need to change the file paths when compiling for Mac. I'm used to looking at the toolChain property when generating binaries from my components, so I tried adding if (toolChain in <Gcc | Clang>) { ... } blocks around the libs() declarations, but I get an error:

Cannot create a ArtifactRepository named 'toolChain'

I also tried creating a separate openssl-mac repository object, and then using the same if (toolChain ...) {} logic in the component declaration, like this :

components {                
        myLib(NativeLibrarySpec) {
            sources {
                cpp { 
                    source {
                        srcDir "mylib/src"
                        include "*.cpp"
                    }
                    exportedHeaders {
                        srcDir "mylib/src"
                        include "*.h"
                    }
                    if (toolChain in Gcc) { lib library: 'openssl', linkage: 'static' }
                    if (toolChain in Clang) { lib library: 'openssl-mac', linkage: 'static' }
                }
            }
        }
    }
}

But I get a similar error:

No such property: toolChain for class: org.gradle.language.cpp.CppSourceSet

Obviously I'm going about this wrong. What is the right way to supply different pre-built libraries depending on the target toolchain/platform/os/etc?

1

There are 1 answers

0
superstator On

The answer, it seems, is to use org.gradle.internal.os.OperatingSystem like so:

import org.gradle.internal.os.OperatingSystem;

model { 
    repositories {
        if (OperatingSystem.current().isLinux()) {
            libs(PrebuiltLibraries) {                     
                openssl {
                    ...
                }
            }
        }
        if (OperatingSystem.current().isMacOsX()) {
            libs(PrebuiltLibraries) {                     
                openssl {
                    ...
                }
            }
        }
    }
    ...
}