about summary refs log tree commit diff
diff options
context:
space:
mode:
authorArtturi <Artturin@artturin.com>2023-08-04 06:04:33 +0300
committerGitHub <noreply@github.com>2023-08-04 06:04:33 +0300
commit4055d18cccbc46ed1de2dffb820fdb8e20c6ad66 (patch)
tree6539071ee8c20f01680cd67380d21d6512660708
parent51606bc8c11c96cdbc2cfd1e85031a5b7357dd47 (diff)
parent0a05fbb9a010337454b942011bfa92168b2efc17 (diff)
Merge pull request #229265 from amjoseph-nixpkgs/pr/chromium/cross/all
-rw-r--r--pkgs/applications/networking/browsers/chromium/browser.nix2
-rw-r--r--pkgs/applications/networking/browsers/chromium/common.nix89
-rw-r--r--pkgs/applications/networking/browsers/chromium/cross-compile.patch31
-rw-r--r--pkgs/applications/networking/browsers/chromium/default.nix21
4 files changed, 133 insertions, 10 deletions
diff --git a/pkgs/applications/networking/browsers/chromium/browser.nix b/pkgs/applications/networking/browsers/chromium/browser.nix
index f943e3f12606a..1e203fc12e75b 100644
--- a/pkgs/applications/networking/browsers/chromium/browser.nix
+++ b/pkgs/applications/networking/browsers/chromium/browser.nix
@@ -6,7 +6,7 @@
 mkChromiumDerivation (base: rec {
   name = "chromium-browser";
   packageName = "chromium";
-  buildTargets = [ "mksnapshot" "chrome_sandbox" "chrome" ];
+  buildTargets = [ "run_mksnapshot_default" "chrome_sandbox" "chrome" ];
 
   outputs = ["out" "sandbox"];
 
diff --git a/pkgs/applications/networking/browsers/chromium/common.nix b/pkgs/applications/networking/browsers/chromium/common.nix
index 183a83f52e8b5..f555ab2893917 100644
--- a/pkgs/applications/networking/browsers/chromium/common.nix
+++ b/pkgs/applications/networking/browsers/chromium/common.nix
@@ -1,4 +1,7 @@
 { stdenv, lib, fetchurl, fetchpatch
+, buildPackages
+, pkgsBuildBuild
+, pkgsBuildTarget
 # Channel data:
 , channel, upstream-info
 # Helper functions:
@@ -8,8 +11,10 @@
 , ninja, pkg-config
 , python3, perl
 , which
-, llvmPackages
+, llvmPackages_attrName
 , rustc
+, libuuid
+, overrideCC
 # postPatch:
 , pkgsBuildHost
 # configurePhase:
@@ -116,6 +121,33 @@ let
     inherit (upstream-info.deps.ungoogled-patches) rev sha256;
   };
 
+  # There currently isn't a (much) more concise way to get a stdenv
+  # that uses lld as its linker without bootstrapping pkgsLLVM; see
+  # https://github.com/NixOS/nixpkgs/issues/142901
+  buildPlatformLlvmStdenv =
+    let
+      llvmPackages = pkgsBuildBuild.${llvmPackages_attrName};
+    in
+      overrideCC llvmPackages.stdenv
+        (llvmPackages.stdenv.cc.override {
+          inherit (llvmPackages) bintools;
+        });
+
+  chromiumRosettaStone = {
+    cpu = platform:
+      let name = platform.parsed.cpu.name;
+      in ({ "x86_64" = "x64";
+            "i686" = "x86";
+            "arm" = "arm";
+            "aarch64" = "arm64";
+          }.${platform.parsed.cpu.name}
+        or (throw "no chromium Rosetta Stone entry for cpu: ${name}"));
+    os = platform:
+      if platform.isLinux
+      then "linux"
+      else throw "no chromium Rosetta Stone entry for os: ${platform.config}";
+  };
+
   base = rec {
     pname = "${packageName}-unwrapped";
     inherit (upstream-info) version;
@@ -130,16 +162,35 @@ let
       ninja pkg-config
       python3WithPackages perl
       which
-      llvmPackages.bintools
+      buildPackages.${llvmPackages_attrName}.bintools
       bison gperf
     ];
 
+    depsBuildBuild = [
+      buildPlatformLlvmStdenv
+      buildPlatformLlvmStdenv.cc
+      pkg-config
+      libuuid
+      libpng # needed for "host/generate_colors_info"
+    ]
+    # When cross-compiling, chromium builds a huge proportion of its
+    # components for both the `buildPlatform` (which it calls
+    # `host`) as well as for the `hostPlatform` -- easily more than
+    # half of the dependencies are needed here.  To avoid having to
+    # maintain a separate list of buildPlatform-dependencies, we
+    # simply throw in the kitchen sink.
+    ++ buildInputs
+    ;
+
     buildInputs = [
       (libpng.override { apngSupport = false; }) # https://bugs.chromium.org/p/chromium/issues/detail?id=752403
       bzip2 flac speex opusWithCustomModes
       libevent expat libjpeg snappy
       libcap
-      xdg-utils minizip libwebp
+    ] ++ lib.optionals (!xdg-utils.meta.broken) [
+      xdg-utils
+    ] ++ [
+      minizip libwebp
       libusb1 re2
       ffmpeg libxslt libxml2
       nasm
@@ -162,6 +213,7 @@ let
       ++ lib.optional pulseSupport libpulseaudio;
 
     patches = [
+      ./cross-compile.patch
       # Optional patch to use SOURCE_DATE_EPOCH in compute_build_timestamp.py (should be upstreamed):
       ./patches/no-build-timestamps.patch
       # For bundling Widevine (DRM), might be replaceable via bundle_widevine_cdm=true in gnFlags:
@@ -225,6 +277,7 @@ let
           '/usr/share/locale/' \
           '${glibc}/share/locale/'
 
+    '' + lib.optionalString (!xdg-utils.meta.broken) ''
       sed -i -e 's@"\(#!\)\?.*xdg-@"\1${xdg-utils}/bin/xdg-@' \
         chrome/browser/shell_integration_linux.cc
 
@@ -268,9 +321,27 @@ let
       # weaken or disable security measures like sandboxing or ASLR):
       is_official_build = true;
       disable_fieldtrial_testing_config = true;
+
+      # note: chromium calls buildPlatform "host" and calls hostPlatform "target"
+      host_cpu      = chromiumRosettaStone.cpu stdenv.buildPlatform;
+      host_os       = chromiumRosettaStone.os  stdenv.buildPlatform;
+      target_cpu    = chromiumRosettaStone.cpu stdenv.hostPlatform;
+      v8_target_cpu = chromiumRosettaStone.cpu stdenv.hostPlatform;
+      target_os     = chromiumRosettaStone.os  stdenv.hostPlatform;
+
       # Build Chromium using the system toolchain (for Linux distributions):
+      #
+      # What you would expect to be caled "target_toolchain" is
+      # actually called either "default_toolchain" or "custom_toolchain",
+      # depending on which part of the codebase you are in; see:
+      # https://github.com/chromium/chromium/blob/d36462cc9279464395aea5e65d0893d76444a296/build/config/BUILDCONFIG.gn#L17-L44
       custom_toolchain = "//build/toolchain/linux/unbundle:default";
-      host_toolchain = "//build/toolchain/linux/unbundle:default";
+      host_toolchain = "//build/toolchain/linux/unbundle:host";
+      v8_snapshot_toolchain = "//build/toolchain/linux/unbundle:host";
+
+      host_pkg_config = "${pkgsBuildBuild.pkg-config}/bin/pkg-config";
+      pkg_config      = "${pkgsBuildHost.pkg-config}/bin/${stdenv.cc.targetPrefix}pkg-config";
+
       # Don't build against a sysroot image downloaded from Cloud Storage:
       use_sysroot = false;
       # Because we use a different toolchain / compiler version:
@@ -304,7 +375,7 @@ let
       rtc_use_pipewire = true;
       # Disable PGO because the profile data requires a newer compiler version (LLVM 14 isn't sufficient):
       chrome_pgo_phase = 0;
-      clang_base_path = "${llvmPackages.stdenv.cc}";
+      clang_base_path = "${pkgsBuildTarget.${llvmPackages_attrName}.stdenv.cc}";
       use_qt = false;
       # To fix the build as we don't provide libffi_pic.a
       # (ld.lld: error: unable to find library -l:libffi_pic.a):
@@ -313,6 +384,9 @@ let
       # We do intentionally not set rustc_version as nixpkgs will never do incremental
       # rebuilds, thus leaving this empty is fine.
       rust_sysroot_absolute = "${rustc}";
+    } // lib.optionalAttrs (!(stdenv.buildPlatform.canExecute stdenv.hostPlatform)) {
+      # https://www.mail-archive.com/v8-users@googlegroups.com/msg14528.html
+      arm_control_flow_integrity = "none";
     } // lib.optionalAttrs proprietaryCodecs {
       # enable support for the H.264 codec
       proprietary_codecs = true;
@@ -342,6 +416,11 @@ let
     # our Clang is always older than Chromium's and the build logs have a size
     # of approx. 25 MB without this option (and this saves e.g. 66 %).
     env.NIX_CFLAGS_COMPILE = "-Wno-unknown-warning-option";
+    env.BUILD_CC = "$CC_FOR_BUILD";
+    env.BUILD_CXX = "$CXX_FOR_BUILD";
+    env.BUILD_AR = "$AR_FOR_BUILD";
+    env.BUILD_NM = "$NM_FOR_BUILD";
+    env.BUILD_READELF = "$READELF_FOR_BUILD";
 
     buildPhase = let
       buildCommand = target: ''
diff --git a/pkgs/applications/networking/browsers/chromium/cross-compile.patch b/pkgs/applications/networking/browsers/chromium/cross-compile.patch
new file mode 100644
index 0000000000000..7df73299bc43a
--- /dev/null
+++ b/pkgs/applications/networking/browsers/chromium/cross-compile.patch
@@ -0,0 +1,31 @@
+diff --git a/build/toolchain/linux/unbundle/BUILD.gn b/build/toolchain/linux/unbundle/BUILD.gn
+index a091491236bb1..d36fd4e652fbf 100644
+--- a/build/toolchain/linux/unbundle/BUILD.gn
++++ b/build/toolchain/linux/unbundle/BUILD.gn
+@@ -9,6 +9,7 @@ gcc_toolchain("default") {
+   cxx = getenv("CXX")
+   ar = getenv("AR")
+   nm = getenv("NM")
++  readelf = getenv("READELF")
+   ld = cxx
+ 
+   extra_cflags = getenv("CFLAGS")
+@@ -27,6 +28,7 @@ gcc_toolchain("host") {
+   cxx = getenv("BUILD_CXX")
+   ar = getenv("BUILD_AR")
+   nm = getenv("BUILD_NM")
++  readelf = getenv("BUILD_READELF")
+   ld = cxx
+ 
+   extra_cflags = getenv("BUILD_CFLAGS")
+@@ -35,7 +37,8 @@ gcc_toolchain("host") {
+   extra_ldflags = getenv("BUILD_LDFLAGS")
+ 
+   toolchain_args = {
+-    current_cpu = current_cpu
+-    current_os = current_os
++    current_cpu = host_cpu
++    current_os = host_os
++    v8_current_cpu = target_cpu
+   }
+ }
diff --git a/pkgs/applications/networking/browsers/chromium/default.nix b/pkgs/applications/networking/browsers/chromium/default.nix
index 03b432d19421b..6419fa6a14fd6 100644
--- a/pkgs/applications/networking/browsers/chromium/default.nix
+++ b/pkgs/applications/networking/browsers/chromium/default.nix
@@ -16,11 +16,17 @@
 , cupsSupport ? true
 , pulseSupport ? config.pulseaudio or stdenv.isLinux
 , commandLineArgs ? ""
+, pkgsBuildTarget
+, pkgsBuildBuild
+, pkgs
 }:
 
 let
-  llvmPackages = llvmPackages_16;
-  stdenv = llvmPackages.stdenv;
+  # Sometimes we access `llvmPackages` via `pkgs`, and other times
+  # via `pkgsFooBar`, so a string (attrname) is the only way to have
+  # a single point of control over the LLVM version used.
+  llvmPackages_attrName = "llvmPackages_16";
+  stdenv = pkgs.${llvmPackages_attrName}.stdenv;
 
   upstream-info = (import ./upstream-info.nix).${channel};
 
@@ -42,7 +48,7 @@ let
   callPackage = newScope chromium;
 
   chromium = rec {
-    inherit stdenv llvmPackages upstream-info;
+    inherit stdenv llvmPackages_attrName upstream-info;
 
     mkChromiumDerivation = callPackage ./common.nix ({
       inherit channel chromiumVersionAtLeast versionRange;
@@ -60,7 +66,12 @@ let
       inherit channel chromiumVersionAtLeast enableWideVine ungoogled;
     };
 
-    ungoogled-chromium = callPackage ./ungoogled.nix {};
+    # ungoogled-chromium is, contrary to its name, not a build of
+    # chromium.  It is a patched copy of chromium's *source code*.
+    # Therefore, it needs to come from buildPackages, because it
+    # contains python scripts which get /nix/store/.../bin/python3
+    # patched into their shebangs.
+    ungoogled-chromium = pkgsBuildBuild.callPackage ./ungoogled.nix {};
   };
 
   pkgSuffix = if channel == "dev" then "unstable" else
@@ -209,8 +220,10 @@ in stdenv.mkDerivation {
 
     export XDG_DATA_DIRS=$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH\''${XDG_DATA_DIRS:+:}\$XDG_DATA_DIRS
 
+  '' + lib.optionalString (!xdg-utils.meta.broken) ''
     # Mainly for xdg-open but also other xdg-* tools (this is only a fallback; \$PATH is suffixed so that other implementations can be used):
     export PATH="\$PATH\''${PATH:+:}${xdg-utils}/bin"
+  '' + ''
 
     .
     w