devkitPro / wut-tools

GNU General Public License v2.0
11 stars 12 forks source link

rplimportgen: Add support for placing all imports into a single section #4

Closed Maschell closed 4 years ago

Maschell commented 4 years ago

By default rplimportgen is creating one section for each import, during linking they are merged back into a single section. This works fine for predictable imports (system .rpls) but all of them have to be explictly added to the *.ld file [of wut].

Currently it's impossible use any other .rpl's than the ones explictly mentioned in the wut .ld file, this is a (hacky) attempt to solve this issue. Normally I would've gone for the inverted logic, but this way the compatibility with existing tools is still provided. This PR is adding a optional argument to rplimportgen to force placing all import into a single section, the default will still be one section for each import.

If someone has another (better?) idea on how to solve this issue I would be happy to close this PR.

exjam commented 4 years ago

It might be better to using a whitelist of RPLs so that for all RPLs defined in the .ld linker file (aka all system RPLs) it uses separate sections, anything else is squished ?

ashquarky commented 4 years ago

Isn't it possible to provide supplementary linker scripts in an app's LDFLAGS? iirc if you don't use -T link.ld and instead just give supplementary.ld it Just Works™. Don't hold me to that though.

exjam commented 4 years ago

I don't think it is ideal to make everyone who wants to import non-system RPLs use a linker script

exjam commented 4 years ago

So for each user .rpl we also need to generate a static library .a with rplimportgen and a .ld linker script.

For example, let's say we have two RPL files, app.rpx and my_first_rpl.rpl, and app.rpx imports functions from my_first_rpl.rpl.

Right now my_first_rpl.rpl is created with .fexports/.dexports sections being generated using rplexportgen. We need to add a build step which also runs rplimportsgen and builds a .a static library from that, and also generates a linker script.

Then when building app.rpx it needs to link against the generated static library my_first_rpl.a, and also the linker script my_first_rpl.ld

Example my_first_rpl.ld:

SECTIONS
{
   .fimport_my_first_rpl ALIGN(16) : {
      KEEP ( *(.fimport_my_first_rpl) )
      *(.fimport_my_first_rpl.*)
   } > loadmem

   .dimport_my_first_rpl ALIGN(16) : {
      KEEP ( *(.dimport_my_first_rpl) )
      *(.dimport_my_first_rpl.*)
   } > loadmem
}

I am unsure how to best express this in CMake, currently we have add_executable(app ...), add_executable(my_first_rpl ...), so you'd expect to be able to do target_link_libraries(app my_first_rpl) however that will not work because

  1. we use CMake's add_executable even for a .rpl file which is technically a shared library - which should be add_library(my_first_rpl SHARED),
  2. Because we need to generate the .rpl file and a matching .a file then you end up with 2 targets which cannot have the same name.
  3. You need to link the linker script still

Maybe we could just use a custom command wut_target_link_rpl - we already use wut_add_exports to add the export section so in that function we could add_library(${target}_rpl_imports) and then in wut_target_link_rpl it does target_link_libraries(${target} ${lib}_rpl_imports ${lib}_rpl_imports.ld) or something. Would need to play around with it.

No clue how you would do it in Makefile land ... :)

WinterMute commented 4 years ago

You'd just add it to your LDFLAGS in Makefile land ...

Personally I'd probably look at providing a .pc file for pkg-config

exjam commented 4 years ago

https://github.com/devkitPro/wut-tools/pull/5 https://github.com/devkitPro/wut/pull/141