Ah, I forgot to mention, but the visibility rules are different for libraries than they are for executables (for better or for worse).
An executable only has reachable C functions exported. I don't think statics are exported, but that's arguably a bug. Libraries, however, have all functions/symbols exported. If you're building an application which is invoked primarily through some other binding, I'd recommend using a staticlib output rather than an executable output (and just using the object file). This is primarily what staticlibs exist for. On Wed, Apr 30, 2014 at 10:41 AM, Vladimir Pouzanov <[email protected]> wrote: > Ok, seems that I found a reasonably good solution. > > The "app" is now an rlib, and the actual staticlib app that gets linked is a > wrapper, that sources all external crates and re-exports required symbols > like this: > > #[no_split_stack] > #[no_mangle] > #[start] > pub extern fn main() { > app::main(); > } > > I also had to move __STACK_LIMIT into external C file, as I couldn't define > it as external in one crate and provide it in another crate down the chain. > > > On Wed, Apr 30, 2014 at 5:29 PM, Vladimir Pouzanov <[email protected]> > wrote: >> >> Right, so I have a publicly reachable symbol __STACK_LIMIT inside my >> libzinc rlib: >> >> #[no_mangle] >> pub static mut __STACK_LIMIT: u32 = 0; >> >> which is present in rlib's object file: >> >> % arm-none-eabi-nm zinc.o|grep __STACK_LIMIT >> 00000000 B __STACK_LIMIT >> >> Now, I compile my application, which is a staticlib, emiting an obj (I >> could change staticlib to binary, that doesn't really change anything at >> this emit level): >> >> rustc -Z no-landing-pads -C relocation_model=static --target >> thumbv7m-linux-eabi -Ctarget-cpu=cortex-m3 --opt-level 2 -Z lto --emit obj >> -L ./build -o ./build/intermediate/app.o ./apps/app_sched.rs >> >> Which implicitly links to libzinc-de5e5c68-0.0.rlib. >> >> Given the lto nature, ./build/intermediate/app.o will contain all the >> required code from libzinc (and libcore), so I proceed to linker: >> >> arm-none-eabi-ld -Map ./build/zinc.map -o ./build/zinc.elf -T >> ./src/hal/lpc17xx/layout.ld ./build/intermediate/app.o >> -L/opt/gcc-arm-none-eabi-4_7-2013q3/lib/gcc/arm-none-eabi/4.7.4/armv7-m >> --gc-sections -lgcc >> >> Which fails due to "undefined reference to `__STACK_LIMIT'", as the lto >> step didn't keep the __STACK_LIMIT (which is, along with __morestack, used >> implicitly). >> >> I have the same problem with ISRs that re defined in libzinc. For now, I >> make trampolines in the app code: >> >> #[no_mangle] >> #[inline(never)] >> #[no_split_stack] >> pub unsafe fn task_scheduler() { >> task::task_scheduler(); >> } >> >> that look bad, but I don't yet know a better way to do it. >> >> I cannot move __STACK_LIMIT or __morestack in a dedicated object file and >> pass it to linker, as those depend on libzinc which isn't reaching the >> linker explicitly. >> >> >> On Wed, Apr 30, 2014 at 5:17 PM, Alex Crichton <[email protected]> wrote: >>> >>> In an rlib, all publicly reachable symbols will be exported from the >>> object, for example: >>> >>> >>> mod foo { pub static BAR: int = 3; } >>> >>> That symbol is not exported because BAR is not reachable from the outside >>> world. >>> >>> pub use foo::BAR; >>> mod foo { pub static BAR: int = 3; } >>> >>> This time, BAR will be an exported symbol because it is publicly >>> reachable (you could also make 'foo' public). >>> >>> Would that help your use case, or are you thinking of something more >>> complex? >>> >>> On Wed, Apr 30, 2014 at 6:49 AM, Vladimir Pouzanov <[email protected]> >>> wrote: >>> > I have the following setup: >>> > >>> > libzinc, compiles as rlib, provides all the stuff >>> > support, compiles as obj, provides __morestack, memset/memcpy and >>> > other >>> > required things >>> > libapp, compiles as staticlib emitting obj, depends on libzinc, >>> > builds >>> > with lto. >>> > >>> > I link libapp.o and support.o to get the final binary. >>> > >>> > Now, to make multitasking work, I need to move __morestack into >>> > libzinc, so >>> > that I can access task API from the function. The problem is that >>> > publicly >>> > visible __morestack in libzinc is not visible from libapp, which >>> > requires it >>> > implicitly via function prologues. Other static symbols (like >>> > __STACK_LIMIT) >>> > are not available as well. >>> > >>> > Is there any way to promote the visibility of symbols from libzinc to >>> > libapp >>> > in this case? >>> > >>> > -- >>> > Sincerely, >>> > Vladimir "Farcaller" Pouzanov >>> > http://farcaller.net/ >>> > >>> > _______________________________________________ >>> > Rust-dev mailing list >>> > [email protected] >>> > https://mail.mozilla.org/listinfo/rust-dev >>> > >> >> >> >> >> -- >> Sincerely, >> Vladimir "Farcaller" Pouzanov >> http://farcaller.net/ > > > > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ _______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
