Skip to content
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

added :objects option to declare-native #66

Merged
merged 1 commit into from
Feb 11, 2023

Conversation

saikyun
Copy link
Contributor

@saikyun saikyun commented Jan 26, 2023

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?

@bakpakin bakpakin merged commit 492def9 into janet-lang:master Feb 11, 2023
@saikyun
Copy link
Contributor Author

saikyun commented Feb 11, 2023 via email

@saikyun
Copy link
Contributor Author

saikyun commented Feb 11, 2023

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.

@bakpakin
Copy link
Member

Perhaps try adding a flag like "-l:raylib.a" to lflags?

@bakpakin
Copy link
Member

bakpakin commented Feb 11, 2023

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.

@saikyun
Copy link
Contributor Author

saikyun commented Feb 11, 2023

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. :)

@bakpakin
Copy link
Member

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).

@saikyun
Copy link
Contributor Author

saikyun commented Feb 11, 2023

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. :)

@saikyun
Copy link
Contributor Author

saikyun commented Feb 11, 2023

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.

@bakpakin
Copy link
Member

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.

@saikyun
Copy link
Contributor Author

saikyun commented Feb 12, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants