Closed saikyun closed 1 year ago
Oh, maybe a bit more work is needed for static builds to work. I tried a bit but couldn't quite figure out what went wrong.
Is there something special needed in order to link .a-files when doing a static build?
Den lör 11 feb. 2023 16:47Calvin Rose @.***> skrev:
Merged #66 https://github.com/janet-lang/jpm/pull/66 into master.
— Reply to this email directly, view it on GitHub https://github.com/janet-lang/jpm/pull/66#event-8496813963, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAS46Z3RRSZW6ETEL3L44XLWW6YCFANCNFSM6AAAAAAUH5PEDE . You are receiving this because you authored the thread.Message ID: @.***>
Okay, so what I'm finding is something like this: If I try to link with raylib.a when doing the static build, I get an error like this when trying to compile an exe using that jaylib:
linking build/test_build...
ld: in build/freja-jaylib.a(raylib.a), archive member 'raylib.a' with length 2181616 is not mach-o or llvm bitcode file 'build/freja-jaylib.a' for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I looked closer at how linking is done normally, and it seems that only .o-files are linked. I tried linking all the .o-files instead of the single .a-file, and now it works.
The question then is if there's a concise way of expressing "I want all the .o-files of this other native module". I guess I could store all the paths to the .o-files in the result of declare-native
, and use that in the second declare-native
. But it feels kinda messy.
Perhaps try adding a flag like "-l:raylib.a" to lflags?
More to the point, in most cases jpm isn't designed for the way you are trying to link things - what you should have are dynamic libraries for raylib, and dynamic libraries for freja. When a user then uses create executable to finally using freja (and there for raylib by dependency), static versions of both libraries, along with any other user code, should be compiled together into one big executable. There is no benefit (that I can think of off hand) for having a dynamic library that has a static library bundled inside it.
Aha, I see. I'll take another look. I have just recently understood what linkers do, so the subtleties between static / dynamic linking in multiple steps are beyond me. Thanks for giving me more clues. :)
So I'm noticing that default executables on linux created by (create-executable ...)
do not have -rdynamic passed, meaning that they cannot themselves easily import dynamic libraries. You can change this adding -rdynamic
to :lflags if the system is linux. I believe that may help your original use case for freja (a bundled executable that can load other janet native modules).
Ah, yeah, I am using that flag. I think you gave me that tip over a year ago. :D
Linking with raylib.a
made it possible to build the .exe, so thanks for that. :)
Just so we aren't talking past each other, when building (vanilla) jaylib, and using the jaylib.so
by (use jaylib)
, do you mean that it in turn loads raylib.so
rather than raylib.a
? And when I build an executable from the same source, it will instead use jaylib.a
and raylib.a
?
EDIT: Wait, nevermind, I see now that regular jaylib never ends up with a raylib.a/.so.
Only reason I'm trying what I'm trying is to split the build steps between "building raylib" and "building jaylib" so that raylib doesn't need to be rebuilt each time. I don't mind if it ends up with only jaylib.a/.so. :)
I just noticed that when modifying files in (vanilla) jaylib it acts as I want if I only modify files in :source
, it's when I modify files in :headers
that it recompiles all of raylib as well.
I just noticed that when modifying files in (vanilla) jaylib it acts as I want if I only modify files in
:source
, it's when I modify files in:headers
that it recompiles all of raylib as well.
Yes, jpm will make each source file depend on all headers, rather than trying to determine which source file imports which headers.
Okay. Is improving the incremental build time in those cases something that you'd be interested in having?
A couple of weeks ago I tried doing something using clang -MM
which figures out local includes. It worked well with my limited testing: https://github.com/saikyun/jpm/blob/eef7ae1f9aeee40b730b44253ef3ec9a56645378/jpm/cc.janet#L101-L113
Not sure if a similar thing exists for cl. And maybe it's just too flaky overall.
I wanted to ask if something like this makes sense, because it allows a project file like this: https://github.com/saikyun/freja-jaylib/blob/test-deps/project.janet
The main idea is that I can have raylib be compiled, and added as a dependency to (freja-)jaylib. This way people won't have to recompile raylib each time jaylib is modified.
Only missing thing in jpm is linking the .a-file, so I added the
:objects
-key.I've only tried on macOS, but should work for linux. For the sake of windows, perhaps
declare-native
/:objects
should deal with using the right suffix. I'm also guessing that for static builds the extra:objects
would be needed as well.What do you think @bakpakin? :) Should I continue in this direction, and make sure it works on windows & with static builds as well, or is there a better way to do this?