Can I control the "prefix" and exported names of functions of a Kotlin native shared library? - kotlin-native

I want to build a shared library in Kotlin/Native that conforms to a predefined naming scheme (JNI, in this particular case, but no, I don't want to compile Kotlin to JVM bytecode). The docs on the Kotlin site show the Kotlin code in a "package example" and then the generated C-exported functions are function pointers that are nested inside of "kotlin.root.example". What I'd like is an equivalent to an "extern C" capability for a standalone function in Kotlin/Native. Am I missing something?

Related

How to package module.modulemap into CocoaTouch Swift Framework?

I am trying to create a CocoaTouch Swift Framework which I can then distribute to 3rd parties for them to use, and I can build it and use it ok on my machine.
The issues arise when I give it to other people.
My framework uses C code, which I make available for use with Swift within my framework via a module.modulemap file as such:
And I am able to use such module in a Swift file, within the framework, ok, as such:
However, when I build the framework and give it to other people to use, their compiler complains that the Minzip module is missing with the message Missing required module 'Minizip'.
Having investigated, it seems like I'd have to make the users of my framework modify their Swift Compiler - Search Paths -> Import Paths the same way I have to do it to have my compiler find the module.modulemap.
Is there a way that I can build the framework so that I don't have to do this?

Xcode Framework Modules

I'm having an issue implementing modules for my particular build configuration. I have a bunch of dynamic frameworks that I would like to add module map files to so that they can be naturally imported into Swift without having to use Objective-C Bridging Header files. The issue that I'm having is as follows:
I have multiple modular frameworks:
Framework.framework (base framework, required by all components)
Framework.Component1.framework
Framework.Component2.framework
... etc
I would like to be able to write a module map for each framework that uses this dot notation for the module naming (for backwards compatibility, among other reasons) but Xcode isn't allowing me to name whole modules with the dot syntax since the dot syntax is reserved for Submodules.
I've tried creating an umbrella framework that contains all of different components and writing a single module map for that, but given that the frameworks are dynamic this necessarily bloats the final binary size if the user isn't using all of the frameworks inside of the umbrella framework.
Are there any solutions that would allow me to use this dot syntax while having separate module map files for each of the frameworks?
Thanks!
Go with the umbrella framework strategy.
Then, for submodules that are "optional" in your umbrella framework (maybe even all or most of them) set the submodule declaration to explicit. This means the consumer must import the submodule explicitly in order for it to be loaded. This is what I've done in the past to import a very large C library into Clang's module system and it worked well enough.
The docs are okay, but not great. However, they do go over this case pretty well: https://clang.llvm.org/docs/Modules.html#submodule-declaration

Why does Bazel under-link and how do I fix it?

I'm trying to build and package LCM with Bazel. This works for the "build" part, but the end result is a library not usable by external consumers (i.e. "package" fails, because the package is broken).
LCM uses glib, which I am importing with pkg_config_package (gory details). More particularly, LCM uses glib internally, but does not expose this to users. This means that consumers should not need to link glib; liblcm.so should do that, and consumers should only need to link to LCM itself.
This all works great with upstream (which uses CMake and Does The Right Thing). Bazel, however, seems to be not linking liblcm.so to glib, for some unknown reason. If I build an executable with Bazel within the same overall environment, Bazel seems to know that users of LCM also need to link to glib. However, when I try to package this LCM for external use, it is broken, because liblcm.so isn't linked to glib, which forces consumers to deal with LCM's private glib dependency.
Why is Bazel not linking the LCM library to glib, and how do I fix it?
(p.s. We have similar issues with libbot...)
Apparently, this is a known issue: https://github.com/bazelbuild/bazel/issues/492.
I can't just make the cc_library a cc_binary, either, because — while that would fix the under-linking — then I can't use the library in other Bazel targets. Nor can I make a cc_binary that wraps a cc_library, because then internal and external consumers aren't using the same library.
Static libraries do not link with other static libraries. When building through Bazel, Bazel keeps track of the dependencies and will link against all dependent libraries when building the executable.
There's more information here about linking static libraries:
Linking static libraries to other static libraries
One interesting suggestion brought up is unarchiving both libraries and then creating a new library with all the .o files. This could possibly be achieved in a genrule.

What is a dynamic framework as opposed to a non-dynamic one?

Xcode 6 allows for dynamic frameworks.
What is a dynamic framework?
Both dynamic framework and static framework is a bundle containing a binary and some other things. The binary is called dynamic library or static library.
The binary is what you code is after compiling, your functions, classes, method become binary form, and they are called symbols.
When building your project.
Your code will be built into a binary, let's call it MyProjectBinary.
If your project links to a static library, then after building MyProjectBinary, linker check the symbols in MyProjectBinary and if it uses some part of the static library, for example, use a class in the static library), then linker will copy all the symbols related to the class and combine them in to MyProjectBinary. So no matter how many static library you use, you only get one building result, which is MyProjectBinary.
If you link to dynamic library, then you are telling the linker that, when MyProjectBinary is running, there will be that dynamic library at a suitable place. Dynamic library is not magic, in fact, you've used them for long time. All the frameworks Apple provides are dynamic libraries. They are guaranteed to exist when you app is running on device/simulator.
Let's assume that your project links to a dynamic library called MyDynamicLibrary. When building your project, first MyProjectBinary is still generated the same as using static library. Then, linker just add some information to MyProjectBinary, mark where to find "MyDynamicLibrary" at runtime. Nothing from MyDynamicLibrary will be add to MyProjectBinary
When running your project:
For the project using static library, nothing special happens, since all the code needed is inside MyProjectBinary, it just runs.
For the project using dynamic library, when your code calls a function which is in MyDynamicLibrary, the system tries to find MyDynamicLibrary according to the information stored in MyProjectBinary, if it finds MyDynamicLibrary, then for MyProjectBinary, the function is used like in MyProjectBinary. If it can't find MyDynamicLibrary, them an error will happen and you app will be terminated.
So why do we need dynamic library for iOS 8?
Before iOS8, an app can have only one executable binary, so using static library is OK.
But when iOS 8 comes, you can deliver multiple executable binary in one app, the additional binaries are extensions' executable binaries. This brings up a problem, if there are some code that are uses by multiple executable binaries, and if using static library, same symbols will be copied into every executable, thus takes more space. This is the time when dynamic library comes in handy, we can put these code in dynamic library, and deliver only one copy of the dynamic library for app, the app and its extensions can use the same dynamic library.

linking custom framework to library in xcode

I want to include Microblink's PDF417 framework into my library. Library project compile and work fine but when I use MyLibrary.a file in my application I've got "undefined symbols for architecture armv7" error. Any ideas? Can I include custom framework to library or this isn't possible.
Trojanfoe's answer is correct for your case. But in general, the answer depends on the type of the library inside the framework.
iOS/MacOS framework is a just a collection of a library together with all relevant header files. This makes including the library into other projects much easier, because the whole framework can be included at once, thus eliminating the need to modify linker and header search paths and linker flags.
Library itself can be either a static library or a dynamic/shared library. Framework can contain the library of any type, there are no limitations in that regard.
If the library in framework is static, then all the objects from that library are copied into target product at compile time. If the target product is a static library (MyLibrary.a in your case), additional linking with the framework in the application is not needed, because all the objects are contained in MyLibrary.a
If the library in the framework is dynamic, then objects from that library are loaded at load-time or run-time, not at compile time. Because of that, frameworks of that type need to be linked with end applications also.
In your case, pdf417 framework contains a dynamic library, which means you will also have to include that framework into your end application.
I'm a developer on Microblink's PDF417 SDK. The thing is, we can provide our library in any format. The format we have chosen in our Github repository is an .embeddedframework which contains a dynamic library together with all resource files because that makes including the framework into Application projects very simple. If you have a use case which requires a different format, we invite you to contact us on https://help.microblink.com/hc/en-us
A static library is just a collection of object files (a bit like a zip file without compression or hierarchy) and cannot hold information about any dependencies it might have.
Therefore you have to link the final executable binary against both your library and the dependent framework. The same applies if the dependency was a static library, dynamic library or framework.

Resources