mono mkbundle : what are mono_mkbundle_init() and JIT inizialization? - mono

I tried to bundle my app with mkbundle command due to this help:
http://www.mono-project.com/Guide:Running_Mono_Applications#Bundles
but I don't understand this part of this doc:
With -c, the further option --nomain will generate the host.c file without a main method so that
you can embed it as a library in an existing native application in which you are embedding the Mono
runtime yourself. Just call mono_mkbundle_init() before initializing the JIT to make the bundled
assemblies available.
which is absolutely what I need to do!
I also looked up this doc:
http://man.he.net/man1/mkbundle2
again the same part:
You may also use mkbundle to generate a bundle you can use when embed-
ding the Mono runtime in a native application. In that case, use both
the -c and --nomain options. The resulting host.c file will not have a
main() function. Call mono_mkbundle_init() before initializing the JIT
in your code so that the bundled assemblies are available to the embed-
ded runtime.
I don't really know what are mono_mkbundle_init() and initializing the JIT...
Thanx

mono_mkbundle_init() is a function generated by mkbundle in host.c
"initializing the JIT" should be mono function mono_jit_init()
so the meaning is that, link the generated c file in your native application and invoke mono_mkbundle_init() before invoking mono_jit_init()

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

How to tell c++ linker that some classes will be added later by dlopen

I have legacy c++ code that I'm trying to re-engineer.
I want to take some part of code out of the project as a ".so" shared library and load them dynamically by "dlopen".
I have written a dynamic loading mechanism which can load new modules dynamically at runtime.
Now I want to decouple existing modules from main project.
For instance I have extracted module "X" from the main project and created shared library which can be loaded later, but some part of the main project are using module X's classes directly and I can't change them yet.
I can compile the project by using module X's header files, but linker throw out "undefined reference" error.
How can I tell c++ linker that these classes will be added later by dlopen mechanism at runtime?
note: I can link and run project by copying created ".so" file of module X in "/lib" folder and use it when linking by "-lX" flag, but if I delete this file form the /lib folder the project fails on startup.
I know if you use X's classes directly you have to link X.so to your program. But if you link X.so you can use dlopen in runtime.
What you need is called an import library. They contain small wrappers for all necessary functions and thus satisfy all static linker dependencies. At runtime these wrappers will load dynamic library if it's not yet loaded and forward execution to real implementation inside library.
Import libraries is a standard feature of Windows DLLs but they are not available out-of-the-box on Linux (or any POSIX system). You can implement wrappers by hand or use Implib.so to generate them automatically.

How can I get the Frege compiler to see Android API classes when using Gradle?

I am attempting to write an Android app using the Frege language. Unfortunately, I'm not aware of any examples of how to do this.
So, I'm using Gradle as my build system, with the Android Gradle plugin. Then to get the Frege code to be compiled, I'm using a javaexec to call the frege compiler before the Java files get compiled, as suggested in this post.
I was successful in building an Android application with Frege code that gets called by Java code, as shown here.
However, the Frege code can only call standard Java APIs. It can't call any of the Android APIs.
I'd like to be able to call Android APIs from Frege. There is a nice repo here that has Frege wrappers for the Android APIs. Unfortunately, it has no build system or instructions.
I believe I've successfully set up my build.gradle to build the FregeAndroid wrappers along with my project's code. The Frege compiler is indeed attempting to build them.
However, the FregeAndroid code fails to compile, because it can't see the Android API classes. I assume I need to somehow find where the Android API classes are, and then add that to the Frege compiler's classpath, so it can see those classes. Unfortunately, this is where I'm stuck. I'm a newbie at Gradle, and can't figure out how to do this.
Here is my project which I have so far, which fails to build, in the following way:
:compileDebugJavaWithJavac
Frege compiler args: "-inline -d src/frege -make -fp /Users/ppelleti/Library/Android/sdk/platforms/android-21/android.jar -sp /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src/frege/android/animation/TimeInterpolator.fr"
calling: javac -cp /Users/ppelleti/.gradle/caches/modules-2/files-2.1/org.frege-lang/frege/3.23.401-g7c45277/716990197271fdc15917b4f8d023d63009ba6e39/frege-3.23.401-g7c45277.jar:/Users/ppelleti/Library/Android/sdk/extras/android/m2repository/com/android/support/multidex/1.0.0/multidex-1.0.0.aar:src/frege:/Users/ppelleti/Library/Android/sdk/platforms/android-21/android.jar -d src/frege -sourcepath /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src -encoding UTF-8 src/frege/frege/android/animation/TimeInterpolator.java
runtime 4.282 wallclock seconds.
Frege compiler args: "-inline -d src/frege -make -fp /Users/ppelleti/Library/Android/sdk/platforms/android-21/android.jar -sp /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src /Users/ppelleti/programming/android/frege-on-android/FregeAndroid/src/frege/android/app/Activity.fr"
Android.app.TaskStackBuilder: build failed because module is not on class path
Android.app.Fragment: build failed because module is not on class path
Android.app.LoaderManager: build failed because module is not on class path
[... omitted a bunch of similar lines ...]
Any ideas would be much appreciated!
It turns out that there were several problems, including problems with both the source path and the classpath. I've updated my repository to fix these problems.
However, ultimately the build fails because there are files missing from the FregeAndroid repo. So to get my example to build, it would be necessary to fix the FregeAndroid wrappers or write new wrappers.

Build and link µIP library with no OS

I'm relitavely new to embedded development and I have a question, or more of a feedback, on building and linking the µIP library on an embedded device. For what it's worth, the following is using a FOX G20 V board with an ATMEL AT91SAM9G20 processor with no OS.
I have done some research, and the way I see myself building and linking the library on the board is one of the following two options.
Option 1: The first option would be to compile the whole library (the .c files) in order to have a built static library in the form of a .a file. Then, I can link the created static library with my application code, before loading it on the device. Of course, the device driver will have to be programmed in order to allow the library to work on the platform (help was found here). This first option is using a Linux machine. For this first option as well, in order to load the static library linked with my application code, do I do so with an "scp"?
Option 2: The second option would be to compile and link the library to my application code directly without going through an intermediate static library. However, since my platorm does not contain an OS, I would need to install an appropraite GCC compiler in order to compile and link (if anyone has any leads for such an installation, that would be very helpful as well). However I'm quite unfamilier with the second option, but I've been told that it is easier to implement so if anyone as an idea on how to implement it, it would be very helpful.
I would appreciate some feedback along with the answers as to whether these options seem correct to you, and to be sure that I have not mentioned something that is false.
There is no real difference between these options. In any case, the host toolchain is responsible for creating a binary file that contains a fully linked executable with no external dependencies, so you need a cross compiler either way, and it is indeed easiest to just compile uIP along with the rest of the application.
The toolchain will typically have a cross compiler (if you use gcc, it should be named arm-eabi-gcc or arm-none-eabi-gcc), cross linker (arm-eabi-ld), cross archiver (arm-eabi-ar) etc. You would use these instead of the native tools. For Debian, you can find a cross compiler for ARM targets without an OS in testing/unstable.
Whether you build a static library
arm-eabi-gcc -c uip.c
arm-eabi-ar cru uip.a uip.o
arm-eabi-ranlib uip.a
arm-eabi-gcc -o executable application.c uip.a
or directly link
arm-eabi-gcc -c application.c
arm-eabi-gcc -c uip.c
arm-eabi-gcc -o executable application.o uip.o
or directly compile and link
arm-eabi-gcc -o executable application.c uip.c
makes no real difference.
If you use an integrated development environment, it is usually easiest to just add uip.c as a source file.

How do I tell cmake not to create a console window?

I can achieve this by gcc :
gcc -mwindows -o simple simple.c
But only find this in cmake:
add_executable(simple WIN32 simple.c)
But it's not exactly the same as -mwindows,
this will require the entry point to be WinMain,
while gcc -mwindows doesn't require this(can be main).
How should I do it properly?
If you use:
add_executable(simple WIN32 simple.c)
then you must provide a WinMain function. That's what the WIN32 flag to add_executable means: it means you're going to make it a Windows program, and provide a WinMain function.
I would recommend doing it this way if you're really writing a Windows application. It's what makes the most sense and fits most naturally with the underlying OS.
However, if you still want to pass gcc the "-mwindows" flag, but use a "main" anyway, then simply add "-mwindows" to the CMAKE_CXX_FLAGS and/or CMAKE_C_FLAGS value. You can do this in the cmake-gui program by adjusting those variables interactively to include "-mwindows" or you can do it with command line CMake, like this:
cmake -DCMAKE_C_FLAGS="-mwindows"
As DLRdave has said saying that the executable will be a win32 one means it will have WinMain as the entry point and be a windows application.
If the application is to be cross platform still then the usual means to suppress the console window but still allow use of main is to write a stub WinMain as found in the SDL or SFML libraries which simply calls the main function with the global variables __argc and __argv as arguments and returns its result.
This prevents the application from having a console window but reduces the disruption to the code of having to use WinMain as the entry point.
You can add target link option (for new versions of Cmake)
target_link_options(simple PRIVATE -mwindows)
https://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/i386-and-x86_002d64-Windows-Options.html
In case you need it for both Windows and Linux
if (WIN32)
# /ENTRY:mainCRTStartup keeps the same "main" function instead of requiring "WinMain"
set(SUBSYSTEM_LINKER_OPTIONS "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
else()
set(SUBSYSTEM_LINKER_OPTIONS "-mwindows")
endif()
target_link_options(TargetName PRIVATE ${SUBSYSTEM_LINKER_OPTIONS})
Related Question