##
##  gcc7.spec -- OpenPKG RPM Package Specification
##  Copyright (c) 2000-2025 OpenPKG Project <http://openpkg.org/>
##
##  Permission to use, copy, modify, and distribute this software for
##  any purpose with or without fee is hereby granted, provided that
##  the above copyright notice and this permission notice appear in all
##  copies.
##
##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
##  SUCH DAMAGE.
##

#   package version
%define       V_full         7.5.0
%define       V_comp         7

#   package information
Name:         gcc7
Summary:      GNU Compiler Collection
URL:          https://gcc.gnu.org/
Vendor:       Free Software Foundation
Packager:     OpenPKG Project
Distribution: OpenPKG Community
Class:        EVAL
Group:        Compiler
License:      GPL
Version:      %{V_full}
Release:      20191114

#   package options
%option       with_binutils  yes
%option       with_cxx       yes
%option       with_objc      no
%option       with_go        no
%option       with_fortran   no
%option       with_optimize  no
%option       with_profile   no
%option       with_threads   yes
%option       with_multilib  no
%option       with_gcc       no

#   list of sources
Source0:      https://gcc.gnu.org/pub/gcc/releases/gcc-%{V_full}/gcc-%{V_full}.tar.xz
Patch0:       gcc7.patch

#   build information
#   (actually also likes "flex", "bison" and "texinfo", but is able
#   to build without it -- which is also important for bootstrapping)
BuildPreReq:  OpenPKG, openpkg >= 20160101, make
PreReq:       OpenPKG, openpkg >= 20160101
%if "%{with_binutils}" == "yes"
BuildPreReq:  binutils >= 2.14
PreReq:       binutils >= 2.14
%endif
BuildPreReq:  mpc, mpfr, gmp
PreReq:       mpc, mpfr, gmp
%if "%{with_cxx}" == "yes"
BuildPreReq:  libiconv
PreReq:       libiconv
%endif
%if "%{with_gcc}" == "yes"
Provides:     gcc = %{version}-%{release}
Provides:     gcc = %{version}-%{release}
Provides:     gcc::with_binutils = %{with_binutils}
Provides:     gcc::with_cxx = %{with_cxx}
Provides:     gcc::with_objc = %{with_objc}
Provides:     gcc::with_fortran = %{with_fortran}
Provides:     gcc::with_profile = %{with_profile}
Provides:     gcc::with_threads = %{with_threads}
Provides:     gcc::with_multilib = %{with_multilib}
Provides:     gcc::with_gcc = %{with_gcc}
%endif

%description
    The GNU Compiler Collection (GCC) provides standard conforming and
    highly portable compilers for the ISO C, ISO C++, Objective-C,
    Fortran, Java and Go languages.

%track
    prog gcc7 = {
        version   = %{V_full}
        url       = https://gcc.gnu.org/pub/gcc/releases/
        regex     = gcc-(7\.\d+\.\d+)
    }

%prep
    %setup -q -n gcc-%{V_full}
    %patch -p0
    %{l_shtool} subst -v -s \
        -e 's;PREFIX_INCLUDE_DIR;PREFIX_INCLUDE_DIR_DISABLED;g' \
        gcc/configure
    if [ ".%{V_comp}" != . ]; then
        %{l_shtool} subst -v -s \
            -e 's;(libdir)/gcc/;(libdir)/gcc%{V_comp}/;' \
            `find . -name Makefile.in -type f -print`
    fi
    case "%{l_platform -t}" in
        amd64*-linux* )
            %{l_shtool} subst \
                -e 's/GLIBCXX_IS_NATIVE=false/GLIBCXX_IS_NATIVE=true/g' \
                -e 's/test x.gcc_no_link = xyes/false/g' \
                libstdc++-v3/configure
            ;;
    esac
    %{l_shtool} subst \
        -e 's;<iconv\.h>;"%{l_prefix}/include/iconv.h";' \
        libstdc++-v3/include/ext/codecvt_specializations.h

%build
    #   support bootstrapping GCC on systems without C++ compiler
    #   (requires OpenPKG package "gcc-bootstrap")
    if [ -d %{l_prefix}/libexec/gcc-bootstrap/bin-bootstrap ]; then
        PATH="%{l_prefix}/libexec/gcc-bootstrap/bin-bootstrap:$PATH"
    fi

    #   create build sub-directory
    %{l_shtool} mkdir -p obj
    cd obj

    #   determine ld(1) and as(1) usage
    l_with_gnu_ld_as=""
    LD=%{l_tool_locate ld ld}
    AS=%{l_tool_locate as as}
    echo $LD | grep '^/' >/dev/null && l_with_gnu_ld_as="${l_with_gnu_ld_as} --with-ld=$LD"
    echo $AS | grep '^/' >/dev/null && l_with_gnu_ld_as="${l_with_gnu_ld_as} --with-as=$AS"
    $LD --version </dev/null 2>/dev/null | grep "^GNU ld "        >/dev/null && l_with_gnu_ld_as="${l_with_gnu_ld_as} --with-gnu-ld"
    $AS --version </dev/null 2>/dev/null | grep "^GNU assembler " >/dev/null && l_with_gnu_ld_as="${l_with_gnu_ld_as} --with-gnu-as"
    unset LD
    unset AS

    #   determine threads usage
%if "%{with_threads}" == "yes"
    l_enable_threads="posix"
%else
    l_enable_threads="no"
%endif

    #   determine language usage
    l_enable_languages="c"
%if "%{with_cxx}" == "yes"
    l_enable_languages="${l_enable_languages},c++"
%endif
%if "%{with_objc}" == "yes"
    l_enable_languages="${l_enable_languages},objc"
%endif
%if "%{with_go}" == "yes"
    l_enable_languages="${l_enable_languages},go"
%endif
%if "%{with_fortran}" == "yes"
    l_enable_languages="${l_enable_languages},fortran"
%endif

    #   disable GNU gettext usage
    ( echo "ac_cv_header_libintl_h=no"
      echo "ac_cv_search_gettext=no"
    ) >config.cache

%if "%{with_cxx}" != "yes"
    #   disable GNU iconv usage
    ( echo "am_cv_func_iconv=no"
      echo "am_cv_lib_iconv=no"
    ) >>config.cache
%endif

    #   configure the package
    clocale="auto"
    case "%{l_platform -t}" in
        *-linux* ) clocale="generic" ;;
    esac
    CC="%{l_cc}" \
    CXX="%{l_cxx}" \
    CFLAGS="%{l_cflags}" \
    CXXFLAGS="%{l_cxxflags}" \
%if "%{with_fortran}" == "yes" || "%{with_cxx}" == "yes"
    CPPFLAGS="%{l_cppflags}" \
    LDFLAGS="%{l_ldflags}" \
%endif
    CONFIG_SHELL="%{l_bash}" \
    ../configure \
        --cache-file=./config.cache \
        --with-bugurl="http://openpkg.org/" \
        --with-pkgversion="GCC %{l_openpkg_release -F "OpenPKG-%%t"}" \
        --srcdir=`pwd`/.. \
        --prefix=%{l_prefix} \
        --exec-prefix=%{l_prefix} \
        --mandir=%{l_prefix}/man \
        --infodir=%{l_prefix}/info \
        --includedir=%{l_prefix}/include/gcc%{V_comp} \
        --libexecdir=%{l_prefix}/libexec/gcc%{V_comp} \
        --with-gxx-include-dir=%{l_prefix}/include/g++%{V_comp} \
        --with-local-prefix=%{l_prefix}/lib/gcc%{V_comp} \
        --enable-languages="${l_enable_languages}" \
        --enable-threads="${l_enable_threads}" \
        --disable-werror \
        --disable-maintainer-mode \
        --disable-shared \
        --disable-nls \
        --enable-clocale=$clocale \
        --with-pic \
%if "%{with_multilib}" == "yes"
        --enable-multilib \
%else
        --disable-multilib \
%endif
%if "%{with_cxx}" == "yes"
        --with-libiconv-prefix=%{l_prefix} \
%else
        --without-libiconv-prefix \
%endif
        --with-gmp=%{l_prefix} \
        --with-mpfr=%{l_prefix} \
        --with-mpc=%{l_prefix} \
        ${l_with_gnu_ld_as}

    #   determine build flags
    l_ccisgcc=no
    if [ ".`(%{l_cc} -v; %{l_cc} --version) </dev/null 2>&1 | grep -i 'gcc'`" != . ]; then
        l_ccisgcc=yes
    fi
    l_cflags=""
    l_cxxflags=""
    l_boot_cflags=""
    l_libcflags="-g"
    l_libcxxflags="-g"
    #   at least GNU as from GNU binutils supports -pipe always
    AS="%{l_tool_locate as as}"
    "$AS" --version </dev/null 2>/dev/null | grep "^GNU assembler " >/dev/null && {
        l_boot_cflags="$l_boot_cflags -pipe"
        l_libcxxflags="$l_libcxxflags -pipe"
    }
%if "%{with_optimize}" == "yes"
    #   conservatively optimize the generated program code
    #   (also _tune_ for particular CPUs, but _without_ requiring these CPUs!)
    l_cflags="$l_cflags -O"
    l_boot_cflags="$l_boot_cflags -O2 -fomit-frame-pointer"
    case "%{l_platform -t}" in
        *i?86-*     ) l_boot_cflags="$l_boot_cflags -mtune=pentium3" ;;
        *sun4[uv]-* ) l_boot_cflags="$l_boot_cflags -mtune=v9"       ;;
    esac
    l_libcxxflags="$l_libcxxflags -O2 -fno-implicit-templates"
%else
    #   else do no optimizations at all to reduce problems to minimum in advance
    l_boot_cflags="$l_boot_cflags -O0"
    l_libcxxflags="$l_libcxxflags -O0"
%endif
    maketarget="bootstrap2-lean"
%if "%{with_profile}" == "yes"
    #   GCC >= 3.4 supports a "profiledbootstrap" target to build an
    #   optimized version of itself through profiling. Because this
    #   requires a (bootstrapping) C compiler with 64-bit arithmetic,
    #   the whole approach is currently supported only if already
    #   building with GCC as the bootstrapping C compiler.
    if [ ".$l_ccisgcc" = .yes ]; then
        maketarget="profiledbootstrap"
    fi
%endif
    case "%{l_platform -t}" in
        amd64-*          ) l_cflags="$l_cflags -fPIC"; l_cxxflags="$l_cxxflags -fPIC"; l_libcflags="$l_libcflags -fPIC"; l_libcxxflags="$l_libcxxflags -fPIC" ;;
        ia64-*           ) l_cflags="$l_cflags -fPIC"; l_cxxflags="$l_cxxflags -fPIC"; l_libcflags="$l_libcflags -fPIC"; l_libcxxflags="$l_libcxxflags -fPIC" ;;
        sparc64-freebsd* ) l_cflags="$l_cflags -fPIC"; l_cxxflags="$l_cxxflags -fPIC"; l_libcflags="$l_libcflags -fPIC"; l_libcxxflags="$l_libcxxflags -fPIC" ;;
    esac
%if "%{with_fortran}" == "yes" || "%{with_cxx}" == "yes"
    l_cflags="$l_cflags %{l_cppflags}"
    l_cxxflags="$l_cxxflags %{l_cppflags}"
    l_libcflags="$l_libcflags %{l_cppflags}"
    l_libcxxflags="$l_libcxxflags %{l_cppflags}"
%endif

    #   build the package
    MAKE="%{l_make} %{l_mflags}" \
    %{l_make} %{l_mflags} \
        MAKE="%{l_make} %{l_mflags}" \
        BOOT_CFLAGS="${l_boot_cflags}" \
        CFLAGS="${l_cflags}" \
        CXXFLAGS="${l_cxxflags}" \
        LIBCFLAGS="${l_libcflags}" \
        LIBCXXFLAGS="${l_libcxxflags}" \
        $maketarget

%install
    #   support bootstrapping GCC on systems without C++ compiler
    #   (requires OpenPKG package "gcc-bootstrap")
    if [ -d %{l_prefix}/libexec/gcc-bootstrap/bin-bootstrap ]; then
        PATH="%{l_prefix}/libexec/gcc-bootstrap/bin-bootstrap:$PATH"
    fi

    #   fetch GNU platform triple
    triple=`./config.guess`

    #   perform the standard installation procedure
    ( cd obj
      %{l_make} %{l_mflags} install DESTDIR=$RPM_BUILD_ROOT
    ) || exit $?

    #   cleanup installation tree
    mv $RPM_BUILD_ROOT%{l_prefix}/lib/{lib*.so,lib*.so.*,lib*.a,*.spec} \
       $RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}/${triple}/[0-9]*/ \
       >/dev/null 2>&1 || true
    mv $RPM_BUILD_ROOT%{l_prefix}/lib64/{lib*.a,*.spec} \
       $RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}/${triple}/[0-9]*/ \
       >/dev/null 2>&1 || true
    dirs=""
    for multilib in `$RPM_BUILD_ROOT%{l_prefix}/bin/gcc --print-multi-lib`; do
        subdir=`echo "$multilib" | sed -e 's/;.*$//'`
        [ ".$subdir" = .. ] && continue
        mv $RPM_BUILD_ROOT%{l_prefix}/lib/$subdir/lib*.a \
           $RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}/${triple}/[0-9]*/$subdir/ \
           >/dev/null 2>&1 || true
        mv $RPM_BUILD_ROOT%{l_prefix}/lib64/$subdir/lib*.a \
           $RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}/${triple}/[0-9]*/$subdir/ \
           >/dev/null 2>&1 || true
        dirs="$dirs $subdir"
    done
    for subdir in $dirs; do
        rm -rf $RPM_BUILD_ROOT%{l_prefix}/lib/$subdir >/dev/null 2>&1 || true
    done
    mv $RPM_BUILD_ROOT%{l_prefix}/${triple}/include/* \
       $RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}/${triple}/[0-9]*/include/ \
           >/dev/null 2>&1 || true

    #   strip installation tree
    rm -rf $RPM_BUILD_ROOT%{l_prefix}/${triple}
    rm -rf $RPM_BUILD_ROOT%{l_prefix}/share/gcc-*/python >/dev/null 2>&1 || true
    rmdir  $RPM_BUILD_ROOT%{l_prefix}/share/gcc-*        >/dev/null 2>&1 || true
    rm -f  $RPM_BUILD_ROOT%{l_prefix}/info/dir
    rm -rf $RPM_BUILD_ROOT%{l_prefix}/man/man7   >/dev/null 2>&1 || true
    rm -f  $RPM_BUILD_ROOT%{l_prefix}/lib/*.la   >/dev/null 2>&1 || true
    rm -f  $RPM_BUILD_ROOT%{l_prefix}/lib/libstdc++.a-gdb.py >/dev/null 2>&1 || true
    rm -rf $RPM_BUILD_ROOT%{l_prefix}/lib64      >/dev/null 2>&1 || true
    rm -f  $RPM_BUILD_ROOT%{l_prefix}/bin/*-gcc* >/dev/null 2>&1 || true
%if "%{with_cxx}" == "yes"
    rm -f  $RPM_BUILD_ROOT%{l_prefix}/bin/*-c++  >/dev/null 2>&1 || true
    rm -f  $RPM_BUILD_ROOT%{l_prefix}/bin/*-g++  >/dev/null 2>&1 || true
%endif
    strip $RPM_BUILD_ROOT%{l_prefix}/bin/* >/dev/null 2>&1 || true
    for prog in cc1 cc1plus collect2 cpp; do
        strip $RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}/${triple}/[0-9]*/${prog} \
            >/dev/null 2>&1 || true
    done

    #   bump up installation tree
    ln $RPM_BUILD_ROOT%{l_prefix}/bin/gcc \
       $RPM_BUILD_ROOT%{l_prefix}/bin/cc
    ln $RPM_BUILD_ROOT%{l_prefix}/man/man1/gcc.1 \
       $RPM_BUILD_ROOT%{l_prefix}/man/man1/cc.1
%if "%{with_cxx}" == "yes"
    ln $RPM_BUILD_ROOT%{l_prefix}/man/man1/g++.1 \
       $RPM_BUILD_ROOT%{l_prefix}/man/man1/c++.1
%endif

    #   resolve filename conflicts
%if "%{with_gcc}" != "yes" && "%{V_comp}" != ""
    ( cd $RPM_BUILD_ROOT%{l_prefix}/bin
      for file in *; do
          [ ".$file" = ".*" ] && continue
          mv ${file} ${file}%{V_comp}
      done
    ) || exit $?
    ( cd $RPM_BUILD_ROOT%{l_prefix}/info
      for file in *; do
          [ ".$file" = ".*" ] && continue
          mv ${file} `echo ${file} | sed -e 's;^\([^.]*\)\(\..*\)$;\1%{V_comp}\2;'`
      done
    ) || exit $?
    ( cd $RPM_BUILD_ROOT%{l_prefix}/man/man1
      for file in *; do
          [ ".$file" = ".*" ] && continue
          mv ${file} `echo ${file} | sed -e 's;^\([^.]*\)\(\..*\)$;\1%{V_comp}\2;'`
      done
    ) || exit $?
%endif

    #   determine installation file list
    %{l_rpmtool} files -v -ofiles -r$RPM_BUILD_ROOT %{l_files_std}

%files -f files

%clean

