Kotlin Native cinterop def file: how to eliminate absolute path? - kotlin

When specify linkerOpts, we need set absolute path for -L option, but it's easy to break.
In older version, setting linkerOpts in build.gradle could work, but in 1.3.50, it warns that "-linker-option(s)/-linkerOpts/-lopt option is not supported by cinterop. Please add linker options to .def file or binary compilation instead.", and build do fail with "Undefined symbols" error.
What could I do?

This option is going to be deprecated once, so the warning was intentionally added after the 1.3.50 release. The motivation here is that one should prefer to set all linker options, even platform-specific, via .def file.
But, the build should not break apart in this case. Can you add the script contents, to make it clearer - what exactly led to the error?
UPD: After the GH project was shared in the comments I want to add some details here. This problem is described in the documentation here, this part:
Often it's necessary to specify target-specific linker options for a binary which uses a native library. It can be done using the linkerOpts property of the binary.
So, in this particular case, it will be correct to add the option to the binaries section instead of the cinterops. In the end, I made things together with
binaries {
all {
linkerOpts = ['-L'+rootProject.projectDir+'/libs/NativeBase64/iOS/', '-lNativeBase64']
}
}

Related

Is it possible to generate a Kotlin .def file from a CMake library?

I have an existing CMake project which is used to build a native library (supporting a few Linux platforms as well as Windows). This library will soon be integrated into a Kotlin app, for which I need to create a .def file, as stated here
Conceptually, I could create this using FILE and other native CMake tools, but if there's a "proper" way to do this, I'd prefer to use that!
Is that file something you have to write yourself? I can't tell just from reading the docs, but that's the impression I'm getting. If each .def corresponds to a CMake target, you could create a build event custom command by using the build events signature of add_custom_command to run the cinterop command.
If you want to script the process of writing the .def file so it's more automatically-robust to you renaming things in the future,
As for putting things like target compile options in a file, you could use the $<TARGET_GENEX_EVAL:> and $<TARGET_PROPERTY:> generator expressions and the COMPILE_OPTIONS target property and the CMAKE_CXX_FLAGS (and similar) variables in a file(GENERATE) command call.
Simliar for compile definitions (see the COMPILE_DEFINITIONS target property).
For a list of all properties supported on targets, see https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html#properties-on-targets

Is it possible to suppress warnings in a specific directory?

In my project I had to copy a library into my source to make some minor adjustments.
This library throws a couple of warnings when compiling. I don't like that ;-)
Since I don't want to change the library code any more than absolutely necessary, I do not want to put #Suppress lines into the library code.
Is there a possability to advise the compiler "Please ignore warnings, but only in src/foo/bar"? Maybe a compiler flag?
I am using a Gradle build, if that opens additional options.
foo.bar is a package and packages can not be suppressed.
Your options are:
Remove compiler warnings entirely
Create separate source set and compile task for the problematic code.
Fix the warnings.

Meson: how to make find_library() works with an unusual path?

For my Meson project I have a dependency that is in an "unusual" place:
/opt/MyDependence/lib/libmyLib.so
/opt/MyDependence/include/myLib.hpp
My meson file is:
project('Test', ['cpp'])
cpp = meson.get_compiler('cpp')
myLib_dep = cpp.find_library('myLib', required: true)
Obviously Meson cannot find the library
Meson.build:5:0: ERROR: C++ library 'myLib' not found
The problem is that I do not know the "canonical" way to add extra search paths so that Meson can found my lib. Any idea?
update: please note that even if I use:
meson --libdir=/opt/MyDepedence/lib build
I get this error message:
meson.build:1:0: ERROR: The value of the 'libdir' option is '/opt/MyDepedence/lib' which must be a subdir of the prefix '/usr/local'.
Note that if you pass a relative path, it is assumed to be a subdir of prefix.
find_library now has an optional argument dirs (since 0.53.0) that indicates an extra list of absolute paths where to look for program names.
cpp = meson.get_compiler('cpp')
myLib_dep = cpp.find_library('myLib', dirs: '/opt/MyDepedence/lib', required: true)
I finally got a solution, one must use LIBRARY_PATH
export LIBRARY_PATH=/opt/MyDepedence/lib
meson build
Note: attention this is not LD_LIBRARY_PATH, see there for the difference
Also read this Meson/issues/217 . For Windows, the LIBRARY_PATH equivalent seems to be LIBPATH (but I was not able to check as I only run under Linux).
An alternative is to "manually" define a new dependence. In your Meson project:
project('Test, ['cpp'])
myLib_dep = declare_dependency(link_args : ['-L/opt/MyDependence/lib', '-lmyLib'],
include_directories : ['/opt/MyDependence/include'])
exe1 = executable('main', ['main.cpp'], dependencies : [myLib_dep])
A refinement that could be done is to store this "manual" setting into meson_options.txt.
Note: I finally answered my question, but I am still open to better solutions.
Standard way to solve this is to use pkg-config. In short, library installation procedure should include stage where special "mylib.pc" file is generated (from scratch, or typically from template "mylib.pc.in" - search in the internet, there are lots of examples). Then these small key-value files which has info on include/library dirs, dependencies, etc are installed to some known location, typically /usr/lib/pkgconfig/. Meson naturally runs pkg-config under the hood and finds your library when you have something like this
mylib_dep = dependency('mylib', required: true)
in your meson.build.
Update
Regarding libdir meson option error, you can try add option prefix as well:
meson --prefix=/opt/MyDepedence --libdir=lib build
Note also that with this command line you actually call implicitly setup command (there is no command build, since you will build with ninja) and build is a build directory that will be created using your options. Check this. That is why it is more visible to write:
meson setup build_dir --prefix=/opt/MyDepedence --libdir=lib

CMAKE_SYSROOT in CMakeTestCCompiler

I have a project which builds for PPC, the Toolchain is working correctly, i can build when the sysroot is installed under /opt/poky/1.5. Now i tried to move that Installation to the Project Directory (it is not a part of the Repository there, it is just installed there so it is not reliant on that fix path, so that everyone can check out the project and build it wothout setting up the sysroot under that fixed folder).
To achieve this I set CMAKE_SYSROOT to "${PROJECT_SOURCE_DIR}/poky" where the poky will be installed upon execution of a custom build script (the project also needs to build a secure image, so it is way simpler to use a build script instead of anything else, also this is convenient for jenkins).
Since the CMAKE_SYSROOT is build from the PROJECT_SOURCE_DIR which is different for the CMakeTestCCompiler Project, the cmake call fails teloling me that the CCompiler is broken of course. So I want to know, how I am supposed to get the CMakeTestCCompiler Project to compile with the same CMAKE_SYSROOT variable, without altering the CMakeTestCCompiler Project itself (of course).
Somehow I cannot find an answer anywhere, it seems that noone ever had this issue (which frankly i cannot understand, this should be a common setup in my opinion). (Or maybe i am just too much of a noob when it comes to CMAKE, which i will gladly admit)
I am not interested in solutions like: "JUST INSTALL IT IN A FIX PATH" or such... please, I need the setup like this, I have reasons for that.
THX for reading/trying/answering/helping
Have a nice day
EDIT1:
In CMakeLists.txt (top level CMakeFile so it should be used by any build):
`SET(CMAKE_SYSROOT "${PROJECT_SOURCE_DIR}/poky/sysroots")`
In ToolchainCMake (the one given to the cmake as CMAKE_TOOLCHAIN_FILE):
`SET(CMAKE_SYSTEM_NAME Linux)`
`SET(CMAKE_SYSTEM_VERSION 1)`
`SET(CMAKE_SYSROOT "${PROJECT_SOURCE_DIR}/poky/sysroots")`
`SET(COMPILER_ROOT ${PROJECT_SOURCE_DIR}/poky/sysroots/i686-pokysdk-linux/usr/bin/powerpc-poky-linux-gnuspe)`
`SET(CMAKE_C_COMPILER ${COMPILER_ROOT}/powerpc-poky-linux-gnuspe-gcc)`
`SET(CMAKE_CXX_COMPILER ${COMPILER_ROOT}/powerpc-poky-linux-gnuspe-g++)`
`MESSAGE("CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}")`
`MESSAGE("CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}")`
`MESSAGE("COMPILER_ROOT: ${COMPILER_ROOT}")`
`SET(CMAKE_FIND_ROOT_PATH ${SYS_ROOT}/ppce500v2-poky-linux-gnuspe)`
`SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)`
`SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)`
`SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)`
EDIT2:
I used the
`set(CMAKE_C_COMPILER_WORKS 1 CACHE INTERNAL "")`
`set(CMAKE_CXX_COMPILER_WORKS 1 CACHE INTERNAL "")`
settings to simulate the CMakeTestCCompiler build succeeding and realized that I am facing some additional problems: It seem that the packages are looked up on the system instead of the CMAKE_SYSROOT folder. Even tried the
`SET(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})`
to try to force the search in there, but without luck. In the CMakeError.log I can see, that the compiler itself was configured with the prefix option that points to /opt/poky/1.5, the path that i want to "overwrite", now I am not sure if the compiler could even deal with an alternate path.
I felt the need to add these information, they not really add to the problem at hand.
ERRORS:
I also found some errors in the above cmake:
`SET(CMAKE_SYSROOT "${PROJECT_SOURCE_DIR}/poky/sysroots")`
must be
`SET(CMAKE_SYSROOT "${PROJECT_SOURCE_DIR}/poky/sysroots/ppce500v2-poky-linux-gnuspe")`
instead and therefor the
`SET(CMAKE_FIND_ROOT_PATH ${SYS_ROOT}/ppce500v2-poky-linux-gnuspe)`
changes to
`SET(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})`
EDIT: Whole answer changed.
My first suspicion was that the problem is that value of ${PROJECT_SOURCE_DIR} is not known in CMAKE_TOOLCHAIN_FILE as it is processed before CMakeLists.txt. But this isn't true.
I had similar problem (CMake 2.8.12.2), everything worked OK, when I passed cross compiler by CC environment variable with --sysroot option, i.e. CMake was invoked as follows:
CC="arm-linux-gnueabi-gcc --sysroot=/path/to/sysroot" cmake /path/to/sources
When I switched to using toolchain file, CMake started to report that C compiler doesn't work.
To workaround this problem, I use CMakeForceCompiler package. Parts toolchain file (along with comments) I think are relevant:
include(CMakeForceCompiler)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 1)
# Force compiler - only option that actually works
cmake_force_c_compiler (${TOOLCHAIN_PATH}/bin/arm-linux-gnueabi-gcc GNU)
cmake_force_cxx_compiler(${TOOLCHAIN_PATH}/bin/arm-linux-gnueabi-g++ GNU)
# NOTE: CMAKE_SYSROOT doesn't work as expected
add_definitions("--sysroot=${TOOLCHAIN_SYSROOT}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --sysroot=${TOOLCHAIN_SYSROOT}" CACHE INTERNAL "" FORCE)
Note, that TOOLCHAIN_PATH and TOOLCHAIN_SYSROOT are my local variables set before.

Objective-C syntax checker

Is there an Objective-C syntax checker?
I have tried gcc -fsyntax-only but it is not really 'syntax only'. It still produces errors if run on an individual implementation file which has references to external frameworks.
I am looking for something that can perform a syntax check on individual header or implementation files without attempting to link or produce object files.
Can gcc do this with additional flags I am unaware of, or is there another tool up to this task?
I want to do this from the command-line. Can xcodebuild do this for an individual file? Running xcodebuild for the entire project to check the syntax of one file is a bit much.
There's no way for it to check the syntax without it knowing about the header files for the frameworks you are using. You need to use the -framework flag to include the relevant header files.
You could try using clang -fsyntax-only instead, especially if you're using 10.6/Xcode 3.2. Clang/LLVM has much better separation between the parser and the other parts of the compiler chain. You can find clang in /Developer/usr/bin.
So after trawling through the gcc man page I discovered the -F flag which lets you add a framework directory to the list of directories gcc searches for header files.
This solves my issue.
Use it like this: gcc -fsyntax-only -ObjC -F/Path/To/A/Framework -F/Path/To/Another/Framework File.m
You can compile a single file in Xcode[1] using Build->Compile (cmd-K) which is effectively a syntax check (there's no linking step).
[1] I assume you're using Xcode, as there's little point in using Objective-C without OS X (really the Cocoa frameworks).