Hacker News new | ask | show | jobs
by dzaima 335 days ago
How possible would it be to have a utility that merges multiple .o files (or equivalently a .a file) into one .o file, via changing all hidden symbols to local ones (i.e. alike C's "static")? Would solve the private symbols leaking out, and give a single object file that's guaranteed to link as a whole. Or would that break too many assumptions made by other things?
4 comments

Like, a linker, with "objcopy --strip-symbols" run as the post-step? I believe you can do this even today.
--localize-hidden seems to be more what I was thinking of. So this works:

    ld --relocatable --whole-archive crappy-regular-static-archive.a -o merged.o
    objcopy --localize-hidden merged.o merged.o
This should (?) then solve most issues in the article, except that including the same library twice still results in an error.
I did this with my dependencies for my game engine. Built them all as libs and used linker to merge them all together. Makes building my codebase as easy as -llibutils
It seems like is precisely what the other commenter implemented? https://news.ycombinator.com/item?id=44645423
I routinely tear apart badly laid-out .a files and re-ar them into something useful. It's a few lines of bash.
This works, but scripting with the ar tool is annoying because it doesn't handle all the edge cases of the .a format.

For instance if two libraries have a source file foo.c with the same name, you can end up with two foo.o, and when you extract they override each other. So you might think to rename them, but actually this nonsense can happen with two foo.o objects in the same archive.

The errors you get when running into these are not fun to debug.

This is the nastiest one in my `libmodern-cpp` suite: https://gist.github.com/b7r6/31a055e890eaaa9e09b260358da897b....

It took a few minutes, probably has a few edge cases I haven't banged out yet, and now I get to `-l` and I can deploy with `rsync` instead of fucking Docker or something.

I take that deal.

`boost` is a little sticky too: https://gist.github.com/b7r6/e9d56c0f6d55bc0620b2ce190e15d44...

but for your trouble: https://gist.github.com/b7r6/0cc4248e24288551bcc06281c831148...

If there's interest in this I can make a priority out of trying to get it open-sourced.

Yes, boost is one of those that gave me the biggest trouble as well.

I feel like we really need better toolchains in the first place. None of this intrinsically needs to be made complex, it's all a lack of proper support in the standard tools.

It's not though, as you can see from building two of the most notoriously nasty libraries on God's earth, emitting reasonable `pkg-config` is trivial, it's string concatenation.

The problem is misaligned incentives: CMake is bad, but it was sort of in the right place at the right time and became a semi-standard, and it's not in the interests of people who work in the CMake ecosystem to emit correct standard artifact manifests.

Dynamic linking by default is bad, but the gravy train on that runs from Docker to AWS to insecure-by-design TLS libraries.

The fix is for a few people who care more about good computing than money or fame to do simple shit like I'm doing above and make it available. CMake will be very useful in destroying CMake: it already encodes the same information that correct `pkg-config` needs.