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). 19 20VERSION="$1" 21TARGET="$2" 22 23case "${VERSION}" in 24devtoolset-7) 25 LIBSTDCXX_VERSION="6.0.24" 26 ;; 27devtoolset-8) 28 LIBSTDCXX_VERSION="6.0.25" 29 ;; 30*) 31 echo "Usage: $0 {devtoolset-7|devtoolset-8} <target-directory>" 32 exit 1 33 ;; 34esac 35 36mkdir -p "${TARGET}" 37# Download binary glibc 2.12 release. 38wget "http://old-releases.ubuntu.com/ubuntu/pool/main/e/eglibc/libc6_2.12.1-0ubuntu6_amd64.deb" && \ 39 unar "libc6_2.12.1-0ubuntu6_amd64.deb" && \ 40 tar -C "${TARGET}" -xvzf "libc6_2.12.1-0ubuntu6_amd64/data.tar.gz" && \ 41 rm -rf "libc6_2.12.1-0ubuntu6_amd64.deb" "libc6_2.12.1-0ubuntu6_amd64" 42wget "http://old-releases.ubuntu.com/ubuntu/pool/main/e/eglibc/libc6-dev_2.12.1-0ubuntu6_amd64.deb" && \ 43 unar "libc6-dev_2.12.1-0ubuntu6_amd64.deb" && \ 44 tar -C "${TARGET}" -xvzf "libc6-dev_2.12.1-0ubuntu6_amd64/data.tar.gz" && \ 45 rm -rf "libc6-dev_2.12.1-0ubuntu6_amd64.deb" "libc6-dev_2.12.1-0ubuntu6_amd64" 46 47# Put the current kernel headers from ubuntu in place. 48ln -s "/usr/include/linux" "/${TARGET}/usr/include/linux" 49ln -s "/usr/include/asm-generic" "/${TARGET}/usr/include/asm-generic" 50ln -s "/usr/include/x86_64-linux-gnu/asm" "/${TARGET}/usr/include/asm" 51 52# Symlinks in the binary distribution are set up for installation in /usr, we 53# need to fix up all the links to stay within /${TARGET}. 54/fixlinks.sh "/${TARGET}" 55 56# Patch to allow non-glibc 2.12 compatible builds to work. 57sed -i '54i#define TCP_USER_TIMEOUT 18' "/${TARGET}/usr/include/netinet/tcp.h" 58 59# Download binary libstdc++ 4.4 release we are going to link against. 60# We only need the shared library, as we're going to develop against the 61# libstdc++ provided by devtoolset. 62wget "http://old-releases.ubuntu.com/ubuntu/pool/main/g/gcc-4.4/libstdc++6_4.4.3-4ubuntu5_amd64.deb" && \ 63 unar "libstdc++6_4.4.3-4ubuntu5_amd64.deb" && \ 64 tar -C "/${TARGET}" -xvzf "libstdc++6_4.4.3-4ubuntu5_amd64/data.tar.gz" "./usr/lib/libstdc++.so.6.0.13" && \ 65 rm -rf "libstdc++6_4.4.3-4ubuntu5_amd64.deb" "libstdc++6_4.4.3-4ubuntu5_amd64" 66 67mkdir -p "${TARGET}-src" 68cd "${TARGET}-src" 69 70# Build a devtoolset cross-compiler based on our glibc 2.12 sysroot setup. 71 72case "${VERSION}" in 73devtoolset-7) 74 wget "http://vault.centos.org/centos/6/sclo/Source/rh/devtoolset-7/devtoolset-7-gcc-7.3.1-5.15.el6.src.rpm" 75 rpm2cpio "devtoolset-7-gcc-7.3.1-5.15.el6.src.rpm" |cpio -idmv 76 tar -xvjf "gcc-7.3.1-20180303.tar.bz2" --strip 1 77 ;; 78devtoolset-8) 79 wget "http://vault.centos.org/centos/6/sclo/Source/rh/devtoolset-8/devtoolset-8-gcc-8.2.1-3.el6.src.rpm" 80 rpm2cpio "devtoolset-8-gcc-8.2.1-3.el6.src.rpm" |cpio -idmv 81 tar -xvf "gcc-8.2.1-20180905.tar.xz" --strip 1 82 ;; 83esac 84 85# Apply the devtoolset patches to gcc. 86/rpm-patch.sh "gcc.spec" 87 88./contrib/download_prerequisites 89 90mkdir -p "${TARGET}-build" 91cd "${TARGET}-build" 92 93"${TARGET}-src/configure" \ 94 --prefix=/"${TARGET}/usr" \ 95 --with-sysroot="/${TARGET}" \ 96 --disable-bootstrap \ 97 --disable-libmpx \ 98 --disable-libsanitizer \ 99 --disable-libunwind-exceptions \ 100 --disable-libunwind-exceptions \ 101 --disable-lto \ 102 --disable-multilib \ 103 --enable-__cxa_atexit \ 104 --enable-gnu-indirect-function \ 105 --enable-gnu-unique-object \ 106 --enable-initfini-array \ 107 --enable-languages="c,c++" \ 108 --enable-linker-build-id \ 109 --enable-plugin \ 110 --enable-shared \ 111 --enable-threads=posix \ 112 --with-default-libstdcxx-abi="gcc4-compatible" \ 113 --with-gcc-major-version-only \ 114 --with-linker-hash-style="gnu" \ 115 --with-tune="generic" \ 116 && \ 117 make -j 42 && \ 118 make install 119 120# Create the devtoolset libstdc++ linkerscript that links dynamically against 121# the system libstdc++ 4.4 and provides all other symbols statically. 122mv "/${TARGET}/usr/lib/libstdc++.so.${LIBSTDCXX_VERSION}" \ 123 "/${TARGET}/usr/lib/libstdc++.so.${LIBSTDCXX_VERSION}.backup" 124echo -e "OUTPUT_FORMAT(elf64-x86-64)\nINPUT ( libstdc++.so.6.0.13 -lstdc++_nonshared44 )" \ 125 > "/${TARGET}/usr/lib/libstdc++.so.${LIBSTDCXX_VERSION}" 126cp "./x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++_nonshared44.a" \ 127 "/${TARGET}/usr/lib" 128 129# Link in architecture specific includes from the system; note that we cannot 130# link in the whole x86_64-linux-gnu folder, as otherwise we're overlaying 131# system gcc paths that we do not want to find. 132# TODO(klimek): Automate linking in all non-gcc / non-kernel include 133# directories. 134mkdir -p "/${TARGET}/usr/include/x86_64-linux-gnu" 135PYTHON_VERSIONS=("python3.6m" "python3.7m" "python3.8") 136for v in "${PYTHON_VERSIONS[@]}"; do 137 ln -s "/usr/local/include/${v}" "/${TARGET}/usr/include/x86_64-linux-gnu/${v}" 138done 139 140