1#!/bin/bash -eu 2# Copyright 2016 The TensorFlow Authors. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# ============================================================================== 16# 17# Builds a devtoolset cross-compiler targeting manylinux 2010 (glibc 2.12 / 18# libstdc++ 4.4) or manylinux2014 (glibc 2.17 / libstdc++ 4.8). 19 20VERSION="$1" 21TARGET="$2" 22 23case "${VERSION}" in 24devtoolset-7) 25 LIBSTDCXX_VERSION="6.0.24" 26 LIBSTDCXX_ABI="gcc4-compatible" 27 ;; 28devtoolset-9) 29 LIBSTDCXX_VERSION="6.0.28" 30 LIBSTDCXX_ABI="new" 31 ;; 32*) 33 echo "Usage: $0 {devtoolset-7|devtoolset-9} <target-directory>" 34 echo "Use 'devtoolset-7' to build a manylinux2010 compatible toolchain or 'devtoolset-9' to build a manylinux2014 compatible toolchain" 35 exit 1 36 ;; 37esac 38 39mkdir -p "${TARGET}" 40 41# Download glibc's shared and development libraries based on the value of the 42# `VERSION` parameter. 43# Note: 'Templatizing' this and the other conditional branches would require 44# defining several variables (version, os, path) making it difficult to maintain 45# and extend for future modifications. 46case "${VERSION}" in 47devtoolset-7) 48 # Download binary glibc 2.12 shared library release. 49 wget "http://old-releases.ubuntu.com/ubuntu/pool/main/e/eglibc/libc6_2.12.1-0ubuntu6_amd64.deb" && \ 50 unar "libc6_2.12.1-0ubuntu6_amd64.deb" && \ 51 tar -C "${TARGET}" -xvzf "libc6_2.12.1-0ubuntu6_amd64/data.tar.gz" && \ 52 rm -rf "libc6_2.12.1-0ubuntu6_amd64.deb" "libc6_2.12.1-0ubuntu6_amd64" 53 # Download binary glibc 2.12 development library release. 54 wget "http://old-releases.ubuntu.com/ubuntu/pool/main/e/eglibc/libc6-dev_2.12.1-0ubuntu6_amd64.deb" && \ 55 unar "libc6-dev_2.12.1-0ubuntu6_amd64.deb" && \ 56 tar -C "${TARGET}" -xvzf "libc6-dev_2.12.1-0ubuntu6_amd64/data.tar.gz" && \ 57 rm -rf "libc6-dev_2.12.1-0ubuntu6_amd64.deb" "libc6-dev_2.12.1-0ubuntu6_amd64" 58 ;; 59devtoolset-9) 60 # Download binary glibc 2.17 shared library release. 61 wget "http://old-releases.ubuntu.com/ubuntu/pool/main/e/eglibc/libc6_2.17-0ubuntu5.1_amd64.deb" && \ 62 unar "libc6_2.17-0ubuntu5.1_amd64.deb" && \ 63 tar -C "${TARGET}" -xvzf "libc6_2.17-0ubuntu5.1_amd64/data.tar.gz" && \ 64 rm -rf "libc6_2.17-0ubuntu5.1_amd64.deb" "libc6_2.17-0ubuntu5.1_amd64" 65 # Download binary glibc 2.17 development library release. 66 wget "http://old-releases.ubuntu.com/ubuntu/pool/main/e/eglibc/libc6-dev_2.17-0ubuntu5.1_amd64.deb" && \ 67 unar "libc6-dev_2.17-0ubuntu5.1_amd64.deb" && \ 68 tar -C "${TARGET}" -xvzf "libc6-dev_2.17-0ubuntu5.1_amd64/data.tar.gz" && \ 69 rm -rf "libc6-dev_2.17-0ubuntu5.1_amd64.deb" "libc6-dev_2.17-0ubuntu5.1_amd64" 70 ;; 71esac 72 73# Put the current kernel headers from ubuntu in place. 74ln -s "/usr/include/linux" "/${TARGET}/usr/include/linux" 75ln -s "/usr/include/asm-generic" "/${TARGET}/usr/include/asm-generic" 76ln -s "/usr/include/x86_64-linux-gnu/asm" "/${TARGET}/usr/include/asm" 77 78# Symlinks in the binary distribution are set up for installation in /usr, we 79# need to fix up all the links to stay within /${TARGET}. 80/fixlinks.sh "/${TARGET}" 81 82# Patch to allow non-glibc 2.12 compatible builds to work. 83sed -i '54i#define TCP_USER_TIMEOUT 18' "/${TARGET}/usr/include/netinet/tcp.h" 84 85# Download specific version of libstdc++ shared library based on the value of 86# the `VERSION` parameter 87case "${VERSION}" in 88devtoolset-7) 89 # Download binary libstdc++ 4.4 release we are going to link against. 90 # We only need the shared library, as we're going to develop against the 91 # libstdc++ provided by devtoolset. 92 wget "http://old-releases.ubuntu.com/ubuntu/pool/main/g/gcc-4.4/libstdc++6_4.4.3-4ubuntu5_amd64.deb" && \ 93 unar "libstdc++6_4.4.3-4ubuntu5_amd64.deb" && \ 94 tar -C "/${TARGET}" -xvzf "libstdc++6_4.4.3-4ubuntu5_amd64/data.tar.gz" "./usr/lib/libstdc++.so.6.0.13" && \ 95 rm -rf "libstdc++6_4.4.3-4ubuntu5_amd64.deb" "libstdc++6_4.4.3-4ubuntu5_amd64" 96 ;; 97devtoolset-9) 98 # Download binary libstdc++ 4.8 shared library release 99 wget "http://old-releases.ubuntu.com/ubuntu/pool/main/g/gcc-4.8/libstdc++6_4.8.1-10ubuntu8_amd64.deb" && \ 100 unar "libstdc++6_4.8.1-10ubuntu8_amd64.deb" && \ 101 tar -C "/${TARGET}" -xvzf "libstdc++6_4.8.1-10ubuntu8_amd64/data.tar.gz" "./usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.18" && \ 102 rm -rf "libstdc++6_4.8.1-10ubuntu8_amd64.deb" "libstdc++6_4.8.1-10ubuntu8_amd64" 103 ;; 104esac 105 106mkdir -p "${TARGET}-src" 107cd "${TARGET}-src" 108 109# Build a devtoolset cross-compiler based on our glibc 2.12/glibc 2.17 sysroot setup. 110case "${VERSION}" in 111devtoolset-7) 112 wget "http://vault.centos.org/centos/6/sclo/Source/rh/devtoolset-7/devtoolset-7-gcc-7.3.1-5.15.el6.src.rpm" 113 rpm2cpio "devtoolset-7-gcc-7.3.1-5.15.el6.src.rpm" |cpio -idmv 114 tar -xvjf "gcc-7.3.1-20180303.tar.bz2" --strip 1 115 ;; 116devtoolset-9) 117 wget "https://vault.centos.org/centos/7/sclo/Source/rh/devtoolset-9-gcc-9.3.1-2.2.el7.src.rpm" 118 rpm2cpio "devtoolset-9-gcc-9.3.1-2.2.el7.src.rpm" |cpio -idmv 119 tar -xvf "gcc-9.3.1-20200408.tar.xz" --strip 1 120 ;; 121esac 122 123# Apply the devtoolset patches to gcc. 124/rpm-patch.sh "gcc.spec" 125 126./contrib/download_prerequisites 127 128mkdir -p "${TARGET}-build" 129cd "${TARGET}-build" 130 131"${TARGET}-src/configure" \ 132 --prefix=/"${TARGET}/usr" \ 133 --with-sysroot="/${TARGET}" \ 134 --disable-bootstrap \ 135 --disable-libmpx \ 136 --disable-libsanitizer \ 137 --disable-libunwind-exceptions \ 138 --disable-libunwind-exceptions \ 139 --disable-lto \ 140 --disable-multilib \ 141 --enable-__cxa_atexit \ 142 --enable-gnu-indirect-function \ 143 --enable-gnu-unique-object \ 144 --enable-initfini-array \ 145 --enable-languages="c,c++" \ 146 --enable-linker-build-id \ 147 --enable-plugin \ 148 --enable-shared \ 149 --enable-threads=posix \ 150 --with-default-libstdcxx-abi=${LIBSTDCXX_ABI} \ 151 --with-gcc-major-version-only \ 152 --with-linker-hash-style="gnu" \ 153 --with-tune="generic" \ 154 && \ 155 make -j 42 && \ 156 make install 157 158 159# Create the devtoolset libstdc++ linkerscript that links dynamically against 160# the system libstdc++ 4.4 and provides all other symbols statically. 161case "${VERSION}" in 162devtoolset-7) 163mv "/${TARGET}/usr/lib/libstdc++.so.${LIBSTDCXX_VERSION}" \ 164 "/${TARGET}/usr/lib/libstdc++.so.${LIBSTDCXX_VERSION}.backup" 165echo -e "OUTPUT_FORMAT(elf64-x86-64)\nINPUT ( libstdc++.so.6.0.13 -lstdc++_nonshared44 )" \ 166 > "/${TARGET}/usr/lib/libstdc++.so.${LIBSTDCXX_VERSION}" 167cp "./x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++_nonshared44.a" \ 168 "/${TARGET}/usr/lib" 169 ;; 170devtoolset-9) 171# Note that the installation path for libstdc++ here is /${TARGET}/usr/lib64/ 172mv "/${TARGET}/usr/lib64/libstdc++.so.${LIBSTDCXX_VERSION}" \ 173 "/${TARGET}/usr/lib64/libstdc++.so.${LIBSTDCXX_VERSION}.backup" 174echo -e "OUTPUT_FORMAT(elf64-x86-64)\nINPUT ( libstdc++.so.6.0.18 -lstdc++_nonshared44 )" \ 175 > "/${TARGET}/usr/lib64/libstdc++.so.${LIBSTDCXX_VERSION}" 176cp "./x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++_nonshared44.a" \ 177 "/${TARGET}/usr/lib64" 178;; 179esac 180 181 182# Link in architecture specific includes from the system; note that we cannot 183# link in the whole x86_64-linux-gnu folder, as otherwise we're overlaying 184# system gcc paths that we do not want to find. 185# TODO(klimek): Automate linking in all non-gcc / non-kernel include 186# directories. 187mkdir -p "/${TARGET}/usr/include/x86_64-linux-gnu" 188PYTHON_VERSIONS=("python3.7m" "python3.8" "python3.9" "python3.10") 189for v in "${PYTHON_VERSIONS[@]}"; do 190 ln -s "/usr/local/include/${v}" "/${TARGET}/usr/include/x86_64-linux-gnu/${v}" 191done 192