Build Yoga 2.0 as a shared library (partial implementation). #1341
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
I need to build Yoga as a shared library so that I can create C# bindings using p/invoke. Below is the updated CMakeLists.txt file for the 'yoga' directory. It includes an option to build Yoga as a shared library. Please note that although it successfully builds Yoga as a working shared library, it still throws an error. I suspect the issue is with yogatest trying to build against the Yoga static library. Any help with working on this would be greatly appreciated.
Error
yoga/CMakeLists.txt
It’s hard to tell what the issue is with the limited error output.
Instead of changing yogacore to be either a shared or static library, it might be easier to link the static library into a new shared library. As a reference, the JNI bindings do just this, and link in some more code which is binding specific to a final libyoga.so. https://github.com/facebook/yoga/blob/main/java/CMakeLists.txt.
I was able to get this buy using
make VERBOSE=1
and it looks like a linking error related to the undefined reference toYGFloatOptionalMax(YGFloatOptional, YGFloatOptional)
I found the following entry in the shared library:
by executing nm libyogacore.so > shared_symbols.txt. According to the documentation for the nm command, the t indicates that this symbol is in the text (code) section of the shared library and has local linkage. This means that the symbol is not visible outside the shared library itself, explaining the undefined reference error I encountered when linking against it in yogatests.
I found the problem in the Utils.h file on line 72. I changed this code:
to:
Now everything builds correctly. I would really appreciate it if the Yoga developers could conduct their testing, and possibly include an option to build a shared library in a future release.
I just realized we are neighbors; I am in Bremerton, WA. ;)
I should also note that what I did, I believe, only works when building using the GCC compiler, maybe LLVM, but I'm not sure. A solution that works for all supported compilers would probably look different than what I did above. When I have time, I'll look into Windows and MacOS (Intel), but mobile and Apple Silicon are beyond my capabilities. But the above at-least works on Linux.
Utils.h
There are macros like
YG_EXPORT
for defining what functions should be exported out of a shared library. Though it seems like unit tests are potentially poking at Yoga internals. I think it is reasonable that the unit tests are able to access APIs we would ideally not export from the library boundary. I.e. I think it might best to keep GTest binary statically linked to Yoga.As far as I can tell from scanning the code base, there is no YG_EXPORT already defined, so it would need to be created. Regarding the decision to keep the GTest binary statically linked, I completely disagree. The simple fact is that it doesn't matter either way because GTest isn't getting deployed to the end user, and it serves no other purpose outside of testing the API.
Oh, it looks like the export macros are
YOGA_EXPORT
andWIN_EXPORT
. I don't see why these are separate right now on first glance. These also break the convention of the other macros starting withYG_
https://github.com/facebook/yoga/blob/main/yoga/YGMacros.hThe downside of dynamically linking GTest, apart from just the added build config, is that it means anything the UT consumes must be exported from Yoga. This means we need to expose functions in the export table, that were previously considered private. Though if there aren't too many extra exports, and they are safe to be public, I think we could add them.
Thanks for pointing that out. It's crazy that I missed YGMacros.h and ...
I made the following modification to Utils.h, which resulted in everything functioning correctly on Linux and MacOS. However, when attempting to build the shared library on Windows 10 using CMake and Visual Studio 2022, an error arises during the yogatest building stage.
Utils.h
https://github.com/facebook/yoga/issues/1341#issue-1840538142
Hi @NickGerleman,
Disclaimer: I am (almost) absolutely a beginner in the JNI/cmake/C++, every action described below was an act of monkey typing, cope-paste and googling.
My idea is to execute java unit tests with Yoga as a native library. I aim to create a JAR file with an embedded binary that is compatible with Linux. I've attempted to achieve this by running commands from workflow, on a virtual machine running Ubuntu. (It's important to note that I've installed necessary tools such as Ninja, CMake, etc., and the unit tests and benchmarks execute correctly.)
For building the binary, I utilized the CMakeLists.txt from the Java directory. I made modifications (basing on
v2.0.1
) to the CMakeLists.txt to exclude Android NDK stuff (liblog.so - minor issue because android-liblog package, libm.so - not found workaround for it) . I have addedfind_package(JNI REQUIRED)
,include_directories(${JNI_INCLUDE_DIRS})
and turn off-Werror
(I should not)I based on v2.0.1, repo was cloned to dir named
facebook
Next I run cmake commands:
getting some warning (more than I paste here, but all of them looks similar):
But I got my
libyoga.so
(smaller than expected, around 150KB, android version was ~500KB), because when I run simple code like this:App blows up (surprise):
So, I must do something wrong, that's for sure. Maybe there is something extra done by android NDK? Maybe C++ standard is wrong? Please give me some clue.
Ps. I also tried the same steps on macos where I got different errors :/
Small update. I have find out that my
jar
should contain java sources, becausefacebook::yoga::vanillajni::registerNatives
looks for them. When I added wholecom.facebook....
package, it started working (yupi).I still have those scary warnings on linux (and compile errors on mac), so if you have any advice about env configuration please tell.