about summary refs log tree commit diff
path: root/lib/systems
diff options
context:
space:
mode:
authorAdam Joseph <adam@westernsemico.com>2023-06-28 23:49:38 -0700
committerAdam Joseph <adam@westernsemico.com>2023-07-01 13:12:22 -0700
commit6980e6b35aacccd4e75a76a384f9dec30f31fa55 (patch)
tree7ddf8b1f5713c69b3596650a24711c6bcf83f159 /lib/systems
parent931b8a4979df477c0baffc2544f593d7a9b32dcb (diff)
lib.systems: introduce hasSharedLibraries
This commit adds `hasSharedLibraries` to `lib.systems`.

We need `plat.hasSharedLibraries` in order to know whether or not to
expect `gcc` (and many other tools) to emit shared libraries (like
`libgcc_s.so`).  Many of the GNU build scripts are smart enough that
if you configure them with `--enable-shared` on a platform (such as
`arm-none-eabi`) that doesn't support dynamic linking, they will
simply skip the shared libraries instead of aborting the
`configurePhase`.  Unfortunately the missing shared libraries in the
final build product cause very hard-to-troubleshoot problems later
on.

The alternative to introducing `hasSharedLibraries` would be to set
`isStatic` in these situations.  However doing so causes
`make-derivation.nix` to insert `-static` between the `pname` and
`hostPlatform` suffix, which is undesirable.

If at some point in the future we eliminate the `-static` suffix,
then `hasSharedLibraries` can be made equal to `!isStatic`.
Diffstat (limited to 'lib/systems')
-rw-r--r--lib/systems/default.nix21
1 files changed, 20 insertions, 1 deletions
diff --git a/lib/systems/default.nix b/lib/systems/default.nix
index 78ccd50ba79a5..a3462d2d424b2 100644
--- a/lib/systems/default.nix
+++ b/lib/systems/default.nix
@@ -86,7 +86,7 @@ rec {
         # choice.
         else                                     "bfd";
       extensions = rec {
-        sharedLibrary =
+        sharedLibrary = assert final.hasSharedLibraries;
           /**/ if final.isDarwin  then ".dylib"
           else if final.isWindows then ".dll"
           else                         ".so";
@@ -132,6 +132,25 @@ rec {
          # uname -r
          release = null;
       };
+
+      # It is important that hasSharedLibraries==false when the platform has no
+      # dynamic library loader.  Various tools (including the gcc build system)
+      # have knowledge of which platforms are incapable of dynamic linking, and
+      # will still build on/for those platforms with --enable-shared, but simply
+      # omit any `.so` build products such as libgcc_s.so.  When that happens,
+      # it causes hard-to-troubleshoot build failures.
+      hasSharedLibraries = with final;
+        (isAndroid || isGnu || isMusl                                  # Linux (allows multiple libcs)
+         || isDarwin || isSunOS || isOpenBSD || isFreeBSD || isNetBSD  # BSDs
+         || isCygwin || isMinGW                                        # Windows
+        ) && !isStatic;
+
+      # The difference between `isStatic` and `hasSharedLibraries` is mainly the
+      # addition of the `staticMarker` (see make-derivation.nix).  Some
+      # platforms, like embedded machines without a libc (e.g. arm-none-eabi)
+      # don't support dynamic linking, but don't get the `staticMarker`.
+      # `pkgsStatic` sets `isStatic=true`, so `pkgsStatic.hostPlatform` always
+      # has the `staticMarker`.
       isStatic = final.isWasm || final.isRedox;
 
       # Just a guess, based on `system`