diff --git a/pkgs/build-support/cc-wrapper/add-flags.sh b/pkgs/build-support/cc-wrapper/add-flags.sh index 1358b167f6ec..323ea5bfd772 100644 --- a/pkgs/build-support/cc-wrapper/add-flags.sh +++ b/pkgs/build-support/cc-wrapper/add-flags.sh @@ -10,6 +10,7 @@ var_templates_list=( NIX+CFLAGS_LINK NIX+CXXSTDLIB_COMPILE NIX+CXXSTDLIB_LINK + NIX+GNATFLAGS_COMPILE ) var_templates_bool=( NIX+ENFORCE_NO_NATIVE @@ -40,6 +41,10 @@ if [ -e @out@/nix-support/cc-cflags ]; then NIX_@infixSalt@_CFLAGS_COMPILE="$(< @out@/nix-support/cc-cflags) $NIX_@infixSalt@_CFLAGS_COMPILE" fi +if [ -e @out@/nix-support/gnat-cflags ]; then + NIX_@infixSalt@_GNATFLAGS_COMPILE="$(< @out@/nix-support/gnat-cflags) $NIX_@infixSalt@_GNATFLAGS_COMPILE" +fi + if [ -e @out@/nix-support/cc-ldflags ]; then NIX_@infixSalt@_LDFLAGS+=" $(< @out@/nix-support/cc-ldflags)" fi diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index f6248335052c..1b7c5750727a 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -199,6 +199,12 @@ stdenv.mkDerivation { fi '' + + optionalString cc.langAda or false '' + wrap ${targetPrefix}gnatmake ${./gnat-wrapper.sh} $ccPath/${targetPrefix}gnatmake + wrap ${targetPrefix}gnatbind ${./gnat-wrapper.sh} $ccPath/${targetPrefix}gnatbind + wrap ${targetPrefix}gnatlink ${./gnat-wrapper.sh} $ccPath/${targetPrefix}gnatlink + '' + + optionalString cc.langFortran or false '' wrap ${targetPrefix}gfortran $wrapper $ccPath/${targetPrefix}gfortran ln -sv ${targetPrefix}gfortran $out/bin/${targetPrefix}g77 @@ -283,6 +289,13 @@ stdenv.mkDerivation { ccLDFlags+=" -L${cc_solib}/lib" ccCFlags+=" -B${cc_solib}/lib" + '' + optionalString cc.langAda or false '' + basePath=$(echo $cc/lib/*/*/*) + ccCFlags+=" -B$basePath -I$basePath/adainclude" + gnatCFlags="-I$basePath/adainclude -I$basePath/adalib" + + echo "$gnatCFlags" > $out/nix-support/gnat-cflags + '' + '' echo "$ccLDFlags" > $out/nix-support/cc-ldflags echo "$ccCFlags" > $out/nix-support/cc-cflags '' + optionalString (targetPlatform.isDarwin && (libcxx != null) && (cc.isClang or false)) '' @@ -351,6 +364,8 @@ stdenv.mkDerivation { hardening_unsupported_flags+=" stackprotector fortify pie pic" '' + optionalString targetPlatform.isNetBSD '' hardening_unsupported_flags+=" stackprotector fortify" + '' + optionalString cc.langAda or false '' + hardening_unsupported_flags+=" stackprotector strictoverflow" '' + optionalString targetPlatform.isWasm '' diff --git a/pkgs/build-support/cc-wrapper/gnat-wrapper.sh b/pkgs/build-support/cc-wrapper/gnat-wrapper.sh new file mode 100644 index 000000000000..15b53d76c630 --- /dev/null +++ b/pkgs/build-support/cc-wrapper/gnat-wrapper.sh @@ -0,0 +1,165 @@ +#! @shell@ +set -eu -o pipefail +o posix +shopt -s nullglob + +if (( "${NIX_DEBUG:-0}" >= 7 )); then + set -x +fi + +path_backup="$PATH" + +# That @-vars are substituted separately from bash evaluation makes +# shellcheck think this, and others like it, are useless conditionals. +# shellcheck disable=SC2157 +if [[ -n "@coreutils_bin@" && -n "@gnugrep_bin@" ]]; then + PATH="@coreutils_bin@/bin:@gnugrep_bin@/bin" +fi + +source @out@/nix-support/utils.bash + +# Flirting with a layer violation here. +if [ -z "${NIX_BINTOOLS_WRAPPER_@infixSalt@_FLAGS_SET:-}" ]; then + source @bintools@/nix-support/add-flags.sh +fi + +# Put this one second so libc ldflags take priority. +if [ -z "${NIX_CC_WRAPPER_@infixSalt@_FLAGS_SET:-}" ]; then + source @out@/nix-support/add-flags.sh +fi + + +# Parse command line options and set several variables. +# For instance, figure out if linker flags should be passed. +# GCC prints annoying warnings when they are not needed. +dontLink=0 +nonFlagArgs=0 +# shellcheck disable=SC2193 + +expandResponseParams "$@" +declare -i n=0 +nParams=${#params[@]} +while (( "$n" < "$nParams" )); do + p=${params[n]} + p2=${params[n+1]:-} # handle `p` being last one + if [ "$p" = -c ]; then + dontLink=1 + elif [ "$p" = -S ]; then + dontLink=1 + elif [ "$p" = -E ]; then + dontLink=1 + elif [ "$p" = -E ]; then + dontLink=1 + elif [ "$p" = -M ]; then + dontLink=1 + elif [ "$p" = -MM ]; then + dontLink=1 + elif [[ "$p" = -x && "$p2" = *-header ]]; then + dontLink=1 + elif [[ "$p" != -?* ]]; then + # A dash alone signifies standard input; it is not a flag + nonFlagArgs=1 + fi + n+=1 +done + +# If we pass a flag like -Wl, then gcc will call the linker unless it +# can figure out that it has to do something else (e.g., because of a +# "-c" flag). So if no non-flag arguments are given, don't pass any +# linker flags. This catches cases like "gcc" (should just print +# "gcc: no input files") and "gcc -v" (should print the version). +if [ "$nonFlagArgs" = 0 ]; then + dontLink=1 +fi + +# Optionally filter out paths not refering to the store. +if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "$NIX_STORE" ]]; then + rest=() + nParams=${#params[@]} + declare -i n=0 + while (( "$n" < "$nParams" )); do + p=${params[n]} + p2=${params[n+1]:-} # handle `p` being last one + if [ "${p:0:3}" = -L/ ] && badPath "${p:2}"; then + skip "${p:2}" + elif [ "$p" = -L ] && badPath "$p2"; then + n+=1; skip "$p2" + elif [ "${p:0:3}" = -I/ ] && badPath "${p:2}"; then + skip "${p:2}" + elif [ "$p" = -I ] && badPath "$p2"; then + n+=1; skip "$p2" + elif [ "${p:0:4}" = -aI/ ] && badPath "${p:3}"; then + skip "${p:3}" + elif [ "$p" = -aI ] && badPath "$p2"; then + n+=1; skip "$p2" + elif [ "${p:0:4}" = -aO/ ] && badPath "${p:3}"; then + skip "${p:3}" + elif [ "$p" = -aO ] && badPath "$p2"; then + n+=1; skip "$p2" + elif [ "$p" = -isystem ] && badPath "$p2"; then + n+=1; skip "$p2" + else + rest+=("$p") + fi + n+=1 + done + # Old bash empty array hack + params=(${rest+"${rest[@]}"}) +fi + + +# Clear march/mtune=native -- they bring impurity. +if [ "$NIX_@infixSalt@_ENFORCE_NO_NATIVE" = 1 ]; then + rest=() + # Old bash empty array hack + for p in ${params+"${params[@]}"}; do + if [[ "$p" = -m*=native ]]; then + skip "$p" + else + rest+=("$p") + fi + done + # Old bash empty array hack + params=(${rest+"${rest[@]}"}) +fi + +if [ "$(basename $0)x" = "gnatmakex" ]; then + extraBefore=("--GNATBIND=@out@/bin/gnatbind" "--GNATLINK=@out@/bin/gnatlink") + extraAfter=($NIX_@infixSalt@_GNATFLAGS_COMPILE) +fi + +if [ "$(basename $0)x" = "gnatbindx" ]; then + extraBefore=() + extraAfter=($NIX_@infixSalt@_GNATFLAGS_COMPILE) +fi + +if [ "$(basename $0)x" = "gnatlinkx" ]; then + extraBefore=() + extraAfter=("--GCC=@out@/bin/gcc") +fi + +# As a very special hack, if the arguments are just `-v', then don't +# add anything. This is to prevent `gcc -v' (which normally prints +# out the version number and returns exit code 0) from printing out +# `No input files specified' and returning exit code 1. +if [ "$*" = -v ]; then + extraAfter=() + extraBefore=() +fi + +# Optionally print debug info. +if (( "${NIX_DEBUG:-0}" >= 1 )); then + # Old bash workaround, see ld-wrapper for explanation. + echo "extra flags before to @prog@:" >&2 + printf " %q\n" ${extraBefore+"${extraBefore[@]}"} >&2 + echo "original flags to @prog@:" >&2 + printf " %q\n" ${params+"${params[@]}"} >&2 + echo "extra flags after to @prog@:" >&2 + printf " %q\n" ${extraAfter+"${extraAfter[@]}"} >&2 +fi + +PATH="$path_backup" +# Old bash workaround, see above. +exec @prog@ \ + ${extraBefore+"${extraBefore[@]}"} \ + ${params+"${params[@]}"} \ + ${extraAfter+"${extraAfter[@]}"} diff --git a/pkgs/development/compilers/gcc/6/default.nix b/pkgs/development/compilers/gcc/6/default.nix index 1adffa8174e5..c04e424b2faa 100644 --- a/pkgs/development/compilers/gcc/6/default.nix +++ b/pkgs/development/compilers/gcc/6/default.nix @@ -1,5 +1,6 @@ { stdenv, targetPackages, fetchurl, fetchpatch, fetchFromGitHub, noSysDirs , langC ? true, langCC ? true, langFortran ? false +, langAda ? false , langObjC ? stdenv.targetPlatform.isDarwin , langObjCpp ? stdenv.targetPlatform.isDarwin , langJava ? false @@ -15,6 +16,7 @@ , libelf # optional, for link-time optimizations (LTO) , isl ? null # optional, for the Graphite optimization framework. , zlib ? null, boehmgc ? null +, gnatboot ? null , zip ? null, unzip ? null, pkgconfig ? null , gtk2 ? null, libart_lgpl ? null , libX11 ? null, libXt ? null, libSM ? null, libICE ? null, libXtst ? null @@ -48,6 +50,8 @@ assert stdenv.hostPlatform.isDarwin -> gnused != null; # The go frontend is written in c++ assert langGo -> langCC; +assert langAda -> gnatboot != null; + # threadsCross is just for MinGW assert threadsCross != null -> stdenv.targetPlatform.isWindows; @@ -63,6 +67,7 @@ let majorVersion = "6"; [ ../use-source-date-epoch.patch ] ++ optional (targetPlatform != hostPlatform) ../libstdc++-target.patch ++ optional noSysDirs ../no-sys-dirs.patch + ++ optional langAda ../gnat-cflags.patch ++ optional langFortran ../gfortran-driving.patch ++ optional (targetPlatform.libc == "musl") ../libgomp-dont-force-initial-exec.patch ++ optional (!crossStageStatic && targetPlatform.isMinGW) (fetchpatch { @@ -200,6 +205,7 @@ stdenv.mkDerivation ({ # The builder relies on GNU sed (for instance, Darwin's `sed' fails with # "-i may not be used with stdin"), and `stdenvNative' doesn't provide it. ++ (optional hostPlatform.isDarwin gnused) + ++ (optional langAda gnatboot) ; depsTargetTarget = optional (!crossStageStatic && threadsCross != null) threadsCross; @@ -208,7 +214,7 @@ stdenv.mkDerivation ({ preConfigure = import ../common/pre-configure.nix { inherit (stdenv) lib; - inherit version hostPlatform langJava langGo; + inherit version hostPlatform gnatboot langJava langAda langGo; }; dontDisableStatic = true; @@ -234,6 +240,7 @@ stdenv.mkDerivation ({ langCC langFortran langJava javaAwtGtk javaAntlr javaEcj + langAda langGo langObjC langObjCpp @@ -292,7 +299,7 @@ stdenv.mkDerivation ({ ; passthru = { - inherit langC langCC langObjC langObjCpp langFortran langGo version; + inherit langC langCC langObjC langObjCpp langFortran langAda langGo version; isGNU = true; }; diff --git a/pkgs/development/compilers/gcc/9/default.nix b/pkgs/development/compilers/gcc/9/default.nix index a6ba8c9c0f64..5785782a6718 100644 --- a/pkgs/development/compilers/gcc/9/default.nix +++ b/pkgs/development/compilers/gcc/9/default.nix @@ -1,5 +1,6 @@ { stdenv, targetPackages, fetchurl, fetchpatch, noSysDirs , langC ? true, langCC ? true, langFortran ? false +, langAda ? false , langObjC ? stdenv.targetPlatform.isDarwin , langObjCpp ? stdenv.targetPlatform.isDarwin , langGo ? false @@ -13,6 +14,7 @@ , libelf # optional, for link-time optimizations (LTO) , isl ? null # optional, for the Graphite optimization framework. , zlib ? null +, gnatboot ? null , enableMultilib ? false , enablePlugin ? stdenv.hostPlatform == stdenv.buildPlatform # Whether to support user-supplied plug-ins , name ? "gcc" @@ -35,6 +37,7 @@ assert stdenv.hostPlatform.isDarwin -> gnused != null; # The go frontend is written in c++ assert langGo -> langCC; +assert langAda -> gnatboot != null; # threadsCross is just for MinGW assert threadsCross != null -> stdenv.targetPlatform.isWindows; @@ -54,6 +57,7 @@ let majorVersion = "9"; url = "https://git.busybox.net/buildroot/plain/package/gcc/${version}/0900-remove-selftests.patch?id=11271540bfe6adafbc133caf6b5b902a816f5f02"; sha256 = ""; # TODO: uncomment and check hash when available. }) */ + ++ optional langAda ../gnat-cflags.patch ++ optional langFortran ../gfortran-driving.patch ++ optional (targetPlatform.libc == "musl" && targetPlatform.isPower) ../ppc-musl.patch ++ optional (!crossStageStatic && targetPlatform.isMinGW) (fetchpatch { @@ -160,6 +164,7 @@ stdenv.mkDerivation ({ # The builder relies on GNU sed (for instance, Darwin's `sed' fails with # "-i may not be used with stdin"), and `stdenvNative' doesn't provide it. ++ (optional hostPlatform.isDarwin gnused) + ++ (optional langAda gnatboot) ; depsTargetTarget = optional (!crossStageStatic && threadsCross != null) threadsCross; @@ -168,7 +173,7 @@ stdenv.mkDerivation ({ preConfigure = import ../common/pre-configure.nix { inherit (stdenv) lib; - inherit version hostPlatform langGo; + inherit version hostPlatform gnatboot langAda langGo; }; dontDisableStatic = true; @@ -193,6 +198,7 @@ stdenv.mkDerivation ({ langC langCC langFortran + langAda langGo langObjC langObjCpp @@ -236,7 +242,7 @@ stdenv.mkDerivation ({ ; passthru = { - inherit langC langCC langObjC langObjCpp langFortran langGo version; + inherit langC langCC langObjC langObjCpp langAda langFortran langGo version; isGNU = true; }; diff --git a/pkgs/development/compilers/gcc/common/configure-flags.nix b/pkgs/development/compilers/gcc/common/configure-flags.nix index aa0fcb506289..c78a28148951 100644 --- a/pkgs/development/compilers/gcc/common/configure-flags.nix +++ b/pkgs/development/compilers/gcc/common/configure-flags.nix @@ -16,6 +16,7 @@ , langCC , langFortran , langJava ? false, javaAwtGtk ? false, javaAntlr ? null, javaEcj ? null +, langAda ? false , langGo , langObjC , langObjCpp @@ -115,6 +116,7 @@ let ++ lib.optional langCC "c++" ++ lib.optional langFortran "fortran" ++ lib.optional langJava "java" + ++ lib.optional langAda "ada" ++ lib.optional langGo "go" ++ lib.optional langObjC "objc" ++ lib.optional langObjCpp "obj-c++" @@ -140,6 +142,9 @@ let "--enable-cloog-backend=isl" ] + # Ada options + ++ lib.optional langAda "--enable-libada" + # Java options ++ lib.optionals langJava [ "--with-ecj-jar=${javaEcj}" diff --git a/pkgs/development/compilers/gcc/common/pre-configure.nix b/pkgs/development/compilers/gcc/common/pre-configure.nix index 4c86d37e2434..85b854e19b9a 100644 --- a/pkgs/development/compilers/gcc/common/pre-configure.nix +++ b/pkgs/development/compilers/gcc/common/pre-configure.nix @@ -1,6 +1,11 @@ -{ lib, version, hostPlatform, langJava ? false, langGo }: +{ lib, version, hostPlatform +, gnatboot ? null +, langAda ? false +, langJava ? false +, langGo }: assert langJava -> lib.versionOlder version "7"; +assert langAda -> gnatboot != null; lib.optionalString (hostPlatform.isSunOS && hostPlatform.is64bit) '' export NIX_LDFLAGS=`echo $NIX_LDFLAGS | sed -e s~$prefix/lib~$prefix/lib/amd64~g` @@ -9,4 +14,6 @@ lib.optionalString (hostPlatform.isSunOS && hostPlatform.is64bit) '' export CFLAGS_FOR_TARGET="-Wl,-rpath,$prefix/lib/amd64 $CFLAGS_FOR_TARGET" '' + lib.optionalString (lib.versionOlder version "7" && (langJava || langGo)) '' export lib=$out; +'' + lib.optionalString langAda '' + export PATH=${gnatboot}/bin:$PATH '' diff --git a/pkgs/development/compilers/gcc/gnat-cflags.patch b/pkgs/development/compilers/gcc/gnat-cflags.patch new file mode 100644 index 000000000000..a16266bbf39c --- /dev/null +++ b/pkgs/development/compilers/gcc/gnat-cflags.patch @@ -0,0 +1,35 @@ +diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in +index 4e74252bd74..0d848b5b4e3 100644 +--- a/gcc/ada/gcc-interface/Makefile.in ++++ b/gcc/ada/gcc-interface/Makefile.in +@@ -111,7 +111,7 @@ NO_OMIT_ADAFLAGS = -fno-omit-frame-pointer + NO_SIBLING_ADAFLAGS = -fno-optimize-sibling-calls + NO_REORDER_ADAFLAGS = -fno-toplevel-reorder + GNATLIBFLAGS = -W -Wall -gnatpg -nostdinc +-GNATLIBCFLAGS = -g -O2 ++GNATLIBCFLAGS = -g -O2 $(CFLAGS_FOR_TARGET) + # Pretend that _Unwind_GetIPInfo is available for the target by default. This + # should be autodetected during the configuration of libada and passed down to + # here, but we need something for --disable-libada and hope for the best. +@@ -198,7 +198,7 @@ RTSDIR = rts$(subst /,_,$(MULTISUBDIR)) + # Link flags used to build gnat tools. By default we prefer to statically + # link with libgcc to avoid a dependency on shared libgcc (which is tricky + # to deal with as it may conflict with the libgcc provided by the system). +-GCC_LINK_FLAGS=-static-libstdc++ -static-libgcc ++GCC_LINK_FLAGS=-static-libstdc++ -static-libgcc $(CFLAGS_FOR_TARGET) + + # End of variables for you to override. + +diff --git a/libada/Makefile.in b/libada/Makefile.in +index 522b9207326..ca866c74471 100644 +--- a/libada/Makefile.in ++++ b/libada/Makefile.in +@@ -59,7 +59,7 @@ LDFLAGS= + CFLAGS=-g + PICFLAG = @PICFLAG@ + GNATLIBFLAGS= -W -Wall -gnatpg -nostdinc +-GNATLIBCFLAGS= -g -O2 ++GNATLIBCFLAGS= -g -O2 $(CFLAGS) + GNATLIBCFLAGS_FOR_C = -W -Wall $(GNATLIBCFLAGS) $(CFLAGS_FOR_TARGET) \ + -fexceptions -DIN_RTS @have_getipinfo@ @have_capability@ + diff --git a/pkgs/development/compilers/gnatboot/default.nix b/pkgs/development/compilers/gnatboot/default.nix new file mode 100644 index 000000000000..cb643d6123a6 --- /dev/null +++ b/pkgs/development/compilers/gnatboot/default.nix @@ -0,0 +1,51 @@ +{ stdenv, fetchurl }: + +stdenv.mkDerivation { + pname = "gentoo-gnatboot"; + version = "4.1"; + + src = if stdenv.system == "i686-linux" then + fetchurl { + url = mirror://gentoo/distfiles/gnatboot-4.1-i386.tar.bz2; + sha256 = "0665zk71598204bf521vw68i5y6ccqarq9fcxsqp7ccgycb4lysr"; + } + else if stdenv.system == "x86_64-linux" then + fetchurl { + url = mirror://gentoo/distfiles/gnatboot-4.1-amd64.tar.bz2; + sha256 = "1li4d52lmbnfs6llcshlbqyik2q2q4bvpir0f7n38nagp0h6j0d4"; + } + else + throw "Platform not supported"; + + dontStrip = 1; + + installPhase = '' + mkdir -p $out + cp -R * $out + + set +e + for a in $out/bin/* ; do + patchelf --interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \ + --set-rpath $(cat $NIX_CC/nix-support/orig-libc)/lib:$(cat $NIX_CC/nix-support/orig-cc)/lib64:$(cat $NIX_CC/nix-support/orig-cc)/lib $a + done + set -e + + mv $out/bin/gnatgcc_2wrap $out/bin/gnatgcc + ln -s $out/bin/gnatgcc $out/bin/gcc + ''; + + passthru = { + langC = true; # TRICK for gcc-wrapper to wrap it + langCC = false; + langFortran = false; + langAda = true; + }; + + meta = with stdenv.lib; { + homepage = "https://gentoo.org"; + license = licenses.gpl3Plus; + maintainers = [ maintainers.lucus16 ]; + + platforms = platforms.linux; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 1fc209f44bbb..a869ce066bf3 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -8396,6 +8396,28 @@ in inherit (gnome2) libart_lgpl; }); + gnat = gnat9; + + gnat6 = wrapCC (gcc6.cc.override { + name = "gnat"; + langC = true; + langCC = false; + langAda = true; + profiledCompiler = false; + inherit gnatboot; + }); + + gnat9 = wrapCC (gcc9.cc.override { + name = "gnat"; + langC = true; + langCC = false; + langAda = true; + profiledCompiler = false; + gnatboot = gnat6; + }); + + gnatboot = wrapCC (callPackage ../development/compilers/gnatboot { }); + gnu-smalltalk = callPackage ../development/compilers/gnu-smalltalk { }; gccgo = gccgo6;