{ stdenv, fetchFromGitHub, overrideCC, gcc5 , makeWrapper, unzip, which , curl, tzdata, gdb, darwin , callPackage , bootstrapVersion ? false , version ? "2.075.1" , dmdSha256 ? "0kq6r8rcghvzk5jcphg89l85rg734s29bssd2rcw3fygx0k9a9k5" , druntimeSha256 ? "0idn2v1lmp7hl637g3i7pdfj9mjk4sclkz4cm77nl8873k2fhk8j" , phobosSha256 ? "1a7q5fd15yspgs5plxgx54jyrcwgzlyw3rahmz04jd2s5h56dj04" }: let bootstrapDmd = if !bootstrapVersion then # Versions 2.070.2 and up require a working dmd compiler to build so we just # use the last dmd without any D code to bootstrap the actual build. callPackage ./default.nix { stdenv = if stdenv.hostPlatform.isDarwin then stdenv else # Doesn't build with gcc6 on linux overrideCC stdenv gcc5; bootstrapVersion = true; version = "2.067.1"; dmdSha256 = "0fm29lg8axfmzdaj0y6vg70lhwb5d9rv4aavnvdd15xjschinlcz"; druntimeSha256 = "1n2qfw9kmnql0fk2nxikispqs7vh85nhvyyr00fk227n9lgnqf02"; phobosSha256 = "0fywgds9xvjcgnqxmpwr67p3wi2m535619pvj159cgwv5y0nr3p1"; } else ""; dmdBuild = stdenv.mkDerivation rec { name = "dmdBuild-${version}"; inherit version; enableParallelBuilding = true; srcs = [ (fetchFromGitHub { owner = "dlang"; repo = "dmd"; rev = "v${version}"; sha256 = dmdSha256; name = "dmd"; }) (fetchFromGitHub { owner = "dlang"; repo = "druntime"; rev = "v${version}"; sha256 = druntimeSha256; name = "druntime"; }) (fetchFromGitHub { owner = "dlang"; repo = "phobos"; rev = "v${version}"; sha256 = phobosSha256; name = "phobos"; }) ]; sourceRoot = "."; postUnpack = '' patchShebangs . # Remove cppa test for now because it doesn't work. rm dmd/test/runnable/cppa.d rm dmd/test/runnable/extra-files/cppb.cpp ''; # Compile with PIC to prevent colliding modules with binutils 2.28. # https://issues.dlang.org/show_bug.cgi?id=17375 usePIC = "-fPIC"; ROOT_HOME_DIR = "$(echo ~root)"; datetimePath = if bootstrapVersion then "phobos/std/datetime.d" else "phobos/std/datetime/timezone.d"; phobosPatches = '' substituteInPlace ${datetimePath} \ --replace "import core.time;" "import core.time;import std.path;" substituteInPlace ${datetimePath} \ --replace "tzName == \"leapseconds\"" "baseName(tzName) == \"leapseconds\"" # Ugly hack to fix the hardcoded path to zoneinfo in the source file. # https://issues.dlang.org/show_bug.cgi?id=15391 substituteInPlace ${datetimePath} \ --replace /usr/share/zoneinfo/ ${tzdata}/share/zoneinfo/ # Ugly hack so the dlopen call has a chance to succeed. # https://issues.dlang.org/show_bug.cgi?id=15391 substituteInPlace phobos/std/net/curl.d \ --replace libcurl.so ${curl.out}/lib/libcurl.so # phobos uses curl, so we need to patch the path to the lib. substituteInPlace phobos/posix.mak \ --replace "-soname=libcurl.so.4" "-soname=${curl.out}/lib/libcurl.so.4" '' + stdenv.lib.optionalString (bootstrapVersion) '' substituteInPlace ${datetimePath} \ --replace "import std.traits;" "import std.traits;import std.path;" substituteInPlace ${datetimePath} \ --replace "tzName == \"+VERSION\"" "baseName(tzName) == \"leapseconds\" || tzName == \"+VERSION\"" '' + stdenv.lib.optionalString stdenv.hostPlatform.isLinux '' # See https://github.com/NixOS/nixpkgs/issues/29443 substituteInPlace phobos/std/path.d \ --replace "\"/root" "\"${ROOT_HOME_DIR}" ''; dmdPath = if bootstrapVersion then "dmd/src" else "dmd"; postPatch = '' # Use proper C++ compiler substituteInPlace ${dmdPath}/posix.mak \ --replace g++ $CXX # TODO substituteInPlace druntime/src/core/memory.d \ --replace "assert(z is null);" "//assert(z is null);" '' + stdenv.lib.optionalString (!bootstrapVersion) '' substituteInPlace druntime/test/common.mak \ --replace "DFLAGS:=" "DFLAGS:=${usePIC} " '' + phobosPatches + stdenv.lib.optionalString (stdenv.hostPlatform.isLinux && bootstrapVersion) '' substituteInPlace ${dmdPath}/root/port.c \ --replace "#include " "#include " '' + stdenv.lib.optionalString stdenv.hostPlatform.isDarwin '' substituteInPlace ${dmdPath}/posix.mak \ --replace MACOSX_DEPLOYMENT_TARGET MACOSX_DEPLOYMENT_TARGET_ '' + stdenv.lib.optionalString (stdenv.hostPlatform.isDarwin && bootstrapVersion) '' # Was not able to compile on darwin due to "__inline_isnanl" # being undefined. substituteInPlace ${dmdPath}/root/port.c --replace __inline_isnanl __inline_isnan ''; nativeBuildInputs = [ bootstrapDmd makeWrapper unzip which gdb ] ++ stdenv.lib.optional stdenv.hostPlatform.isDarwin (with darwin.apple_sdk.frameworks; [ Foundation ]); buildInputs = [ curl tzdata ]; bits = builtins.toString stdenv.hostPlatform.parsed.cpu.bits; osname = if stdenv.hostPlatform.isDarwin then "osx" else stdenv.hostPlatform.parsed.kernel.name; top = "$(echo $NIX_BUILD_TOP)"; pathToDmd = if bootstrapVersion then "${top}/dmd/src/dmd" else "${top}/dmd/generated/${osname}/release/${bits}/dmd"; # Buid and install are based on http://wiki.dlang.org/Building_DMD buildPhase = '' cd dmd make -j$NIX_BUILD_CORES -f posix.mak INSTALL_DIR=$out cd ../druntime make -j$NIX_BUILD_CORES -f posix.mak PIC=1 INSTALL_DIR=$out DMD=${pathToDmd} cd ../phobos make -j$NIX_BUILD_CORES -f posix.mak PIC=1 INSTALL_DIR=$out DMD=${pathToDmd} cd .. ''; doCheck = !bootstrapVersion; checkPhase = '' cd dmd make -j$NIX_BUILD_CORES -C test -f Makefile PIC=1 DMD=${pathToDmd} BUILD=release SHARED=0 SHELL=$SHELL cd ../druntime make -j$NIX_BUILD_CORES -f posix.mak unittest PIC=1 DMD=${pathToDmd} BUILD=release cd .. ''; extension = if stdenv.hostPlatform.isDarwin then "a" else "{a,so}"; installPhase = '' cd dmd mkdir $out mkdir $out/bin cp ${pathToDmd} $out/bin mkdir -p $out/share/man/man1 mkdir -p $out/share/man/man5 cp -r docs/man/man1/* $out/share/man/man1/ cp -r docs/man/man5/* $out/share/man/man5/ cd ../druntime mkdir $out/include mkdir $out/include/d2 cp -r import/* $out/include/d2 cd ../phobos mkdir $out/lib cp generated/${osname}/release/${bits}/libphobos2.${extension} $out/lib cp -r std $out/include/d2 cp -r etc $out/include/d2 wrapProgram $out/bin/dmd \ --prefix PATH ":" "${stdenv.cc}/bin" \ --set-default CC "$CC" cd $out/bin tee dmd.conf << EOF [Environment] DFLAGS=-I$out/include/d2 -L-L$out/lib ${stdenv.lib.optionalString (!stdenv.cc.isClang) "-L--export-dynamic"} -fPIC EOF ''; meta = with stdenv.lib; { description = "Official reference compiler for the D language"; homepage = http://dlang.org/; # Everything is now Boost licensed, even the backend. # https://github.com/dlang/dmd/pull/6680 license = licenses.boost; maintainers = with maintainers; [ ThomasMader ]; platforms = [ "x86_64-linux" "i686-linux" "x86_64-darwin" ]; }; }; # Need to test Phobos in a fixed-output derivation, otherwise the # network stuff in Phobos would fail if sandbox mode is enabled. phobosUnittests = stdenv.mkDerivation rec { name = "phobosUnittests-${version}"; version = dmdBuild.version; enableParallelBuilding = dmdBuild.enableParallelBuilding; preferLocalBuild = true; inputString = dmdBuild.outPath; outputHashAlgo = "sha256"; outputHash = builtins.hashString "sha256" inputString; srcs = dmdBuild.srcs; sourceRoot = "."; postPatch = dmdBuild.phobosPatches; nativeBuildInputs = dmdBuild.nativeBuildInputs; buildInputs = dmdBuild.buildInputs; buildPhase = '' cd phobos make -j$NIX_BUILD_CORES -f posix.mak unittest PIC=1 DMD=${dmdBuild}/bin/dmd BUILD=release ''; installPhase = '' echo -n $inputString > $out ''; }; in stdenv.mkDerivation rec { inherit phobosUnittests; name = "dmd-${version}"; phases = "installPhase"; installPhase = '' mkdir $out cp -r --symbolic-link ${dmdBuild}/* $out/ ''; }