Which standard library to use in Kotlin - kotlin

In Kotlin, when working with the JVM, it seems there is multiple choices for standard library, namely kotlin-stdlib, kotlin-stdlib-jdk7 and kotlin-stdlib-jdk8.
I cannot, however, find anything telling me the difference between these.
The only visible difference I have found is that I cannot use com.fasterxml.jackson.databind.exc.MismatchedInputException with kotlin-stdlib, but I can with kotlin-stdlib-jdk8.
Is there anywhere I can read about the advantages using one over the others, or can anyone explain this in layman terms?

Most of the stdlib is in the plain kotlin-stdlib artifact.
kotlin-stdlib-jdk7 adds suppressed exceptions and a few extension methods.
kotlin-stdlib-jdk8 adds ThreadLocalRandom as well as a few other extension methods and retrieving groups by name in Regexes.
The code is there: https://github.com/JetBrains/kotlin/blob/55c8b35eee2ee8a93ccaffeaac6f9c3e4fd4ff18/libraries/stdlib/jvm/src/kotlin/internal/PlatformImplementations.kt#L27
EDIT: I got curious so wrote an article about this: https://medium.com/#mbonnin/the-different-kotlin-stdlibs-explained-83d7c6bf293.
Bottom line: Android declares a weird JVM version so almost nothing from -jdk7 and -jdk8 is used.

As the name indicates, -jdk8 is supposed to be used when using the JDK8. It contains code used to integrate the changes made in the JDK 8 into the Kotlin standard lib.
As its pom indicates, it depends on -jdk7, which contains the code needed to integrate the changes made in the JDK 7 into the Kotlin standard lib.
And as the pom of -jdk7 indicates, it depends on the stdlib.
So, in short, use the one matching your JDK. Adding it to the dependencies will also, transitively, add all the ones for the previous versions of the JDK.

As of Kotlin 1.8, the different standard libraries have been merged, and you can just use kotlin-stdlib. JVM targets 1.6 and 1.7 are not supported anymore.
Updated JVM compilation target
In Kotlin 1.8.0, the standard libraries (kotlin-stdlib,
kotlin-reflect, and kotlin-script-*) are compiled with JVM target 1.8.
Previously, the standard libraries were compiled with JVM target 1.6.
Kotlin 1.8.0 no longer supports JVM targets 1.6 and 1.7. As a result,
you no longer need to declare kotlin-stdlib-jdk7 and
kotlin-stdlib-jdk8 separately in build scripts because the contents of
these artifacts have been merged into kotlin-stdlib.
note
If you have explicitly declared kotlin-stdlib-jdk7 and kotlin-stdlib-jdk8 as dependencies in your build scripts, then you
should replace them with kotlin-stdlib.
Note that mixing different versions of stdlib artifacts could lead to
class duplication or to missing classes. To avoid that, the Kotlin
Gradle plugin can help you align stdlib versions.
What's new in Kotlin 1.8 - Updated JVM compilation target

By running Gradle dependencies task in your Kotlin project, you can find some useful information. This is a part of output in a sample project:
$ ./gradlew dependencies
...
kotlinCompilerClasspath
\--- org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.20
+--- org.jetbrains.kotlin:kotlin-stdlib:1.3.20
| +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.3.20
| \--- org.jetbrains:annotations:13.0
+--- org.jetbrains.kotlin:kotlin-script-runtime:1.3.20
+--- org.jetbrains.kotlin:kotlin-reflect:1.3.20
| \--- org.jetbrains.kotlin:kotlin-stdlib:1.3.20 (*)
\--- org.jetbrains.intellij.deps:trove4j:1.0.20181211
...

Related

Dependencies between Android native modules (prefab) fail to build

Our Android application consists of 40-some Android Library Modules (ALMs), each of which also builds a C++ shared library with externalNativeBuild and CMake. So far we had the dependencies between these libs set up like this:
The dependent ALM references the dependency ALM with api project(':lib')
The dependent CMake script references the dependency .so with add_library(SHARED IMPORTED lib) and set_target_properties(lib PROPERTIES IMPORTED_LOCATION ...) and a relative path.
Recently we had to upgrade to the latest Android API version. This started off a cascade because now we were getting deprecated warnings in code generated by the navigation-ktx library, but upgrading that requires upgrading Gradle and the Android Gradle plugin. After that I started getting errors like liblib.so, needed by 'project', missing and no known rule to make it.
It looks like the latest Gradle parallelizes build tasks more heavily, and this means the dependent CMake/Ninja builds are being started concurrently with their dependencies, resulting in this error because the dependency is not yet built. I figured out that what we were doing was not entirely supported, but there is a "supported" way to do that now, so I refactored our entire build to use Prefab.
Now I started getting other errors, alternating between:
1.
C++ build system [prefab] failed while executing ...
Usage: prefab [OPTIONS] PACKAGE_PATH...
Error: Invalid value for "PACKAGE_PATH": Directory ... is not readable.
ld: error: undefined symbol ...
I looked into build/intermediates and found that in the 2nd case, the cmake config script was generated incorrectly: instead of add_library(lib::lib SHARED IMPORTED ) it had add_library(lib::lib INTERFACE IMPORTED) like it it was a header only library, and there was no IMPORTED_LOCATION set in the file.
What am I doing wrong and what should I do to unbreak our build?
It looks like the toolchain support for prefab interdependencies within a project is not quite finished. Others are reporting the same kind of errors at https://issuetracker.google.com/issues/265544858:
This appears to be a race condition with generating prefab cmake files.
It says in https://issuetracker.google.com/issues/221231432 that the header-only cmake config is generated to satisfy Android Studio's IDE features (completion, etc.) before the library is actually built.
Treat as-yet-unconfigured modules as if they are Header-only libraries for Android Studio purposes. This works because Android Studio doesn't care about linker flags for the purposes of providing language services.

Maintaining multiple projects which consume conan packages

Background:
I have a Visual Studio solution(s) with multiple (50+) projects (libraries static/dynamic and final executables). There is internal Visual Studio reference mechanism used to comsume required libraries for particular executables. Of course each project uses external packages, there are "duplicates" like boost, gtest, there are also some "unique" references for only one or few projects.
What's more, libraries are used in other solutions (project sharing) to deploy other executables.
This is my general project structure:
MainDir
|
- DebugDlls (build output)
- Debug64Dlls (build output)
- ReleaseDlls (build output)
- Release64Dlls (build output)
- Libraries
|
- lib1
- lib2
- ...
- Executables
|
- exe1
- exe2
...
I'm about to migrate from NuGet to conan as a dependency manager for external libraries since there are more ready to use conan packages that NuGet one and it's cross-platform. I'd like to do it project by project, dependency by dependency.
One global conan file to rule them all is not an option since each library has to be as standalone as possible so I'm able to simply grab one and use for new executable. What's more it would be impossible to track dependencies of particular library or executable.
My idea is to put a separate conanfile in each project and define dependencies.
Here is the first issue: I need some global/automatic management of common libraries like boost to not mix versions/variants and spare some time on version updates.
this one may be handled by a global file which defines reusable depndencies
is there something ready to use in conan, like template?
Second issue is to copy dlls from dependencies into proper build output so I'm able to execute the binaries.
this one should be fixable also by some global file with proper defines.
Third one is to execute conan install in each project
once again, a hand crafted script will do the job.
I was digging across the conan documentation but it's not very well organized and I was unable to find proper solution in my case. Maybe I missed something?
What would be the best approach here? Is there any build in conan mechanism for that (like CMake add_subdirectory). I would not like to reinvent the well if one already exists :)
I'm about to use conan 1.x

How do I obtain Kotlin/JS dependency files

As of Kotlin 1.3.41, the kotlin js compiler would produce the js files for dependencies (e.g. the standard lib kotlin.js). In Kotlin 1.3.50 and 1.3.60, these dependencies are no longer produced.
How is one supposed to obtain these files separately or get the kotlin compiler to produce them again?
The problem seems to go away if we switch to "compile" instead of "implementation" for the dependencies in the build.gradle file.

Interface compile options for imported library in older CMake versions

I'm trying to create an imported target in CMake and specify a compiler option to use with my target from any downstream project. It looks similar to the snippet below (-O3 is just an example, the use case is a bit more sophisticated):
add_library(Foo::Foo UNKNOWN IMPORTED)
set_target_properties(Foo::Foo
INTERFACE_COMPILE_OPTIONS "-O3")
The issue is that this isn't supported by CMake versions older than 2.8.12.
Is there a way to implement this mechanism in the older versions or are there any reasonable alternatives?

Encapsulating a JNI library inside a jar file

I am trying to develop a plugin for Fiji/ImageJ that relies on a native library (JNI).
The JNI library itself depends on libtiff and fftw. On OSX and Linux, I use the class NativeUtils and everything works fine.
On windows, I included binary versions of libtiff and fftw in the CMake package and managed to link the JNI library against those (either statically of dynamically). However, the resulting JNI module does not include libtiff or fftw and I obtain an error when I try to load the JNI library with NativeUtils.loadLibraryFromJar. This is also the case when I include the dependent .dll in the .jar since they are not extracted by NativeUtils.
Here are the relevant lines in CMakeLists.txt:
add_library(fftw STATIC IMPORTED GLOBAL)
set_target_properties(fftw PROPERTIES IMPORTED_LOCATION "${libdir}/libfftw3f-3.lib"
INTERFACE_INCLUDE_DIRECTORIES "${incdir}")
SWIG_ADD_LIBRARY(javainterf
TYPE MODULE
LANGUAGE java
SOURCES javainterf.i javainterf.c src1.c)
SWIG_LINK_LIBRARIES(javainterf libcode1 fftw)
add_jar(Foo
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/java/foo1.java
INCLUDE_JARS java/resources/ij-1.51p.jar
VERSION ${JAR_VERSION})
add_dependencies(Foo javainterf)
add_custom_command(TARGET Foo POST_BUILD
COMMAND "${Java_JAR_EXECUTABLE}" -uf Foo-${JAR_VERSION}.jar
-C ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} ${JNI_LIB_NAME})
How would you make sure that all the dependencies are properly included in the jar and loaded?
You can't load library from inside JAR without extracting it in a first place.
Take a look here at full sample where native code is embedded inside JAR and extracted when needed.
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo031
Update
Well, in that case, when you need to pack more libs and you want to properly resolve locations, you need to play with runtime env a little bit.
Take a look here:
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo035
git clone https://github.com/mkowsiak/jnicookbook
cd jnicookbook/recipes/recipeNo035
make
make test
Have fun with JNI!