• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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