-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix JNI target #26
fix JNI target #26
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome!
docs/install.md
Outdated
|
||
The library is available at [conan-center](https://conan.io/center/djinni-support-lib): | ||
|
||
```text | ||
[requires] | ||
djinni-support-lib/0.0.1 | ||
djinni-support-lib/0.1.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I plan to release the canges in this PR as a patch release. To make the usage in cmake without conan possible, two adjustments are needed in the CMakeLists.txt
CMakeLists.txt
Outdated
@@ -55,6 +55,9 @@ if(DJINNI_STATIC_LIB) | |||
else() | |||
add_library(djinni_support_lib SHARED ${SRC_SHARED}) | |||
endif() | |||
|
|||
add_library(djinni-support-lib::djinni-support-lib ALIAS djinni_support_lib) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the name of the target that is defined if the library is installed with the conan cmake_find_package
generator. I have added this alias to ensure that the target can always be referenced under the same name, no matter if installed via conan or by embedding the sources in cmake directly (see updated install instructions).
CMakeLists.txt
Outdated
|
||
include(CTest) | ||
if (BUILD_TESTING) | ||
if (BUILD_TESTING AND DJINNI_BUILD_TESTING) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BUILD_TESTING
is a global cmake variable that will affect the whole project. If the support-lib is installed by embedding the sources in cmake, setting the variable could potentially disable the tests for the parent project itself, too. In this case the new option DJINNI_BUILD_TESTING
can be used to disable tests just for the support-lib.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you created answered while I wrote the question, that's great!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added two new installation options. I have tested both in a local setup and they seem to work.
…l be set to define wether the library should be STATIC or SHARED. But if not defined, the global BUILD_SHARED_LIBS cmake flag is followed.
CMakeLists.txt
Outdated
# The target type of the library can be defined by setting `DJINNI_STATIC_LIB`. | ||
# If `DJINNI_STATIC_LIB` is not defined, the default CMake flag `BUILD_SHARED_LIBS` is followed. | ||
if(NOT DEFINED DJINNI_STATIC_LIB) | ||
if(BUILD_SHARED_LIBS) | ||
set(DJINNI_STATIC_LIB OFF) | ||
else() | ||
set(DJINNI_STATIC_LIB ON) | ||
endif() | ||
endif() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I decided to go down another path than what we discussed in slack to resolve #23. It was a priority for me to not break existing setups. And because the variable DJINNI_STATIC_LIB
is used twice in the configuration of the target, it has to be set anyways. That's why it seemed the easiest solution to just set it according to BUILD_SHARED_LIB
if undefined. This does not use the default CMake mechanism when defining the target, but simulates it.
What do you think about that? I have mixed feelings. The downside of this is that it introduces additional complexity. Reducing complexity would only be possible by introducing a breaking change. I think I have at least figured out a solution that introduces as little additional code as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw do you know why the ObjC flavor of the lib is only linked to the Foundation framework if built as shared lib?
if (NOT DJINNI_STATIC_LIB)
target_link_libraries(djinni_support_lib
"-framework Foundation"
)
endif()
The only explanation that I have is: "If this is a static lib the library that will link to this will most likely link the Foundation framework anyways. So screw it here."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what you suggested on slack, second way, is the best solution.
If it breaks things, lets break it (with a new version number).
Complexity kills, especially if it is not required, and this is not required since it gives us no great functionality.
For a project like that , where people drop out and in, and you might have a breaks between reading the code where you lose the context, readability and maintainability must be the number 1 priority.
--
If you have a static lib and use it, yourself needs to link against foundation yourself
Your app will only take from the static lib what it needs, and embed it.
If you use a dynamic library nothing gets embedded into your app, it just says I need these symbols and expect them to be found at runtime. The dynamic library does the same with an other dynamic lib it depends on.
But a static library does/can not do that, it says, if you use me, I expect you to provide the external symbol, either via an other static library at link time (than pls get the link order right) or at runtime via an other dynamic library
…e DJINNI_LIBRARY_TYPE
…tic library will always be linked to a shared library.
Thanks for the cmake simplification! |
…d & JNI_OnUnload are now part of the public library interface. This means any user can include them in his sources to be able to use the default implementation. djinni-generator v1.0.0 will support this approach by automatically generating a file that includes the JNI_OnLoad implementation from the support-lib.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This got out of hand pretty quickly... 🙈
With the new commit I am trying to address the problem that we discussed in slack in the past days: How should the user include/implement a default JNI_OnLoad
and JNI_OnUnload
implementation.
I realized that this is an issue when I tried to make the Java tests link to the support-lib defined by cmake instead of globbing for the source files.
My strategy is the following:
djinni_jni_main.h
is a header file that implements JNI_OnLoad
and JNI_OnUnload
. It is part of the djinni-support-lib ABI. If a user links a static support-lib, he can include the header file himself to make use of the default JNI_OnLoad
and JNI_OnUnload
implementation.
To make things easier for the end-user, this PR is complemented by changes in the generator: cross-language-cpp/djinni-generator#49
All of these changes will most likely break some existing setups, thats why I think this is the right time to introduce v1.0.0 for both the generator & support-lib.
// limitations under the License. | ||
// | ||
|
||
#include "djinni_jni_main.hpp" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new files only purpose is to inclued the JNI_OnLoad
implementation from djinni_jni_main.hpp
.
// This provides a minimal JNI_OnLoad and JNI_OnUnload implementation. | ||
// Don't include it if your library does require a custom JNI_OnLoad implementation with custom initialization logic. | ||
#pragma once |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've transformed djinni_main.cpp
to a header file. That way anybody can include it and get the JNI_OnLoad
implementation. This only works if the header is included once. Otherwise the linker will complain.
This is expected to fail for JNI. It requires changes in the djinni-generator to work. |
#include "djinni/proxy_cache_interface.hpp" | ||
#include "djinni/djinni_common.hpp" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! I see ..
in include directives as a smell (even though we had some weird stuff in my previous PRs 😅)
…Otherwise both would generate a main file & which would result in colliding filenames/symbols
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, great work!
…ib into update_conan_install_instructions
v0.1.0 is not yet available in conan-center-index but I am working on it. This PR updates the documentation according to the new configuration options that will be added in the new version.This PR has been repurposed to propose a solution for the problem that we are currently discussing regarding
JNI_OnLoad
. Sry for the chaos! 🙈This needs further discussion. All things not relevant to this change have been moved to #27