Skip to content
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

stdenv: principial linking problems when putting static and dynamic libraries into different directories #12085

Open
vcunat opened this issue Jan 2, 2016 · 11 comments
Labels
0.kind: question 1.severity: mass-rebuild 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md 6.topic: closure-size

Comments

@vcunat
Copy link
Member

vcunat commented Jan 2, 2016

I've recently been digging into link errors introduced by splitting outputs, and there's a general problem for which I don't see any easy solution (yet). It again stems from assumptions that stuff is in the same directory, in particular static and dynamic version of the same library.

When linking, ld checks directories specified by -L in order and prefers dynamic libs by default, but it does so in each folder separately, therefore when dynamic and static versions are separate, the preference is "given" by directory order.

The order isn't very easy to affect. For example gcc also passes ${stdenv.cc.cc.out}/lib by itself which currently contains some static libraries whose dynamic versions are split into a different output. Example: https://gist.github.com/vcunat/8e5d56eb4e5cf4a80944. I this case it wasn't possible to link against those libs, but I'm afraid there may be many hidden cases where static libraries were preferred unintentionally. Therefore I'd like to find a general solution instead of fixing up particular cases.

Any ideas? In the worst case we could patch ld to first search all dirs for dynamic version before trying static.

@lucabrunox
Copy link
Contributor

Ok so if .a and .so are in the same directory it works. If they are in different directories it doesn't work.

However rather than only a simple assumption, it's also a good practical assumption. From an ld implementation view point, it would be a little hard to "merge" directories trying to find a proper order between .a and .so of the same library.

A possibility is the following, it's a little more disk expensive but might work: drv1 has only .so, drv2 has both .a and .so. That should solve the problem for dynamic, and well for static you have to fix a little the build process.

@vcunat
Copy link
Member Author

vcunat commented Jan 2, 2016

That would work, but it would link against paths that contain both *.a and *.so, which would defeat the purpose of splitting the outputs. Link scripts might be usable instead of symlinks; maybe that will be the easiest way in the end.

There's also libtool which explicitly requires both *.a and *.so be in the same directory, so it seems a good idea to approach it from that side.

@vcunat
Copy link
Member Author

vcunat commented Jan 8, 2016

So, linker scripts do allow to have a file containing INPUT(/path/to/something/to/link), but they don't solve this problem, unfortunately. When I do this with gcc, the linker leaves path to the script in RPATH which fails on any run attempt (or ldd). Apparently this won't work for stuff found by -lfoo, only by adding files to be linked explicitly.

Now I'm thinking of patching ld to resolve symlinks, i.e. link against the canonized paths of libraries. Then that symlink approach should work. Also we could auto-symlink $dev/lib/* -> $lib/lib/* and thus avoid lots of errors, as not specifying the output would lead to extra retained runtime dependencies instead of errors.

@vcunat
Copy link
Member Author

vcunat commented Jan 10, 2016

Oh, the code in ld seems far messier than our nix's c++, for example. I'm giving up on that for now.

As long as people don't mess with default flags or search order, the dynamic ones come first in -L arguments (at least for gcc) and there's no problem. Even forcing static libs works, e.g. just by -static-libstdc++, because it rejects any dynamic libs while searching and finds static ones in further search paths.

vcunat added a commit that referenced this issue Jan 20, 2016
The extra flag was causing static libraries to be found (and used)
before dynamic ones. /cc #12085
@Profpatsch
Copy link
Member

(triage) Is this still an ongoing thing?

@vcunat
Copy link
Member Author

vcunat commented Aug 18, 2016

My last comment still holds AFAIK. It seems it doesn't get into our way as much as I assumed when first submitting the issue.

@cleverca22
Copy link
Contributor

2 random ideas i had

  • symlink the .so from ${static}/lib/ so you can put just the static output in -L and get both
  • buildEnv all of the inputs into a single path?

@CMCDragonkai
Copy link
Member

CMCDragonkai commented Sep 2, 2017

Emscripten also only produces static archives, except its archives are meant to be .bc, naming them .a confuses things. Right now the current emscripten toolchain on nixpkgs puts its output as .a in the static directories. #16208

@stale
Copy link

stale bot commented Jun 5, 2020

Thank you for your contributions.

This has been automatically marked as stale because it has had no activity for 180 days.

If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity.

Here are suggestions that might help resolve this more quickly:

  1. Search for maintainers and people that previously touched the related code and @ mention them in a comment.
  2. Ask on the NixOS Discourse.
  3. Ask on the #nixos channel on irc.freenode.net.

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jun 5, 2020
@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/how-to-get-this-basic-c-build-to-work-in-a-nix-shell/12262/4

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Apr 3, 2021
@stale
Copy link

stale bot commented Oct 1, 2021

I marked this as stale due to inactivity. → More info

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Oct 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.kind: question 1.severity: mass-rebuild 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md 6.topic: closure-size
Projects
None yet
Development

No branches or pull requests

6 participants