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

Add pkgsCross.emscripten, replacing hand-crafted emscriptenPackages #217428

Open
wants to merge 1 commit into
base: staging
Choose a base branch
from

Conversation

AtnNn
Copy link
Contributor

@AtnNn AtnNn commented Feb 21, 2023

Description of changes
  • Added a pre-built Emscripten SYSTEM cache to the emscripten package
  • Added emscriptenFull which additionally contains Emscripten PORTS
  • Added emscriptenNoCache which requires setting EM_CACHE to use
  • Add wrapped emscriptenCC and emscriptenBintools
  • Added Emscripten to lib/systems and pkgsCross
  • Moved the xmlmirror package from inside top-level/emscripten-packages.nix to tools/text/xml
  • Removed custom emscriptenPackages.json_c and emscriptenPackages.zlib
  • Removed buildEmscriptenPackage
  • Added some pkgsCross.emscripten packages to release-cross.nix

Possibly fixes #28929 #141246 #136396. Improves the fix for #139943.

Tested with

$ nix-build --show-trace -E 'with import ./pkgs/top-level/release-cross.nix {}; builtins.mapAttrs (k: v: v."x86_64-linux") emscripten'
$ node result-3/bin/hello
Hello, world!
Things done
  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 23.05 Release Notes (or backporting 22.11 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

@github-actions github-actions bot added 6.topic: haskell 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 6.topic: stdenv Standard environment 8.has: documentation This PR adds or changes documentation 8.has: module (update) This PR changes an existing module in `nixos/` labels Feb 21, 2023
@AtnNn
Copy link
Contributor Author

AtnNn commented Feb 21, 2023

What do you think about this approach? @qknight @matthewbauer @RaitoBezarius

@RaitoBezarius
Copy link
Member

What do you think about this approach? @qknight @matthewbauer @RaitoBezarius

Interesting changes, thank you for doing this. I am not too expert in the stdenv area, so I would rather defer to people working on that, cc @alyssais @Ericson2314

I will need more time to review though and test thoroughly, but it seems to be a PR in the right direction.

Copy link
Member

@alyssais alyssais left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very promising direction. Thank you for exploring it! Since it's still early, I've focused my review only on the stdenv stuff, not any individual package modifications.

The biggest threat I see is the split binaries, so some more info on those would be great.

lib/systems/examples.nix Outdated Show resolved Hide resolved
lib/systems/inspect.nix Outdated Show resolved Hide resolved
pkgs/development/compilers/emscripten/wrapped.nix Outdated Show resolved Hide resolved
pkgs/stdenv/generic/make-derivation.nix Outdated Show resolved Hide resolved
pkgs/tools/misc/figlet/default.nix Outdated Show resolved Hide resolved
pkgs/top-level/all-packages.nix Outdated Show resolved Hide resolved
@alyssais alyssais added the 2.status: merge conflict This PR has merge conflicts with the target branch label Mar 22, 2023
@AtnNn
Copy link
Contributor Author

AtnNn commented Mar 25, 2023

Thanks @alyssais. I'm going to update this branch to use Emscripten's -sSINGLE_FILE mode, which seems to solve the issues I had with split executables.

@github-actions github-actions bot added 6.topic: python and removed 8.has: module (update) This PR changes an existing module in `nixos/` 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS labels Mar 27, 2023
@ofborg ofborg bot removed the 2.status: merge conflict This PR has merge conflicts with the target branch label Mar 27, 2023
@mohe2015
Copy link
Contributor

Could you please fix the syntax errors in overlay.nix? And maybe update to latest nixpkgs?

@RaitoBezarius
Copy link
Member

Let's get this after the branch-off :).

@willcohen
Copy link
Contributor

Just as a note for a parallel emscripten change, #229718 (not merged as of this comment) would bump underlying emscripten from 3.1.24 to 3.1.39, which in turn requires LLVM 16 instead of 14.

lib/strings.nix Outdated Show resolved Hide resolved
@@ -294,6 +294,7 @@ rec {
openbsd = { execFormat = elf; families = { inherit bsd; }; };
solaris = { execFormat = elf; families = { }; };
wasi = { execFormat = wasm; families = { }; };
emscripten = { execFormat = wasm; families = { }; };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
emscripten = { execFormat = wasm; families = { }; };
emscripten = { execFormat = wasm; families = { }; };

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best would be to adjust the alignment of the others to match.

, isGNU ? false, isClang ? cc.isClang or false, gnugrep ? null
, isGNU ? false
, isClang ? cc.isClang or false
, isEmscripten ? cc.isEmscripten or false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not used

explicitFlags ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) crossFlags;
explicitFlags
++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) crossFlags
++ (stdenv.extraCmakeFlags or []) ;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
++ (stdenv.extraCmakeFlags or []) ;
++ (stdenv.extraCmakeFlags or []);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parens aren't necessary either, I think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer keeping the parens as it makes it more clear what is meant.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would trust deadnix. If it says they are optional, I would remove them.

Comment on lines 25 to 33
bullet = bullet;
bzip2 = bzip2;
giflib = giflib;
harfbuzz = harfbuzz;
icu = icu;
libjpeg = libjpeg;
libmodplug = libmodplug;
libpng = libpng;
mpg123 = mpg123;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bullet = bullet;
bzip2 = bzip2;
giflib = giflib;
harfbuzz = harfbuzz;
icu = icu;
libjpeg = libjpeg;
libmodplug = libmodplug;
libpng = libpng;
mpg123 = mpg123;
inherit bullet bzip2 giflib harfbuzz icu libjpeg libmodplug libpng mpg123 zlib;

libogg = ogg;
sqlite = sqlite3;
libvorbis = vorbis;
zlib = zlib;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
zlib = zlib;

sha256 = "sha256-hzXN30IocklLty8daZSF5rHQJ4xHKLWzCQP7o0m5Z0s=";
};
libpng = {
url = "https://github.com/libsdl-org/SDL/archive/release-2.24.0.zip";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least this URL is duplicated. Not sure if it is worth to dedupe. Also can't we re-use the src's from our packages?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've fixed the duplicate URLs. The src's from nixpkgs cannot be used here, the url in this file point to the exact sources that embuilder.py requires.

buildInputs = [ makeWrapper ];

unpackPhase = ''
src=$PWD
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use sourceRoot?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just copied this from pkgs/build-support/bintools-wrapper/default.nix. How would I use srcRoot instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is okay, the point is to forgo upacking (since there is no source), but src needs to be set to something. sourceRoot only controls the working directory which is irrelevant here.

pkgs/development/compilers/emscripten/cc.nix Outdated Show resolved Hide resolved
pkgs/development/compilers/emscripten/cache.nix Outdated Show resolved Hide resolved
pkgs/development/compilers/emscripten/cache.nix Outdated Show resolved Hide resolved
pkgs/development/compilers/emscripten/bintools.nix Outdated Show resolved Hide resolved
@alyssais alyssais added the 2.status: merge conflict This PR has merge conflicts with the target branch label May 22, 2023
@willcohen
Copy link
Contributor

Noting that #229718, which bumps underlying emscripten and llvm, has entered staging.

emulatorAvailable = pkgs: (selectEmulator pkgs) != null;

emulator = pkgs:
emulatorNeeded = pkgs:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused and there's already canExecute

@ofborg ofborg bot added 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild 8.has: clean-up and removed 2.status: merge conflict This PR has merge conflicts with the target branch labels Jul 6, 2023
@ofborg ofborg bot requested a review from qknight July 8, 2023 21:19
@ofborg ofborg bot added 11.by: package-maintainer This PR was created by the maintainer of the package it changes 10.rebuild-darwin: 11-100 and removed 10.rebuild-darwin: 501+ 10.rebuild-darwin: 5001+ labels Jul 8, 2023
Comment on lines 1150 to 1152
makeWrapper =
if stdenv.hostPlatform.isWindows || stdenv.hostPlatform.isEmscripten
then null
Copy link
Member

@Artturin Artturin Jul 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should throw or something

should break early

comment why it doesn't work on emscripten

can't be changed to makeBinaryWrapper globally on windows #120726 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My intent here is to allow packages to conditionally use makeWrapper if it is available by checking for makeWrapper == null. Changing this to a throw wouldn't work for that. Is there a better way to do that? Maybe something like lib.elem stdenv.hostPlatform makeWrapper.meta.platforms?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, the using expression should check whether something is available or not. lib.meta.availableOn should suffice for this, given that the compatibility is expressed in (makeWrapper's) meta.platforms.

Using null will also break makeWrapper in buildPackages for the affected package sets due to splicing depending on attribute sets.

passthru = {
libc_bin = "";
libc_dev = "";
libc_lib = "";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null is better here.

Comment on lines 1150 to 1152
makeWrapper =
if stdenv.hostPlatform.isWindows || stdenv.hostPlatform.isEmscripten
then null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, the using expression should check whether something is available or not. lib.meta.availableOn should suffice for this, given that the compatibility is expressed in (makeWrapper's) meta.platforms.

Using null will also break makeWrapper in buildPackages for the affected package sets due to splicing depending on attribute sets.

@@ -7469,10 +7472,6 @@ with pkgs;

zzuf = callPackage ../tools/security/zzuf { };

### DEVELOPMENT / EMSCRIPTEN

buildEmscriptenPackage = callPackage ../development/em-modules/generic { };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a substantial, breaking change and should also be explained in the release notes for 23.11.


* nix
* nixpkgs
This mode is far more power full since this makes use of `nix` for
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This mode is far more power full since this makes use of `nix` for
This mode is far more powerful since this makes use of `nix` for

Though this sentence doesn't really make sense: More powerful than what? Imperative Usage is only described later on…

emulatorAvailable = pkgs: (selectEmulator pkgs) != null;

emulator = pkgs:
emulatorCommand = pkgs:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dislike introducing yet another field here, how is this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CMake variable CMAKE_CROSSCOMPILING_EMULATOR requires a semicolon-delimited command.

buildInputs = [ makeWrapper ];

unpackPhase = ''
src=$PWD
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is okay, the point is to forgo upacking (since there is no source), but src needs to be set to something. sourceRoot only controls the working directory which is irrelevant here.

@@ -27,7 +27,9 @@ let
# https://gitlab.gnome.org/GNOME/libxml2/-/commit/b706824b612adb2c8255819c9a55e78b52774a3c
# This case is encountered "temporarily" during stdenv bootstrapping on darwin.
# Beware that the old version has known security issues, so the final set shouldn't use it.
oldVer = python.pname == "python3-minimal";
oldVer =
(pythonSupport || stdenv.isDarwin) # testing for isDarwin only to avoid mass rebuild (stdenv contains libxml2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just target staging.

@@ -172,7 +174,7 @@ let
mkdir -p $bin
mv $out/bin $bin/bin

'' + lib.optionalString (!stdenv.hostPlatform.isWindows)
'' + lib.optionalString (makeWrapper != null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lib.meta.availableOn makeWrapper stdenv.hostPlatform would be a possibility or querying meta.broken of makeWrapper—or just expanding the conditional.

For better or worse, the convention in nixpkgs is that the expression using a package decides whether it can use it or not. This also has the sense that it prevents stuff from being silently unavailable which can alter configure time settings etc.

@@ -380,7 +380,7 @@ else let
"-DCMAKE_HOST_SYSTEM_PROCESSOR=${stdenv.buildPlatform.uname.processor}"
] ++ lib.optionals (stdenv.buildPlatform.uname.release != null) [
"-DCMAKE_HOST_SYSTEM_VERSION=${stdenv.buildPlatform.uname.release}"
]);
]) ++ (stdenv.extraCmakeFlags or []);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is better achieved with a setup hook that appends to cmakeFlags.

@sternenseemann sternenseemann requested a review from a user July 9, 2023 11:30
@AtnNn AtnNn changed the base branch from master to staging July 10, 2023 18:43
@github-actions github-actions bot added the 6.topic: lib The Nixpkgs function library label Jul 10, 2023
@github-actions github-actions bot added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: changelog labels Jul 10, 2023
@AtnNn
Copy link
Contributor Author

AtnNn commented Jul 10, 2023

Thanks for the suggestions. I've:

  • removed escapeShellArgs' and emulatorCommand
  • used a setup hook for CMake flags
  • stopped avoiding rebuilds and target staging instead

Comment on lines 7 to 9
addEnvHooks "$hostOffset" addEmscriptenCMakeEnv


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trailing newlines should be removed

targetPrefix = "${wasmArch}-emscripten-";
llvm = emscripten.llvmEnv;

unwrapped = stdenv.mkDerivation {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong indentation, run git diff --name-only HEAD~ --diff-filter=A | grep "\.nix" | xargs nixpkgs-fmt to format added files only

Comment on lines 36 to 38
unpackPhase = ''
src=$PWD
'';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
unpackPhase = ''
src=$PWD
'';
dontUnpack = true;

same for the others

src=$PWD
'';

installPhase = ''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

runHook's missing
also in other files

lnLLVM llvm-cxxfilt c++filt
lnLLVM llvm-addr2line addr2line

echo -n > $out/nix-support/libc-ldflags-before
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?, add a comment.

@@ -21135,6 +21138,7 @@ with pkgs;
else if name == "nblibc" then targetPackages.netbsdCross.libc or netbsdCross.libc
else if name == "wasilibc" then targetPackages.wasilibc or wasilibc
else if name == "relibc" then targetPackages.relibc or relibc
else if stdenv.targetPlatform.isEmscripten then null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is emscripten special from all the others, why is stdenv.targetPlatform.libc not null on emscripten

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll remove this and set libc = null

@@ -136,7 +136,7 @@ stdenv.mkDerivation rec {
'';
license = licenses.gpl3Plus;
platforms = platforms.all;
maintainers = with maintainers; [ dtzWill ];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accidentally removed

@@ -95,6 +95,7 @@ lib.runTests (
# The functions should be derived from the data, so this is not a problem.
canExecute = null;
emulator = null;
emulatorCommand = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
emulatorCommand = null;

leftover

@@ -125,3 +125,5 @@ The module update takes care of the new config syntax and the data itself (user
./common/auto-format-root-device.nix ];` When you use the systemd initrd, you
can automatically format the root device by setting
`virtualisation.fileSystems."/".autoFormat = true;`.

- `emscriptenPackages` and `buildEmscriptenPackage` have been replaced with `pkgsCross.emscripten` and `pkgsCross.emscripten.stdenv.mkDerivation`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't add directly at the end but at a random location to prevent merge conflicts

@willcohen
Copy link
Contributor

As a quick note I've discovered working through #260267 -- emscripten will now need access to emscripten's node_modules folder as well, so it can run acorn-optimizer.js during some of its passes.

@wegank wegank added 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md 2.status: merge conflict This PR has merge conflicts with the target branch labels Mar 19, 2024
@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Mar 20, 2024
@allsey87
Copy link

allsey87 commented Apr 23, 2024

I was experimenting a bit with this PR and considering to revive it and noticed that the following works:

nix-build '<nixpkgs>' -I nixpkgs=https://github.com/AtnNn/nixpkgs/archive/emscripten.tar.gz \
  -A pkgsCross.emscripten.hello

However, this does not work:

nix-build '<nixpkgs>' -I nixpkgs=https://github.com/AtnNn/nixpkgs/archive/emscripten.tar.gz \
  --arg crossSystem '{ config = "wasm32-unknown-emscripten"; }' \
  -A hello

Instead it fails with the error, "Unknown libc emscripten".

Is this expected?

@wegank wegank added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jul 4, 2024
@willcohen willcohen mentioned this pull request Dec 4, 2024
13 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.status: merge conflict This PR has merge conflicts with the target branch 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md 6.topic: haskell 6.topic: lib The Nixpkgs function library 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 6.topic: python 6.topic: stdenv Standard environment 8.has: changelog 8.has: clean-up 8.has: documentation This PR adds or changes documentation 8.has: package (new) This PR adds a new package 10.rebuild-darwin: 501+ 10.rebuild-darwin: 5001+ 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild 10.rebuild-linux: 11-100 11.by: package-maintainer This PR was created by the maintainer of the package it changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Emscripten package should have a setup hook to set EMSCRIPTEN_ROOT_PATH and EMSCRIPTEN
10 participants