-
Notifications
You must be signed in to change notification settings - Fork 496
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
feat: support build and link dynamic library #1444
base: main
Are you sure you want to change the base?
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.
Thank you!
There are two places where I would like to see some changes
src/lib.rs
Outdated
if self.link_shared_flag { | ||
let objects = objects.iter().map(|o| o.dst.clone()).collect::<Vec<_>>(); | ||
|
||
let mut command = self.try_get_compiler()?.to_command(); | ||
let cmd = command | ||
.args(["-shared", "-o"]) | ||
.arg(dst.join(dynlib_name)) | ||
.args(&objects); | ||
run(cmd, &self.cargo_output)?; | ||
} | ||
|
||
self.assemble(lib_name, &dst.join(static_name), &objects)?; |
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 we don't need to run assemble if it's already dynamically linked?
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.
Should we consider support dll
on windows
?
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 we don't need to run assemble if it's already dynamically linked?
Sure, fixed.
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.
Should we consider support
dll
onwindows
?
Can you elaborate on that please?
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.
Windows ddl
is complicated, i have not idea how to add a dynamic library test case for it. It's weird as cl.exe
require a main
function to build a dll
library.
With this source file, it will cause a Entry Point Not Found
error
#include <windows.h>
void msvc() {}
Test pass if add a main
function
#include <windows.h>
void msvc() {}
void main() {}
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.
Thanks for explanation, I'm ok with it not tested, if you have time to add another test for it I would greatly appreciate
f9dead6
to
f9e4a70
Compare
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.
Thanks LGTM!
cc @madsmtm can you review this PR please?
/// Configure whether cc should build dynamic library and link with `rustc-link-lib=dylib` | ||
/// | ||
/// This option defaults to `false`. | ||
pub fn link_shared_flag(&mut self, link_shared_flag: bool) -> &mut Build { |
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.
When reading this as a user, it is not really clear how this differs from shared_flag
.
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.
Stated another way: When would you ever want shared_flag(true)
but not link_shared_flag(true)
? And vice-versa?
/// Configures the output directory where shared library will be located. | ||
/// | ||
/// This option defaults to `out_dir`. | ||
pub fn shared_lib_out_dir<P: AsRef<Path>>(&mut self, out_dir: P) -> &mut Build { | ||
self.shared_lib_out_dir = Some(out_dir.as_ref().into()); | ||
self | ||
} |
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'm against adding this, I think the user should copy it from out_dir
if they want the final shared library to be placed elsewhere.
In general, I'm a bit inclined to think that
|
Should I close this PR and use another crate to support dynamic linking? The purpose of submitting this commit was to implement a C/C++ UDF with Rust's compute engine. It's fine for me to just call a bash command in build.rs. |
Hmm, I guess I don't understand why that has to be dynamically linked?
We haven't actually decided to deprecate |
I think this is mostly an API issue, since it doesn't add a lot of code we just want the right API |
I had the same confusion before I forked cc-rs and read the code. For most users' expectations, shared_flag should behave like dynamic linking. However, currently, shared_flag only adds the -shared flag while still linking statically. Since I didn’t want to introduce a breaking change, I added the link_shared_flag function to properly support dynamic linking.
In our use case, we have C/C++ UDF code that changes frequently. Static linking isn’t ideal because users would need to download and update the entire binary every time the UDF code changes, which can be time-consuming.
This approach significantly reduces update overhead. |
I don't think this should really be seen as a breaking change, since Alternatively, we deprecate both
Thanks for the context. If we go forwards with this PR, would you mind adding something to this effect to the method documentation, as a use-case example? |
.target(&target) | ||
.host(&target) | ||
.target(target) | ||
.host(target) | ||
.file("foo.c") | ||
.compile("foo"); | ||
|
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.
Documentation on compile
should also be updated to reflect the new renaming rules.
.target(&target) | ||
.host(&target) | ||
.target(target) | ||
.host(target) | ||
.file("foo.c") | ||
.compile("foo"); | ||
|
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.
If we actually want to support shared libraries, we should consider a .linker
and .get_linker
similar to .archiver
and .get_archiver
, as well as maybe allowing overriding the linker with an LD
env var (?)
Though if we allow using a raw linker (e.g. invoke rust-lld
binary instead of cc
), we're getting into hairy territory of needing to know how to invoke the linker if it's not a compiler driver.
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.
(Which again is why I'm really not in favour of it).
Close shared_flag and static_flag don't work