Hello! I am compiling a existing library from source to be linked as a native module to another program.
That program requires a specific symbol to be defined.
I need something equivalent to objcopy --redefine-sym Alice=Bob my_lib.a.
I tried
the -D options is for the gcc front end, when invoke gcc as linker, the option will be parsed but has no effect.
unfortunately, I don't know if you can rename a symbol at link time, but I believe you can create aliases with a linker script, will that suffice your need?
for example, create a linker script to define the symbol Bob:
Bob = Alice;
then simply add the path of the linker script file to the linker command line as an input file:
rustflags = [ "-C", "link-arg=./bob.ld" ]
then a symbol named Bob should appear in the so file.
I created bob.ld in the root of the project and run cargo build again. I still can't find the new symbol.
To be more concrete I am trying to replace PyInit__pydantic_core with PyInit_anything when compiling GitHub - pydantic/pydantic-core: Core validation logic for pydantic written in rust with command cargo build --target=x86_64-unknown-linux-gnu -v. But no matter what I try the only symbol in lib_pydantic_core.so starting with PyInit is PyInit__pydantic_core.
Yeah, it works #[pyo3(name = "pydantic_core")]. But only with a valid identifier as a name. I need numbers after PyInit_ like PyInit_10something. In a sense that #[pyo3(name = "10something")] won't compile.
You may assign a value to a symbol in a linker script. This will define the symbol and place it into the symbol table with a global scope.
I'm at lost now. I don't know how to define a global symbol without modifying the source code. so I'd suggest just add a name option to the pymodule attribute macro, it is just easier than tinkering with the linker.
Thank you. It is a valid suggestion.
But in my case I need a name that is not a valid Rust identifier. In the end it would be valid with a prefix PyInit_, but at a compile time it is not valid.
in that case, maybe you can just define an "proxy" function which forwards to the procedurally generated entry point, something like this:
// declare the exported entry point which will be resolved at link type
extern "C" {
fn entry_point();
}
// define our "proxy" entry point
#[export_name = "another_entry_point"]
pub extern "C" fn proxy() {
unsafe {
entry_point()
}
}
// pseudo code for the procedural generated entry point
mod procedurally_generated {
#[export_name = "entry_point"]
pub extern "C" fn init() {
println!("hello, this is the entry point.");
}
}
it's not perfect, but it should work. and if you enable LTO, the symbols should point to the same address.