diff --git a/.envrc b/.envrc new file mode 100644 index 0000000000..3550a30f2d --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore index 9a9d505fec..1bc7ea3bb1 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ InterfacesAndLibraries .vscode /result /result-* -/build/ +/build diff --git a/Dockerfile b/Dockerfile index f69d67c15b..653d4975b1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,43 @@ # vim:ft=dockerfile -FROM ubuntu:18.04 +# Base image +FROM ubuntu:20.04 AS base -RUN apt-get update && apt-get -y install \ - g++ \ - cmake libgmp-dev libmpfr-dev libmpc-dev libboost-all-dev bison \ - zlib1g-dev \ - perl texinfo +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + cmake libgmp-dev libmpfr-dev libmpc-dev \ + libboost-all-dev bison texinfo \ + ruby flex curl g++ git macutils + +# Add toolchain to default PATH +ENV PATH=/Retro68-build/toolchain/bin:$PATH +WORKDIR /root + +# Build image +FROM base AS build ADD . /Retro68 -RUN mkdir /Retro68-build +RUN mkdir /Retro68-build && \ + mkdir /Retro68-build/bin && \ + bash -c "cd /Retro68-build && bash /Retro68/build-toolchain.bash" -RUN bash -c "cd /Retro68-build && bash /Retro68/build-toolchain.bash --clean-after-build" +# Release image +FROM base AS release + +ENV INTERFACES=multiversal + +COPY --from=build \ + /Retro68/interfaces-and-libraries.sh \ + /Retro68/prepare-headers.sh \ + /Retro68/prepare-rincludes.sh \ + /Retro68/install-universal-interfaces.sh \ + /Retro68/docker-entrypoint.sh \ + /Retro68-build/bin/ + +COPY --from=build /Retro68-build/toolchain /Retro68-build/toolchain + +LABEL org.opencontainers.image.source https://github.com/autc04/Retro68 + +CMD [ "/bin/bash" ] +ENTRYPOINT [ "/Retro68-build/bin/docker-entrypoint.sh" ] diff --git a/PEFTools/MakePEF.cc b/PEFTools/MakePEF.cc index 9f5d03bb53..f2ee393154 100755 --- a/PEFTools/MakePEF.cc +++ b/PEFTools/MakePEF.cc @@ -227,9 +227,9 @@ class ExportTable public: void addExport(StringTable& stringTable, const std::string& name, - uint32_t value, int16_t section) /* TODO: symbol class */ + uint32_t value, int16_t section, uint8_t clas) { - uint32_t classAndName = (kPEFTVectorSymbol << 24) | stringTable.insert(name); + uint32_t classAndName = ((uint32_t)clas << 24) | stringTable.insert(name); symbols.push_back({hash(name), {classAndName, value, section}}); } @@ -376,7 +376,9 @@ void mkpef(const std::string& inFn, const std::string& outFn) { if(verboseFlag) std::cerr << "... exported from section " << get(sym.l_scnum) << " addr " << get(sym.l_value) << ".\n"; - exports.addExport(stringTable, name, get(sym.l_value), 0 /* ### */); + exports.addExport(stringTable, name, get(sym.l_value), 1 /*all exports from section 1*/, + (get(sym.l_smclas) == 10) ? kPEFTVectorSymbol : kPEFDataSymbol); + } } importedSymbolIndices.resize(get(xcoffLoaderHeader.l_nsyms)); diff --git a/README.md b/README.md index 9652577e2c..5361c25dd7 100644 --- a/README.md +++ b/README.md @@ -155,43 +155,128 @@ Using Retro68 with Nix If you are not using the [Nix Package Manager](https://www.nixos.org), please skip this section. But maybe you should be using it ;-). Nix is a package manager that runs on Linux and macOS, and NixOS is a Linux distribution based on it. +Try the [Determinate Nix Installer](https://install.determinate.systems/) for the best installation experience. -If you've got `nix` installed, after downloading Retro68, you can run +[TODO: docs on using the binary cache to avoid builds] - nix-shell +Once you've got `nix` installed, and without checking out the Retro68 repository, you can run + + nix develop github:autc04/Retro68#m68k from the Retro68 directory to get a shell with the compiler tools targeting 68K Macs available in the path, and `CC` and other environment variables already set up for you. You can then `cd` to one of the example directories or to your own project and use `cmake` to build it. -You can use the `nix-shell` command to invoke various useful shell environments: +Likewise, use -| Command | What | -|-------------------------------------|----------------------------------------------| -| `nix-shell` | 68K development environment | -| `nix-shell -A m68k` | 68K development environment | -| `nix-shell -A powerpc` | PowerPC development environment | -| `nix-shell -A retro68.monolithic` | Shell for running `build-toolchain.bash` | + nix develop github:autc04/Retro68#powerpc -You can also use the `nix-build` command to build packages. As always with `nix`, +... to get an environment targeting PowerPC Macs. + +If you have a local checkout of Retro68, you can replace `github:autc04/Retro68` by the path +to that local checkout, e.g., run `nix develop .#m68k` from inside the Retro68 directory. + +You can also use the `nix build` command to build packages. As always with `nix`, the result will be somewhere in a subdirectory of `/nix/store`, with a symlink -named `result` placed in your Retro68 directory. +named `result` placed in the directory where you invoked the command. -| Command | What | -|----------------------------------------|----------------------------------------------| -| `nix-build -A m68k.retro68.samples` | Sample programs for 68K | -| `nix-build -A powerpc.retro68.samples` | Sample programs for PowerPC | -| `nix-build -A retro68.monolithic` | Result of `build-toolchain.bash --no-carbon` | -| `nix-build -A m68k.zlib` | zlib library, cross-compiled for 68K Macs | -| `nix-build -A m68k.`*packagename* | cross-compile *packagename* to 68K | -| `nix-build -A powerpc.`*packagename* | cross-compile *packagename* to PowerPC | +| Command | What | +|--------------------------------------------------------------------|-------------------------------------------| +| `nix build github:autc04/Retro68#samples-m68k` | Sample programs for 68K | +| `nix build github:autc04/Retro68#samples-powerpc` | Sample programs for PowerPC | +| `nix build github:autc04/Retro68#pkgsCross.m68k.zlib` | zlib library, cross-compiled for 68K Macs | +| `nix build github:autc04/Retro68#pkgsCross.m68k.`*packagename* | cross-compile *packagename* to 68K | +| `nnix build github:autc04/Retro68#pkgsCross.powerpc.`*packagename* | cross-compile *packagename* to PowerPC | You can attempt to cross-compile *any* package from the `nixpkgs` collection. Unless the package contains a very portable library, the command will of course fail. Please don't report bugs, please report successes instead! +Using Retro68 with Docker +------------------------- + +Whenever commits are merged into the Retro68 git repository, a build pipeline is triggered to +create a container image which is then pushed to the Retro68 package repository as +`ghcr.io/autc04/retro68`. This image contains the complete 68K and PPC toolchains ready for +use for either local development or as part of CI pipeline. The command line below shows an +example invocation of Retro68 to build the `Samples/Raytracer` app: + +``` +$ git clone --depth 1 https://github.com/autc04/Retro68.git +$ cd Retro68 +$ docker run --rm -v $(pwd):/root -i ghcr.io/autc04/retro68 /bin/bash <<"EOF" + cd Samples/Raytracer + rm -rf build && mkdir build && cd build + cmake .. -DCMAKE_TOOLCHAIN_FILE=/Retro68-build/toolchain/m68k-apple-macos/cmake/retro68.toolchain.cmake + make +EOF +``` + +The container image is configured by default to use the multiversal interfaces, but it is +possible to use the universal interfaces by passing a path to either a local file or a URL +that points to a Macbinary DiskCopy image containing the "Interfaces&Libraries" directory +from MPW. + +Using the universal interfaces from a local file: + +``` +$ docker run --rm -v $(pwd):/root -v $(pwd)/MPW-GM.img.bin:/tmp/MPW-GM.img.bin \ + -e INTERFACES=universal -e INTERFACESFILE=/tmp/MPW-GM.img.bin \ + -i ghcr.io/autc04/retro68 /bin/bash <<"EOF" + cd Samples/Raytracer + rm -rf build && mkdir build && cd build + cmake .. -DCMAKE_TOOLCHAIN_FILE=/Retro68-build/toolchain/m68k-apple-macos/cmake/retro68.toolchain.cmake + make +EOF +``` + +Using the universal interfaces from a URL: + +``` +$ docker run --rm -v $(pwd):/root \ + -e INTERFACES=universal -e INTERFACESFILE=https://mysite.com/MPW-GM.img.bin \ + -i ghcr.io/autc04/retro68 /bin/bash <<"EOF" + cd Samples/Raytracer + rm -rf build && mkdir build && cd build + cmake .. -DCMAKE_TOOLCHAIN_FILE=/Retro68-build/toolchain/m68k-apple-macos/cmake/retro68.toolchain.cmake + make +EOF +``` + +Note that `entrypoint.sh` checks to see if the universal interfaces are installed into +`/Retro68/toolchain/universal` first before attempting to access the file or URL specified +by INTERFACESFILE. This means that it is possible to use caching or another volume so that +the universal interfaces are only processed once to speed up builds e.g. + +``` +$ docker run --rm -v $(pwd):/root \ + -v $(pwd)/universal:/Retro68-build/toolchain/universal \ + -e INTERFACES=universal -e INTERFACESFILE=https://mysite.com/MPW-GM.img.bin \ + -i ghcr.io/autc04/retro68 /bin/bash <<"EOF" + cd Samples/Raytracer + rm -rf build && mkdir build && cd build + cmake .. -DCMAKE_TOOLCHAIN_FILE=/Retro68-build/toolchain/m68k-apple-macos/cmake/retro68.toolchain.cmake + make +EOF +``` + +and then on subsequent runs: + +``` +$ docker run --rm -v $(pwd):/root \ + -v $(pwd)/universal:/Retro68-build/toolchain/universal \ + -e INTERFACES=universal \ + -i ghcr.io/autc04/retro68 /bin/bash <<"EOF" + cd Samples/Raytracer + rm -rf build && mkdir build && cd build + cmake .. -DCMAKE_TOOLCHAIN_FILE=/Retro68-build/toolchain/m68k-apple-macos/cmake/retro68.toolchain.cmake + make +EOF +``` + + Sample programs --------------- diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 172434818b..d13df78d82 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -5,36 +5,53 @@ jobs: - job: Linux pool: - vmImage: 'ubuntu-20.04' + vmImage: 'ubuntu-latest' timeoutInMinutes: 90 + variables: + - group: Tokens steps: - checkout: self submodules: true - - script: | - sudo apt-get update - DEBIAN_FRONTEND=noninteractive sudo apt-get install -y \ - cmake libgmp-dev libmpfr-dev libmpc-dev \ - libboost-all-dev bison texinfo \ - ruby flex curl - displayName: 'Install prerequisites' - - script: | - mkdir build - cd build - ../build-toolchain.bash + + - task: Docker@2 + inputs: + command: build + repository: ghcr.io/autc04/retro68-build + tags: latest + arguments: --target build displayName: 'Build' + - task: Docker@2 + inputs: + command: build + repository: ghcr.io/autc04/retro68 + tags: latest + arguments: --target release + displayName: 'Build release' - script: | - cd build - curl -L -O https://github.com/autc04/executor/releases/download/v0.1.0/Executor2000-0.1.0-Linux.tar.bz2 - tar xfvj Executor2000-0.1.0-Linux.tar.bz2 Executor2000-0.1.0-Linux/bin/executor-headless - echo "executor-path=`pwd`/Executor2000-0.1.0-Linux/bin/executor-headless" > ~/.LaunchAPPL.cfg - echo "emulator=executor" >> ~/.LaunchAPPL.cfg - ctest --no-compress-output -T test -E Carbon || true + docker run --name retro68-build --rm -i -d ghcr.io/autc04/retro68-build:latest + docker exec -i retro68-build /bin/bash <<"EOF" + cd /Retro68-build + curl -L -O https://github.com/autc04/executor/releases/download/v0.1.0/Executor2000-0.1.0-Linux.tar.bz2 + tar xfvj Executor2000-0.1.0-Linux.tar.bz2 Executor2000-0.1.0-Linux/bin/executor-headless + echo "executor-path=`pwd`/Executor2000-0.1.0-Linux/bin/executor-headless" > ~/.LaunchAPPL.cfg + echo "emulator=executor" >> ~/.LaunchAPPL.cfg + ctest --no-compress-output -T test -E Carbon || true + EOF + mkdir build && docker cp retro68-build:/Retro68-build/Testing build + docker stop retro68-build displayName: Run Tests using Executor 2000 - task: PublishTestResults@2 inputs: testResultsFormat: 'CTest' testResultsFiles: build/Testing/**/*.xml buildPlatform: 'x86_64-linux' + - script: | + docker login ghcr.io/autc04 -u autc04 -p $GHCR_TOKEN + docker push ghcr.io/autc04/retro68 + env: + GHCR_TOKEN: $(GHCR_TOKEN) + displayName: 'Push release to GHCR' + condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master')) - job: macOS pool: @@ -74,36 +91,32 @@ jobs: TARGET: powerpc Carbon: TARGET: carbon - maxParallel: 2 pool: - vmImage: 'ubuntu-20.04' + vmImage: 'ubuntu-latest' steps: + - script: | + curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix \ + | sh -s -- install --no-confirm --extra-conf "trusted-users = root vsts" + displayName: Install Nix + - script: | + . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh + nix profile install --accept-flake-config nixpkgs#cachix + cachix use autc04 + displayName: Setup Cachix - checkout: self - submodules: true + submodules: false - script: | - docker run -i --name nix -v`pwd`:/src nixos/nix:2.18.1 <) { }).lib; - - multiversal_src = if builtins.pathExists ./multiversal/make-multiverse.rb then - ./multiversal - else - sources.multiversal; + lib = ((import nixpkgs) { inherit system; }).lib; # A Nixpkgs overlay. overlay = lib.composeManyExtensions [ @@ -23,26 +25,36 @@ let overlays = [ overlay ]; }; - crossPkgs = lib.mapAttrs (name: plat: - import nixpkgs { - inherit system; - overlays = [ overlay ]; - crossSystem = plat; - config = { allowUnsupportedSystem = true; }; - }) retroPlatforms; + crossPkgs = lib.mapAttrs + (name: plat: + import nixpkgs { + inherit system; + overlays = [ overlay ]; + crossSystem = plat; + config = { allowUnsupportedSystem = true; }; + }) + retroPlatforms; + targetPkgs = lib.mapAttrs (name: cross: cross.buildPackages) crossPkgs; - shell = lib.mapAttrs (name: cross: - cross.mkShell { - nativeBuildInputs = with overlaidPkgs; [ - retro68.hfsutils - retro68.tools - cmake - gnumake - ]; - buildInputs = [ cross.retro68.console ]; - } // cross) crossPkgs; + shell = lib.mapAttrs + (name: cross: + cross.mkShell + { + nativeBuildInputs = with overlaidPkgs; [ + retro68.hfsutils + retro68.tools + cmake + gnumake + ]; + buildInputs = [ cross.retro68.console ]; + } // cross) + crossPkgs; -in shell.m68k // shell // { - inherit overlay; - inherit (overlaidPkgs) retro68; -} +in +builtins.trace + "Warning: Retro68's default.nix is deprecated and will disappear soon. Please use the flake instead." + (shell.m68k // shell // { + inherit overlay; + inherit (overlaidPkgs) retro68; + targetPkg = targetPkgs; + }) diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100755 index 0000000000..792a753266 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +set -e + +TMPDIR=/tmp +BUILDDIR=/Retro68-build + +if [[ $INTERFACES == "universal" ]]; +then + # If the universal RIncludes directory is empty, download and install the universal headers + if [ ! "$(ls -A $BUILDDIR/toolchain/universal/RIncludes 2> /dev/null)" ]; then + # If INTERFACESFILE is empty, exit + if [[ -z $INTERFACESFILE ]]; + then + echo -n "Universal interfaces not present, please specify the location of a suitable " + echo "MacBinary DiskCopy image using the INTERFACESFILE environment variable." + exit 1 + fi + + BASEINTERFACESFILE=`basename $INTERFACESFILE` + + # If INTERFACESFILE is a URL, download it first to TMPDIR. Otherwise assume the file is + # already present and copy it to TMPDIR for installation + if [[ $INTERFACESFILE == http* ]]; + then + echo "Downloading Universal interfaces from MacBinary DiskCopy image $BASEINTERFACESFILE..." + curl -s $INTERFACESFILE -o $TMPDIR/$BASEINTERFACESFILE + echo "done" + else + if [[ -z $INTERFACESFILE ]]; + then + echo "Unable to locate universal interfaces file $INTERFACESFILE" + exit 1 + else + echo "Using Universal intefaces from MacBinary Diskcopy image $BASEINTERFACESFILE" + cp $INTERFACESFILE $TMPDIR/$BASEINTERFACESFILE + fi + fi + + # Extract the file + $BUILDDIR/bin/install-universal-interfaces.sh $TMPDIR $BASEINTERFACESFILE + + # Switch to universal + echo "Linking Universal interfaces..." + $BUILDDIR/bin/interfaces-and-libraries.sh $BUILDDIR/toolchain $TMPDIR/InterfacesAndLibraries + echo "done" + else + echo "Linking Universal interfaces..." + + # Link to existing universal interfaces + PREFIX=$BUILDDIR/toolchain + . "$BUILDDIR/bin/interfaces-and-libraries.sh" + BUILD_68K=true + BUILD_PPC=true + + unlinkInterfacesAndLibraries + linkInterfacesAndLibraries "universal" + echo "done" + fi +else + echo "Using multiversal interfaces" +fi + +# Execute command +exec "$@" diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000000..4d943e6cc9 --- /dev/null +++ b/flake.lock @@ -0,0 +1,81 @@ +{ + "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1701473968, + "narHash": "sha256-YcVE5emp1qQ8ieHUnxt1wCZCC3ZfAS+SRRWZ2TMda7E=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "34fed993f1674c8d06d58b37ce1e0fe5eebcb9f5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "multiversal": { + "flake": false, + "locked": { + "lastModified": 1703617805, + "narHash": "sha256-GngLWR9i+hC7hJ+ZkKlRK4K63lIJ4D/CMXZwefcVAqw=", + "owner": "autc04", + "repo": "multiversal", + "rev": "27c08c654bbd48d23f025741e3a584b59374904a", + "type": "github" + }, + "original": { + "owner": "autc04", + "repo": "multiversal", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1703200384, + "narHash": "sha256-q5j06XOsy0qHOarsYPfZYJPWbTbc8sryRxianlEPJN0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0b3d618173114c64ab666f557504d6982665d328", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1701253981, + "narHash": "sha256-ztaDIyZ7HrTAfEEUt9AtTDNoCYxUdSd6NrRHaYOIxtk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e92039b55bcd58469325ded85d4f58dd5a4eaf58", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-parts": "flake-parts", + "multiversal": "multiversal", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000000..846a412da6 --- /dev/null +++ b/flake.nix @@ -0,0 +1,101 @@ +{ + description = "Description for the project"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11"; + multiversal.url = "github:autc04/multiversal"; + multiversal.flake = false; + flake-parts.url = "github:hercules-ci/flake-parts"; + }; + + outputs = inputs@{ flake-parts, nixpkgs, multiversal, ... }: + flake-parts.lib.mkFlake { inherit inputs; } ({ self, lib, retroPlatforms, ... }: { + _module.args.lib = import (nixpkgs + "/lib"); + _module.args.retroPlatforms = import ./nix/platforms.nix; + + systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ]; + perSystem = { config, self', inputs', pkgs, system, ... }: + { + _module.args.pkgs = import nixpkgs { inherit system; overlays = [ self.overlays.default ]; }; + + formatter = pkgs.nixpkgs-fmt; + + legacyPackages.pkgsCross = lib.mapAttrs + (name: plat: + import nixpkgs { + inherit system; + overlays = [ self.overlays.default ]; + crossSystem = plat; + config = { allowUnsupportedSystem = true; }; + }) + retroPlatforms; + + devShells = { + default = pkgs.mkShell { + inputsFrom = [ pkgs.retro68.monolithic ]; + nativeBuildInputs = [ pkgs.nixpkgs-fmt ]; + }; + } // lib.mapAttrs + (name: cross: + cross.mkShell + { + nativeBuildInputs = with pkgs; [ + retro68.hfsutils + retro68.tools + cmake + gnumake + ninja + ]; + buildInputs = [ cross.retro68.console ]; + } // cross) + self'.legacyPackages.pkgsCross; + + packages = { + tools = pkgs.retro68.tools; + hfsutils = pkgs.retro68.hfsutils; + + default = pkgs.runCommand "Retro68" { } '' + mkdir $out + mkdir $out/m68k-apple-macos + mkdir $out/powerpc-apple-macos + ${pkgs.xorg.lndir}/bin/lndir -silent ${self'.legacyPackages.pkgsCross.m68k.retro68.libretro}/. $out/m68k-apple-macos + ${pkgs.xorg.lndir}/bin/lndir -silent ${self'.legacyPackages.pkgsCross.m68k.retro68.multiversal}/. $out/m68k-apple-macos + ${pkgs.xorg.lndir}/bin/lndir -silent ${self'.legacyPackages.pkgsCross.powerpc.retro68.libretro}/. $out/powerpc-apple-macos + ${pkgs.xorg.lndir}/bin/lndir -silent ${self'.legacyPackages.pkgsCross.powerpc.retro68.multiversal}/. $out/powerpc-apple-macos + ${pkgs.xorg.lndir}/bin/lndir -silent ${self'.legacyPackages.pkgsCross.carbon.retro68.libretro}/. $out/powerpc-apple-macos + ${pkgs.xorg.lndir}/bin/lndir -silent ${self'.legacyPackages.pkgsCross.carbon.retro68.multiversal}/. $out/powerpc-apple-macos + ${pkgs.xorg.lndir}/bin/lndir -silent ${pkgs.retro68.tools}/. $out + ${pkgs.xorg.lndir}/bin/lndir -silent ${pkgs.retro68.hfsutils}/. $out + ${pkgs.xorg.lndir}/bin/lndir -silent ${pkgs.cmake}/. $out + ${pkgs.xorg.lndir}/bin/lndir -silent ${pkgs.gnumake}/. $out + ${pkgs.xorg.lndir}/bin/lndir -silent ${pkgs.ninja}/. $out + + ${pkgs.rsync}/bin/rsync -a ${self'.legacyPackages.pkgsCross.m68k.buildPackages.retro68.gcc_unwrapped}/. $out + ${pkgs.rsync}/bin/rsync -a ${self'.legacyPackages.pkgsCross.powerpc.buildPackages.retro68.gcc_unwrapped}/. $out + ${pkgs.rsync}/bin/rsync -a ${self'.legacyPackages.pkgsCross.carbon.buildPackages.retro68.gcc_unwrapped}/. $out + ''; + + samples = pkgs.linkFarm "Retro68-Samples" [ + { name = "m68k"; path = self'.legacyPackages.pkgsCross.m68k.retro68.samples; } + { name = "powerpc"; path = self'.legacyPackages.pkgsCross.powerpc.retro68.samples; } + { name = "carbon"; path = self'.legacyPackages.pkgsCross.carbon.retro68.samples; } + ]; + } // lib.mapAttrs' + (name: cross: lib.nameValuePair "samples-${name}" cross.retro68.samples) + self'.legacyPackages.pkgsCross; + }; + flake = { + overlays.default = + lib.composeManyExtensions [ + ((import nix/overlay.nix) { + multiversal_src = + if builtins.pathExists ./multiversal/make-multiverse.rb + then ./multiversal + else multiversal; + }) + (import nix/universal.nix) + (import nix/samples.nix) + ]; + }; + }); +} diff --git a/garnix.yaml b/garnix.yaml new file mode 100644 index 0000000000..e391f4b267 --- /dev/null +++ b/garnix.yaml @@ -0,0 +1,4 @@ +# turn off garnix for now +builds: + include: [] + exclude: [] diff --git a/hfsutils/libhfs/data.h b/hfsutils/libhfs/data.h index fd38e75c46..8bebfb78ea 100644 --- a/hfsutils/libhfs/data.h +++ b/hfsutils/libhfs/data.h @@ -19,6 +19,8 @@ * $Id: data.h,v 1.7 1998/11/02 22:08:58 rob Exp $ */ +#include + extern const unsigned char hfs_charorder[]; signed char d_getsb(register const unsigned char *); diff --git a/hfsutils/librsrc/data.h b/hfsutils/librsrc/data.h index 6e5d644ee0..9fdb75cbc1 100644 --- a/hfsutils/librsrc/data.h +++ b/hfsutils/librsrc/data.h @@ -19,6 +19,8 @@ * $Id: data.h,v 1.5 1998/04/11 08:27:18 rob Exp $ */ +# include + extern const unsigned char hfs_charorder[]; signed char d_getsb(const unsigned char *); diff --git a/install-universal-interfaces.sh b/install-universal-interfaces.sh new file mode 100755 index 0000000000..013aeaf644 --- /dev/null +++ b/install-universal-interfaces.sh @@ -0,0 +1,101 @@ +#!/bin/bash + +# +# install-universal-interfaces.sh +# +# Optionally download and attempt to install the universal interfaces from +# a Macbinary disk image containing the Interfaces&Libraries directory +# +# Usage: +# install-universal-interfaces.sh +# +# Decompress the Macbinary image at / into +# /InterfacesAndLibraries in the correct format for +# interfaces-and-libraries.sh. +# + +set -e + +TMPDIR=$1 +FILENAME=$2 + +if [[ ! -f $TMPDIR/$FILENAME ]]; +then + echo "$TMPDIR/$FILENAME not found" + exit 1 +fi + +echo "Decompressing $FILENAME..." +ConvertDiskImage $TMPDIR/$FILENAME $TMPDIR/$FILENAME.img +echo "Decompression complete" + +# Copy over Interfaces&Libraries files +echo "Copying Interfaces&Libraries files..." +hmount $TMPDIR/$FILENAME.img + +# Find Interfaces&Libraries directory, get recursive directory listing +HFSINTERFACESANDLIBSDIR=`hls -R | grep 'Interfaces&Libraries:$'` +IFS="$(printf '\n')" +echo "Found Interfaces&Libraries at $HFSINTERFACESANDLIBSDIR" +FILES=`hls -FR1 $HFSINTERFACESANDLIBSDIR` + +UNIXINTERFACESANDLIBSDIR=$TMPDIR/InterfacesAndLibraries +mkdir -p $UNIXINTERFACESANDLIBSDIR + +# Parse results: first line is the HFS path, following lines contain one file +# per line terminated by an empty line +while IFS= read -r LINE; do + if [[ $LINE == :* ]]; + then + # If it starts with : then it is a HFS path + HFSPATH=$LINE + UNIXRELPATH=$(echo "$HFSPATH" | sed "s#$HFSINTERFACESANDLIBSDIR##g" | sed "s#:#/"#g) + UNIXPATH="$UNIXINTERFACESANDLIBSDIR/$UNIXRELPATH" + + # Make UNIX directory + mkdir -p $UNIXPATH + else + # If it ends with : it is a directory so ignore (we will find it during the descent) + if [[ ! $LINE == *: ]]; + then + # If it isn't empty, it must be a filename + if [[ ! -z $LINE ]]; + then + HFSFULLPATH="$HFSPATH$LINE" + UNIXFULLPATH="$UNIXPATH$LINE" + + echo "Copying $HFSFULLPATH to $UNIXFULLPATH" + + # PPC libraries need a resource fork, but the code in + # interfaces-and-libraries.sh doesn't correctly detect InterfaceLib in + # Macbinary format. Work around this for now by using Basilisk II format + # which can be parsed by ResourceFile and still allows the filename + # detection logic to work. + if [[ $HFSPATH == *SharedLibraries: ]]; + then + if [[ ! -d $UNIXPATH.rsrc ]]; + then + mkdir $UNIXPATH.rsrc + fi + + # First copy as Macbinary + hcopy -m $HFSFULLPATH $UNIXFULLPATH.bin + + # Extract data fork using normal name + bash -c "cd $UNIXPATH && macunpack -d $UNIXFULLPATH.bin && mv $UNIXFULLPATH.data $UNIXFULLPATH" + + # Extract resource fork into .rsrc directory + bash -c "cd $UNIXPATH && macunpack -r $UNIXFULLPATH.bin && mv $UNIXFULLPATH.rsrc $UNIXPATH.rsrc/$LINE" + + # Delete original Macbinary + rm -rf $UNIXFULLPATH.bin + else + hcopy -r $HFSFULLPATH $UNIXFULLPATH + fi + fi + fi + fi +done <<< "$FILES" + +# Unmount image +humount diff --git a/libelf/src/config.h b/libelf/src/config.h index 5a6219d9ee..2d3f00f630 100644 --- a/libelf/src/config.h +++ b/libelf/src/config.h @@ -53,8 +53,9 @@ #endif /* USE_LOCKS */ /* Compiler-specific definitions. */ -//#define strong_alias(name, aliasname) \ - // extern __typeof (name) aliasname __attribute__ ((alias (#name))); +/*#define strong_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((alias (#name))); +*/ #define strong_alias(name, aliasname) diff --git a/libelf/src/system.h b/libelf/src/system.h index c23ad05db4..ebf34799a1 100644 --- a/libelf/src/system.h +++ b/libelf/src/system.h @@ -35,6 +35,7 @@ #include #include "portable_endian.h" #include +#include # define LE32(n) le32toh (n) # define LE64(n) le64toh (n) diff --git a/multiversal b/multiversal index d7aac1e58d..27c08c654b 160000 --- a/multiversal +++ b/multiversal @@ -1 +1 @@ -Subproject commit d7aac1e58d165c30fd3a0796e7b4745e78d34643 +Subproject commit 27c08c654bbd48d23f025741e3a584b59374904a diff --git a/nix/overlay.nix b/nix/overlay.nix index 72f8e0f50c..df86028545 100644 --- a/nix/overlay.nix +++ b/nix/overlay.nix @@ -1,6 +1,5 @@ { multiversal_src }: -pkgs: prevPkgs: -{ +pkgs: prevPkgs: { retro68 = pkgs.lib.makeScope pkgs.newScope (self: { platforms = import ./platforms.nix; @@ -11,7 +10,7 @@ pkgs: prevPkgs: src = ../.; nativeBuildInputs = [ cmake bison flex ruby ninja bash ]; buildInputs = [ boost gmp mpfr libmpc zlib ] - ++ lib.optional hostPlatform.isDarwin + ++ lib.optional hostPlatform.isDarwin darwin.apple_sdk.frameworks.ApplicationServices; buildCommand = '' bash $src/build-toolchain.bash --ninja --prefix=$out --no-carbon @@ -33,6 +32,7 @@ pkgs: prevPkgs: mkdir -p $out/share/man/man1 ''; configureFlags = [ "--mandir=$(out)/share/man" "--enable-devlibs" ]; + env.CFLAGS = "--std=c89"; # the configure script fails with modern C }; # tools -- native tools that are part of Retro68 @@ -56,7 +56,7 @@ pkgs: prevPkgs: nativeBuildInputs = [ cmake bison flex ]; buildInputs = [ boost zlib retro68.hfsutils ] - ++ lib.optional hostPlatform.isDarwin + ++ lib.optional hostPlatform.isDarwin darwin.apple_sdk.frameworks.ApplicationServices; }; @@ -77,21 +77,23 @@ pkgs: prevPkgs: ++ stdenv.targetPlatform.retro68BinutilsConfig or [ ]; enableParallelBuilding = true; - postInstall = let - ld = "$out/bin/${stdenv.targetPlatform.config}-ld"; - ld_real = "$out/bin/${stdenv.targetPlatform.config}-ld.real"; + postInstall = + let + ld = "$out/bin/${stdenv.targetPlatform.config}-ld"; + ld_real = "$out/bin/${stdenv.targetPlatform.config}-ld.real"; - in '' - mv ${ld} ${ld_real} + in + '' + mv ${ld} ${ld_real} - echo "#!${stdenv.shell}" > ${ld} - echo "exec \$'' + '' + echo "#!${stdenv.shell}" > ${ld} + echo "exec \$'' + '' {RETRO68_LD_WRAPPER_${stdenv.targetPlatform.cmakeSystemName}-${ld_real}} \"\$@\"" >> ${ld} chmod +x ${ld} rm $out/${stdenv.targetPlatform.config}/bin/ld ln -s ${ld} $out/${stdenv.targetPlatform.config}/bin/ld - ''; + ''; }; # gcc -- gcc, without any wrappers @@ -119,58 +121,86 @@ pkgs: prevPkgs: make -j$NIX_BUILD_CORES make install ''; + env.CXXFLAGS = "--std=c++14"; # gcc 9 doesn't seem to like C++17 }; + # binutils -- binutils with the wrappers provided by nixpkgs + binutils = pkgs.wrapBintoolsWith { + bintools = pkgs.retro68.binutils_unwrapped; + libc = null; + }; + + # gcc -- gcc with the wrappers provided by nixpkgs + gcc = pkgs.wrapCCWith { + cc = pkgs.retro68.gcc_unwrapped; + bintools = pkgs.retro68.binutils; + libc = null; + + # don't allow nix to add options for hardening + extraBuildCommands = '' + echo "" > $out/nix-support/add-hardening.sh + ''; + + extraPackages = with pkgs.targetPackages.retro68; [ + multiversal + import_libraries + libretro + setup_hook + ]; + }; + } // prevPkgs.lib.optionalAttrs (prevPkgs.hostPlatform ? retro68) { - setup_hook = let - systemName = pkgs.targetPlatform.cmakeSystemName; - toolchain = pkgs.writeTextFile { - name = "retro68.cmake-toolchain"; - text = '' - set(CMAKE_SYSTEM_NAME ${systemName}) - set(CMAKE_SYSTEM_VERSION 1) - set(CMAKE_CROSSCOMPILING TRUE) + setup_hook = + let + systemName = pkgs.targetPlatform.cmakeSystemName; + toolchain = pkgs.writeTextFile { + name = "retro68.cmake-toolchain"; + text = '' + set(CMAKE_SYSTEM_NAME ${systemName}) + set(CMAKE_SYSTEM_VERSION 1) + set(CMAKE_CROSSCOMPILING TRUE) - set(REZ "${pkgs.buildPackages.retro68.tools}/bin/Rez" ) - set(REZ_TEMPLATES_PATH ${pkgs.retro68.libretro}/RIncludes) + set(REZ "${pkgs.buildPackages.retro68.tools}/bin/Rez" ) + set(REZ_TEMPLATES_PATH ${pkgs.retro68.libretro}/RIncludes) - set(MAKE_PEF "${pkgs.buildPackages.retro68.tools}/bin/MakePEF" ) + set(MAKE_PEF "${pkgs.buildPackages.retro68.tools}/bin/MakePEF" ) - include(${../cmake/add_application.cmake}) - '' + (pkgs.lib.optionalString (systemName == "RetroCarbon") '' - set(CMAKE_EXE_LINKER_FLAGS_INIT "-carbon") - set(CMAKE_SHARED_LINKER_FLAGS_INIT "-carbon") - add_definitions( -DTARGET_API_MAC_CARBON=1 ) - ''); - }; - hook = pkgs.writeTextFile { - name = "retro68.setup_hook"; - text = '' - export CMAKE_TOOLCHAIN_FILE=${toolchain} + include(${../cmake/add_application.cmake}) + '' + (pkgs.lib.optionalString (systemName == "RetroCarbon") '' + set(CMAKE_EXE_LINKER_FLAGS_INIT "-carbon") + set(CMAKE_SHARED_LINKER_FLAGS_INIT "-carbon") + add_definitions( -DTARGET_API_MAC_CARBON=1 ) + ''); + }; + hook = pkgs.writeTextFile { + name = "retro68.setup_hook"; + text = '' + export CMAKE_TOOLCHAIN_FILE=${toolchain} - retro68_addRIncludes() { - case $depHostOffset in - -1) local role='BUILD_' ;; - 0) local role="" ;; - 1) local role='TARGET_' ;; - *) echo "retro68_addRIncludes: Error: Cannot be used with $depHostOffset-offset deps" >2; - return 1 ;; - esac + retro68_addRIncludes() { + case $depHostOffset in + -1) local role='BUILD_' ;; + 0) local role="" ;; + 1) local role='TARGET_' ;; + *) echo "retro68_addRIncludes: Error: Cannot be used with $depHostOffset-offset deps" >2; + return 1 ;; + esac - if [[ -d "$1/RIncludes" ]]; then - export REZ_INCLUDE_PATH+=":$1/RIncludes" - fi - } + if [[ -d "$1/RIncludes" ]]; then + export REZ_INCLUDE_PATH+=":$1/RIncludes" + fi + } - addEnvHooks "$targetOffset" retro68_addRIncludes + addEnvHooks "$targetOffset" retro68_addRIncludes - '' + (pkgs.lib.optionalString (systemName == "Retro68") '' - export RETRO68_LD_WRAPPER_Retro68="${pkgs.buildPackages.retro68.tools}/bin/Elf2Mac" - export RETRO68_REAL_LD="${pkgs.buildPackages.retro68.binutils_unwrapped}/bin/m68k-apple-macos-ld.real" - ''); - }; - in pkgs.makeSetupHook { } hook; + '' + (pkgs.lib.optionalString (systemName == "Retro68") '' + export RETRO68_LD_WRAPPER_Retro68="${pkgs.buildPackages.retro68.tools}/bin/Elf2Mac" + export RETRO68_REAL_LD="${pkgs.buildPackages.retro68.binutils_unwrapped}/bin/m68k-apple-macos-ld.real" + ''); + }; + in + pkgs.makeSetupHook { name = "retro68.setup_hook"; } hook; # ----------- Retro68 core libraries ------------- @@ -181,7 +211,7 @@ pkgs: prevPkgs: }).mkDerivation { name = "retro68.multiversal"; src = multiversal_src; - nativeBuildInputs = [ buildPackages.ruby ]; + nativeBuildInputs = [ pkgsBuildBuild.ruby ]; buildCommand = '' echo $src build=`pwd` @@ -195,17 +225,17 @@ pkgs: prevPkgs: ""); }; - import_libraries = with pkgs; if stdenvNoCC.targetPlatform.system != "m68k-macos" then - stdenvNoCC.mkDerivation { - name = "retro68.import_libraries"; - src = ../ImportLibraries; - buildCommand = '' - mkdir -p $out/lib - cp $src/*.a $out/lib/ - ''; - } + stdenvNoCC.mkDerivation + { + name = "retro68.import_libraries"; + src = ../ImportLibraries; + buildCommand = '' + mkdir -p $out/lib + cp $src/*.a $out/lib/ + ''; + } else null; @@ -220,7 +250,8 @@ pkgs: prevPkgs: set(CMAKE_CROSSCOMPILING TRUE) ''; }; - in (pkgs.stdenv.override { + in + (pkgs.stdenv.override { cc = stdenv.cc.override { extraPackages = [ ]; }; }).mkDerivation { name = "libretro"; @@ -250,33 +281,22 @@ pkgs: prevPkgs: }; }); -} // prevPkgs.lib.optionalAttrs (prevPkgs.targetPlatform ? retro68) { # ----------- Binutils & GCC wrapped for nixpkgs ------------- - # binutils -- binutils with the wrappers provided by nixpkgs + # binutils -- binutils with the wrappers provided by nixpkgs + # note: on nix/darwin (as of nixpkgs 23.11), nixpkgs seems to + # ignore (or re-override) this override. binutils = - pkgs.wrapBintoolsWith { bintools = pkgs.retro68.binutils_unwrapped; }; + if (prevPkgs.targetPlatform ? retro68) then + pkgs.retro68.binutils + else + prevPkgs.binutils; # gcc -- gcc with the wrappers provided by nixpkgs - gcc = pkgs.wrapCCWith { - cc = pkgs.retro68.gcc_unwrapped; - - # don't allow nix to add options for hardening - extraBuildCommands = '' - echo "" > $out/nix-support/add-hardening.sh - ''; - - extraPackages = with pkgs.targetPackages.retro68; [ - multiversal - import_libraries - libretro - setup_hook - ]; - }; - - # no separate libc package for now - libcCrossChooser = name: - if name == "retro68" then null else prevPkgs.libcCrossChooser name; - + gcc = + if (prevPkgs.targetPlatform ? retro68) then + pkgs.retro68.gcc + else + prevPkgs.gcc; } diff --git a/nix/platforms.nix b/nix/platforms.nix index 3f36c5956b..d3683cadef 100644 --- a/nix/platforms.nix +++ b/nix/platforms.nix @@ -2,7 +2,7 @@ m68k = { system = "m68k-macos"; config = "m68k-apple-macos"; - libc = "retro68"; + libc = null; parsed = { cpu = { name = "m68k"; @@ -14,6 +14,8 @@ name = "macos"; execFormat = { name = "unknown"; }; }; + vendor = { name = "apple"; }; + abi = { name = "macos"; }; }; bfdEmulation = "m68k"; isStatic = true; @@ -25,7 +27,7 @@ powerpc = { system = "powerpc-macos"; config = "powerpc-apple-macos"; - libc = "retro68"; + libc = null; parsed = { cpu = { name = "powerpc"; @@ -37,6 +39,8 @@ name = "macos"; execFormat = { name = "unknown"; }; }; + vendor = { name = "apple"; }; + abi = { name = "macos"; }; }; isStatic = true; @@ -48,7 +52,7 @@ carbon = { system = "powerpc-carbon"; config = "powerpc-apple-macos"; - libc = "retro68"; + libc = null; parsed = { cpu = { name = "powerpc"; @@ -60,6 +64,8 @@ name = "carbon"; execFormat = { name = "unknown"; }; }; + vendor = { name = "apple"; }; + abi = { name = "macos"; }; }; isStatic = true; retro68BinutilsConfig = [ "--disable-plugins" ]; @@ -67,9 +73,4 @@ retro68 = true; cmakeSystemName = "RetroCarbon"; }; - - isStatic = true; - retro68BinutilsConfig = [ "--disable-plugins" ]; - retro68GccConfig = [ "--disable-lto" ]; - retro68 = true; } diff --git a/nix/samples.nix b/nix/samples.nix index 24f9ac71d7..3c4d9e4d19 100644 --- a/nix/samples.nix +++ b/nix/samples.nix @@ -2,18 +2,20 @@ pkgs: prevPkgs: { retro68 = prevPkgs.retro68.overrideScope' (self: prevRetro: { samples = with pkgs; let - individualSamples = lib.mapAttrs (key: path: - stdenv.mkDerivation { - name = "retro68.samples." + key; - src = path; - nativeBuildInputs = [ buildPackages.ninja buildPackages.cmake ]; - buildInputs = [ retro68.console ]; - installPhase = '' - mkdir $out - cp *.bin $out/ - rm -f $out/*.code.bin $out/*.rsrc.bin - ''; - }) ({ + individualSamples = lib.mapAttrs + (key: path: + stdenv.mkDerivation { + name = "retro68.samples." + key; + src = path; + nativeBuildInputs = [ buildPackages.ninja buildPackages.cmake ]; + buildInputs = [ retro68.console ]; + installPhase = '' + mkdir $out + cp *.bin $out/ + rm -f $out/*.code.bin $out/*.rsrc.bin + ''; + }) + ({ dialog = ../Samples/Dialog; helloworld = ../Samples/HelloWorld; raytracer = ../Samples/Raytracer; @@ -25,8 +27,9 @@ pkgs: prevPkgs: { } // lib.optionalAttrs (targetPlatform.cmakeSystemName == "Retro68") { systemextension = ../Samples/SystemExtension; launcher = ../Samples/Launcher; - }) // { launchapplserver = self.launchapplserver; }; - in runCommand "retro68.samples" { } '' + }) // { launchapplserver = self.launchapplserver; }; + in + runCommand "retro68.samples" { } '' mkdir -p $out/ ${lib.concatMapStrings (x: '' diff --git a/nix/sources.json b/nix/sources.json index f017eed65e..13b4dfc2d2 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -5,10 +5,10 @@ "homepage": null, "owner": "autc04", "repo": "multiversal", - "rev": "ce33b1bada9b0acb14021c21ac916927c757d525", - "sha256": "1fsyjad4kwsqgr2mlx9dfl7z8z42cf2sgw1arqmci47zhaj8is1f", + "rev": "27c08c654bbd48d23f025741e3a584b59374904a", + "sha256": "1b022pvpjw3n6713zq09abgbm0iba6lr16czhjxi1yk23xchny0s", "type": "tarball", - "url": "https://github.com/autc04/multiversal/archive/ce33b1bada9b0acb14021c21ac916927c757d525.tar.gz", + "url": "https://github.com/autc04/multiversal/archive/27c08c654bbd48d23f025741e3a584b59374904a.tar.gz", "url_template": "https://github.com///archive/.tar.gz" }, "niv": { @@ -17,22 +17,22 @@ "homepage": "https://github.com/nmattia/niv", "owner": "nmattia", "repo": "niv", - "rev": "5830a4dd348d77e39a0f3c4c762ff2663b602d4c", - "sha256": "1d3lsrqvci4qz2hwjrcnd8h5vfkg8aypq3sjd4g3izbc8frwz5sm", + "rev": "6bd7cd686220bf3db0e212481faf9578e8c8ff0f", + "sha256": "15claxlj6y15db67qc7kb4vzyn6sv7r13z4q502vq7a4z2488z94", "type": "tarball", - "url": "https://github.com/nmattia/niv/archive/5830a4dd348d77e39a0f3c4c762ff2663b602d4c.tar.gz", + "url": "https://github.com/nmattia/niv/archive/6bd7cd686220bf3db0e212481faf9578e8c8ff0f.tar.gz", "url_template": "https://github.com///archive/.tar.gz" }, "nixpkgs": { - "branch": "release-21.11", + "branch": "nixos-23.11", "description": "Nix Packages collection", "homepage": "", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d1e59cfc49961e121583abe32e2f3db1550fbcff", - "sha256": "03ldf1dlxqf3g8qh9x5vp6vd9zvvr481fyjds111imll69y60wpm", + "rev": "0b3d618173114c64ab666f557504d6982665d328", + "sha256": "1p941x8rx6hq8zrcmwnw6rnxd4v0v7vn1v5a763lmjxcfglz965b", "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/d1e59cfc49961e121583abe32e2f3db1550fbcff.tar.gz", + "url": "https://github.com/NixOS/nixpkgs/archive/0b3d618173114c64ab666f557504d6982665d328.tar.gz", "url_template": "https://github.com///archive/.tar.gz" } } diff --git a/nix/sources.nix b/nix/sources.nix index 1938409ddd..fe3dadf7eb 100644 --- a/nix/sources.nix +++ b/nix/sources.nix @@ -10,29 +10,50 @@ let let name' = sanitizeName name + "-src"; in - if spec.builtin or true then - builtins_fetchurl { inherit (spec) url sha256; name = name'; } - else - pkgs.fetchurl { inherit (spec) url sha256; name = name'; }; + if spec.builtin or true then + builtins_fetchurl { inherit (spec) url sha256; name = name'; } + else + pkgs.fetchurl { inherit (spec) url sha256; name = name'; }; fetch_tarball = pkgs: name: spec: let name' = sanitizeName name + "-src"; in - if spec.builtin or true then - builtins_fetchTarball { name = name'; inherit (spec) url sha256; } - else - pkgs.fetchzip { name = name'; inherit (spec) url sha256; }; + if spec.builtin or true then + builtins_fetchTarball { name = name'; inherit (spec) url sha256; } + else + pkgs.fetchzip { name = name'; inherit (spec) url sha256; }; fetch_git = name: spec: let ref = - if spec ? ref then spec.ref else + spec.ref or ( if spec ? branch then "refs/heads/${spec.branch}" else - if spec ? tag then "refs/tags/${spec.tag}" else - abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!"; + if spec ? tag then "refs/tags/${spec.tag}" else + abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!" + ); + submodules = spec.submodules or false; + submoduleArg = + let + nixSupportsSubmodules = builtins.compareVersions builtins.nixVersion "2.4" >= 0; + emptyArgWithWarning = + if submodules + then + builtins.trace + ( + "The niv input \"${name}\" uses submodules " + + "but your nix's (${builtins.nixVersion}) builtins.fetchGit " + + "does not support them" + ) + { } + else { }; + in + if nixSupportsSubmodules + then { inherit submodules; } + else emptyArgWithWarning; in - builtins.fetchGit { url = spec.repo; inherit (spec) rev; inherit ref; }; + builtins.fetchGit + ({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg); fetch_local = spec: spec.path; @@ -66,16 +87,16 @@ let hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; hasThisAsNixpkgsPath = == ./.; in - if builtins.hasAttr "nixpkgs" sources - then sourcesNixpkgs - else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then - import {} - else - abort - '' - Please specify either (through -I or NIX_PATH=nixpkgs=...) or - add a package called "nixpkgs" to your sources.json. - ''; + if builtins.hasAttr "nixpkgs" sources + then sourcesNixpkgs + else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then + import { } + else + abort + '' + Please specify either (through -I or NIX_PATH=nixpkgs=...) or + add a package called "nixpkgs" to your sources.json. + ''; # The actual fetching function. fetch = pkgs: name: spec: @@ -95,13 +116,13 @@ let # the path directly as opposed to the fetched source. replace = name: drv: let - saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name; + saneName = stringAsChars (c: if (builtins.match "[a-zA-Z0-9]" c) == null then "_" else c) name; ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}"; in - if ersatz == "" then drv else - # this turns the string into an actual Nix path (for both absolute and - # relative paths) - if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}"; + if ersatz == "" then drv else + # this turns the string into an actual Nix path (for both absolute and + # relative paths) + if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}"; # Ports of functions for older nix versions @@ -112,7 +133,7 @@ let ); # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295 - range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1); + range = first: last: if first > last then [ ] else builtins.genList (n: first + n) (last - first + 1); # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257 stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1)); @@ -123,43 +144,46 @@ let concatStrings = builtins.concatStringsSep ""; # https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331 - optionalAttrs = cond: as: if cond then as else {}; + optionalAttrs = cond: as: if cond then as else { }; # fetchTarball version that is compatible between all the versions of Nix builtins_fetchTarball = { url, name ? null, sha256 }@attrs: let inherit (builtins) lessThan nixVersion fetchTarball; in - if lessThan nixVersion "1.12" then - fetchTarball ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; })) - else - fetchTarball attrs; + if lessThan nixVersion "1.12" then + fetchTarball ({ inherit url; } // (optionalAttrs (name != null) { inherit name; })) + else + fetchTarball attrs; # fetchurl version that is compatible between all the versions of Nix builtins_fetchurl = { url, name ? null, sha256 }@attrs: let inherit (builtins) lessThan nixVersion fetchurl; in - if lessThan nixVersion "1.12" then - fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; })) - else - fetchurl attrs; + if lessThan nixVersion "1.12" then + fetchurl ({ inherit url; } // (optionalAttrs (name != null) { inherit name; })) + else + fetchurl attrs; # Create the final "sources" from the config mkSources = config: - mapAttrs ( - name: spec: - if builtins.hasAttr "outPath" spec - then abort - "The values in sources.json should not have an 'outPath' attribute" - else - spec // { outPath = replace name (fetch config.pkgs name spec); } - ) config.sources; + mapAttrs + ( + name: spec: + if builtins.hasAttr "outPath" spec + then + abort + "The values in sources.json should not have an 'outPath' attribute" + else + spec // { outPath = replace name (fetch config.pkgs name spec); } + ) + config.sources; # The "config" used by the fetchers mkConfig = { sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null - , sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile) + , sources ? if sourcesFile == null then { } else builtins.fromJSON (builtins.readFile sourcesFile) , system ? builtins.currentSystem , pkgs ? mkPkgs sources system }: rec { @@ -171,4 +195,4 @@ let }; in -mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); } +mkSources (mkConfig { }) // { __functor = _: settings: mkSources (mkConfig settings); } diff --git a/nix/universal.nix b/nix/universal.nix index 1f7df2856b..4648ef0db5 100644 --- a/nix/universal.nix +++ b/nix/universal.nix @@ -1,59 +1,59 @@ pkgs: prevPkgs: { - retro68 = if !(prevPkgs.hostPlatform ? retro68) then - prevPkgs.retro68 - else - prevPkgs.retro68.overrideScope' (self: prevRetro: { + retro68 = + if !(prevPkgs.hostPlatform ? retro68) then + prevPkgs.retro68 + else + prevPkgs.retro68.overrideScope' (self: prevRetro: { - mpw_35_gm = with pkgs; - fetchurl { - url = - "https://web.archive.org/web/20210309154524/https://staticky.com/mirrors/ftp.apple.com/developer/Tool_Chest/Core_Mac_OS_Tools/MPW_etc./MPW-GM_Images/MPW-GM.img.bin"; - sha256 = "0wm8dwmm0cpp8px27in564ih27sn5vbydz3jqpzwh04qpfazmfwr"; - }; + mpw_35_gm = with pkgs; + fetchurl { + url = + "https://web.archive.org/web/20210309154524/https://staticky.com/mirrors/ftp.apple.com/developer/Tool_Chest/Core_Mac_OS_Tools/MPW_etc./MPW-GM_Images/MPW-GM.img.bin"; + sha256 = "0wm8dwmm0cpp8px27in564ih27sn5vbydz3jqpzwh04qpfazmfwr"; + }; - universal = with pkgs; - stdenvNoCC.mkDerivation { - name = "retro68.universal"; - src = retro68.mpw_35_gm; - nativeBuildInputs = with buildPackages.retro68; [ - tools - hfsutils - binutils_unwrapped - ]; + universal = with pkgs; + stdenvNoCC.mkDerivation { + name = "retro68.universal"; + src = retro68.mpw_35_gm; + nativeBuildInputs = with buildPackages.retro68; [ + tools + hfsutils + binutils_unwrapped + ]; - buildCommand = '' - ConvertDiskImage $src decoded.dsk - export HOME=. - hmount decoded.dsk - mkdir -p CIncludes RIncludes - hcopy -t 'MPW-GM:MPW-GM:Interfaces&Libraries:Interfaces:CIncludes:*.h' CIncludes/ - hcopy -t 'MPW-GM:MPW-GM:Interfaces&Libraries:Interfaces:RIncludes:*.r' RIncludes/ - mkdir -p $out/include $out/RIncludes - bash ${../prepare-headers.sh} CIncludes $out/include - bash ${../prepare-rincludes.sh} RIncludes $out/RIncludes + buildCommand = '' + ConvertDiskImage $src decoded.dsk + export HOME=. + hmount decoded.dsk + mkdir -p CIncludes RIncludes + hcopy -t 'MPW-GM:MPW-GM:Interfaces&Libraries:Interfaces:CIncludes:*.h' CIncludes/ + hcopy -t 'MPW-GM:MPW-GM:Interfaces&Libraries:Interfaces:RIncludes:*.r' RIncludes/ + mkdir -p $out/include $out/RIncludes + bash ${../prepare-headers.sh} CIncludes $out/include + bash ${../prepare-rincludes.sh} RIncludes $out/RIncludes - . ${../interfaces-and-libraries.sh} - '' + (pkgs.lib.optionalString (pkgs.targetPlatform.cmakeSystemName == "Retro68") '' - mkdir -p lib68 - hcopy -r 'MPW-GM:MPW-GM:Interfaces&Libraries:Libraries:Libraries:*.o' lib68 - M68KLIBRARIES=lib68 - setup68KLibraries $out/ - mv $out/lib68k $out/lib - '') + (pkgs.lib.optionalString (pkgs.targetPlatform.cmakeSystemName != "Retro68") '' - mkdir -p libppc peflibs - hcopy -r 'MPW-GM:MPW-GM:Interfaces&Libraries:Libraries:PPCLibraries:*.o' libppc - hcopy -m 'MPW-GM:MPW-GM:Interfaces&Libraries:Libraries:SharedLibraries:*' peflibs - PPCLIBRARIES=libppc - SHAREDLIBRARIES=peflibs - INTERFACELIB=peflibs/InterfaceLib.bin + . ${../interfaces-and-libraries.sh} + '' + (pkgs.lib.optionalString (pkgs.targetPlatform.cmakeSystemName == "Retro68") '' + mkdir -p lib68 + hcopy -r 'MPW-GM:MPW-GM:Interfaces&Libraries:Libraries:Libraries:*.o' lib68 + M68KLIBRARIES=lib68 + setup68KLibraries $out/ + mv $out/lib68k $out/lib + '') + (pkgs.lib.optionalString (pkgs.targetPlatform.cmakeSystemName != "Retro68") '' + mkdir -p libppc peflibs + hcopy -r 'MPW-GM:MPW-GM:Interfaces&Libraries:Libraries:PPCLibraries:*.o' libppc + hcopy -m 'MPW-GM:MPW-GM:Interfaces&Libraries:Libraries:SharedLibraries:*' peflibs + PPCLIBRARIES=libppc + SHAREDLIBRARIES=peflibs + INTERFACELIB=peflibs/InterfaceLib.bin - setupPPCLibraries $out/ - mv $out/libppc $out/lib - ''); - }; - }); -} // prevPkgs.lib.optionalAttrs (prevPkgs.targetPlatform ? retro68) { + setupPPCLibraries $out/ + mv $out/libppc $out/lib + ''); + }; + }); stdenvUniversal = pkgs.stdenv.override { cc = pkgs.stdenv.cc.override {