Partially was discussed in #1032, but still require ugly workarounds.
Situation: I want to interop with C library, available in precompiled release tarball, and link it statically.
So I downloaded and unpacked it to "build" directory, and add to .def file relative paths:
...
headers = ui.h
noStringConversion = uiFreeInitError
compilerOpts = -I./build
staticLibraries = libui.a
libraryPaths = build
...
But this path is relative to current OS directory, not to .def or .gradle file!
So it works if I compile it as cd libui && ../gradlew build,
but if called as ./gradlew :libui:build - it falis.
OK, I can add support for this case:
...
headers = ui.h
noStringConversion = uiFreeInitError
compilerOpts = -I./build -I./libui/build
staticLibraries = libui.a
libraryPaths = build libui/build
...
and i works in both cases.
But I still can call it from something else, and it fail: cd samples && ../gradlew :libui:build.
As workaroind I can add to .gradle
...
compilations.main {
cinterops {
libui {
includeDirs "${project.rootDir}/libui/build"
}
}
}
...
but not for libraryPaths - there are no such option in DSL.
And in general I think this workaround is ugly - relative paths in .def should work in a predictable way.
Is this going to be fixed anytime soon? My build is rather fragile because I've hard-coded the path.
We believe that proper approach is to compute appropriate full paths in build scripts.
Maybe, but then libraryPaths or something similar should be added to cinterop tool and gradle plugin.
Or cinerop should handle linkerOpts=-L... for static libs.
Well, looks like cinterop supports it, but how to call it from build.gradle.kts ?
}
compilations["main"].cinterops.create("libui") {
includeDirs(buildDir)
+ freeCompilerArgs = mutableListOf("-staticLibrary=$buildDir/libui.a")
}
}
Script compilation error:
Line 54: freeCompilerArgs = mutableListOf("-staticLibrary=$buildDir/libui.a")
^ Unresolved reference: freeCompilerArgs
1 error
Ok,
compilations["main"].cinterops.create("libui") {
includeDirs(buildDir)
}
+ compilations["main"].kotlinOptions.freeCompilerArgs = mutableListOf(
+ "-include-binary", "$buildDir/libui.a"
+ )
}
if (os.isLinux || publishModeEnabled) linuxX64("linux") {
Compiles, but in this case libui.a is included in libui.klib.
Before it was included in libui-cinterop-libui.klib.
Does it matter?
I have the problem when using Gradle composite builds. When I build from the project everything is fine with a relative libraryPathbut it fails when the project is composed by another.
staticLibraries = libiup.a
libraryPaths.linux = iup/lib/iup-3.28/linux64
libraryPaths.mingw = iup/lib/iup-3.28/windows64
libraryPaths.osx = iup/lib/iup-3.28/darwin64
Having a reliable reference path for relative one would be nice.
Another solution:
mainCompilation.cinterops.create("libcrypto") {
+ extraOpts("-libraryPath", "$projectDir/nativeLib/build/$targetName/lib")
}
This has the advantage of having the static library be included in the cinterop klib.
Most helpful comment
Ok,
Compiles, but in this case
libui.ais included inlibui.klib.Before it was included in
libui-cinterop-libui.klib.Does it matter?