2021-01-08 01:07:04 +01:00
#!/usr/bin/env bash
2022-06-17 14:23:05 +02:00
# Copyright 2010-2022 Google LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
2021-01-08 01:07:04 +01:00
set -eo pipefail
function extract( ) {
2021-10-27 08:46:15 +02:00
echo " Extracting ${ 1 } ... "
2021-01-08 01:07:04 +01:00
case $1 in
*.tar.bz2) tar xjf " $1 " ; ;
*.tar.xz) tar xJf " $1 " ; ;
*.tar.gz) tar xzf " $1 " ; ;
*)
>& 2 echo " don't know how to extract ' $1 '... "
exit 1
esac
}
function unpack( ) {
mkdir -p " ${ ARCHIVE_DIR } "
cd " ${ ARCHIVE_DIR } " || exit 2
local -r URL = $1
local -r RELATIVE_DIR = $2
local -r DESTINATION = " ${ ARCHIVE_DIR } / ${ RELATIVE_DIR } "
if [ [ ! -d " ${ DESTINATION } " ] ] ; then
2021-10-27 08:46:15 +02:00
echo " Downloading ${ URL } ... "
2021-01-08 01:07:04 +01:00
local -r ARCHIVE_NAME = $( basename " ${ URL } " )
2022-03-02 15:25:04 +01:00
[ [ -f " ${ ARCHIVE_NAME } " ] ] || wget --no-verbose " ${ URL } "
2021-01-08 01:07:04 +01:00
extract " ${ ARCHIVE_NAME } "
rm -f " ${ ARCHIVE_NAME } "
fi
}
function install_qemu( ) {
2021-01-26 11:07:55 +01:00
if [ [ " ${ QEMU_ARCH } " = = "DISABLED" ] ] ; then
>& 2 echo 'QEMU is disabled !'
return 0
fi
2023-05-16 12:02:38 +02:00
local -r QEMU_VERSION = ${ QEMU_VERSION : =8.0.0 }
2021-01-08 01:07:04 +01:00
local -r QEMU_TARGET = ${ QEMU_ARCH } -linux-user
if echo " ${ QEMU_VERSION } ${ QEMU_TARGET } " | cmp --silent " ${ QEMU_INSTALL } /.build " -; then
echo " qemu ${ QEMU_VERSION } up to date! "
return 0
fi
echo " QEMU_VERSION: ${ QEMU_VERSION } "
echo " QEMU_TARGET: ${ QEMU_TARGET } "
rm -rf " ${ QEMU_INSTALL } "
# Checking for a tarball before downloading makes testing easier :-)
2023-05-16 12:02:38 +02:00
local -r QEMU_URL = " https://download.qemu.org/qemu- ${ QEMU_VERSION } .tar.xz "
2021-01-08 01:07:04 +01:00
local -r QEMU_DIR = " qemu- ${ QEMU_VERSION } "
unpack ${ QEMU_URL } ${ QEMU_DIR }
cd ${ QEMU_DIR } || exit 2
./configure \
2021-04-02 09:59:27 +02:00
--prefix= " ${ QEMU_INSTALL } " \
--target-list= " ${ QEMU_TARGET } " \
2021-01-08 01:07:04 +01:00
--audio-drv-list= \
2021-01-09 23:08:24 +01:00
--disable-brlapi \
--disable-curl \
--disable-curses \
2021-01-08 01:07:04 +01:00
--disable-docs \
2021-01-09 23:08:24 +01:00
--disable-gcrypt \
--disable-gnutls \
2021-01-08 01:07:04 +01:00
--disable-gtk \
2021-01-09 23:08:24 +01:00
--disable-libnfs \
--disable-libssh \
--disable-nettle \
2021-01-08 01:07:04 +01:00
--disable-opengl \
2021-01-09 23:08:24 +01:00
--disable-sdl \
2021-01-08 01:07:04 +01:00
--disable-virglrenderer \
2022-08-24 12:48:14 +02:00
--disable-vte
2021-01-08 01:07:04 +01:00
# wrapper on ninja
make -j8
make install
echo " $QEMU_VERSION $QEMU_TARGET " > " ${ QEMU_INSTALL } /.build "
}
function assert_defined( ) {
if [ [ -z " ${ !1 } " ] ] ; then
>& 2 echo " Variable ' ${ 1 } ' must be defined "
exit 1
fi
}
function clean_build( ) {
# Cleanup previous build
rm -rf " ${ BUILD_DIR } "
mkdir -p " ${ BUILD_DIR } "
}
function expand_codescape_config( ) {
2022-08-29 11:37:59 +02:00
# https://www.mips.com/develop/tools/codescape-mips-sdk/mips-toolchain-configurations/
# mips-mti: MIPS32R6 and MIPS64R6
# mips-img: MIPS32R2 and MIPS64R2
2021-10-27 08:46:15 +02:00
# ref: https://codescape.mips.com/components/toolchain/2020.06-01/downloads.html
2022-08-24 11:24:04 +02:00
local -r DATE = 2020.06-01
local -r CODESCAPE_URL = https://codescape.mips.com/components/toolchain/${ DATE } /Codescape.GNU.Tools.Package.${ DATE } .for.MIPS.MTI.Linux.CentOS-6.x86_64.tar.gz
local -r GCC_RELATIVE_DIR = " mips-mti-linux-gnu/ ${ DATE } "
2022-08-29 11:37:59 +02:00
# ref: https://codescape.mips.com/components/toolchain/2019.02-04/downloads.html
#local -r DATE=2019.02-04
#local -r CODESCAPE_URL=https://codescape.mips.com/components/toolchain/${DATE}/Codescape.GNU.Tools.Package.${DATE}.for.MIPS.IMG.Linux.CentOS-6.x86_64.tar.gz
2022-08-24 11:24:04 +02:00
#local -r GCC_RELATIVE_DIR="mips-img-linux-gnu/${DATE}"
2022-08-29 11:37:59 +02:00
local -r GCC_URL = ${ CODESCAPE_URL }
2021-01-08 01:07:04 +01:00
unpack " ${ GCC_URL } " " ${ GCC_RELATIVE_DIR } "
local -r GCC_DIR = ${ ARCHIVE_DIR } /${ GCC_RELATIVE_DIR }
local MIPS_FLAGS = ""
2022-08-24 11:24:04 +02:00
local LIBC_DIR_SUFFIX = ""
2021-01-08 01:07:04 +01:00
local FLAVOUR = ""
case " ${ TARGET } " in
2021-01-26 11:07:55 +01:00
"mips64" )
2022-08-24 11:24:04 +02:00
MIPS_FLAGS = "-EB -mips64r6 -mabi=64"
2022-08-29 11:37:59 +02:00
#MIPS_FLAGS="-EB -mips64r2 -mabi=64"
2021-11-11 22:15:00 +01:00
FLAVOUR = "mips-r6-hard"
2022-08-24 11:24:04 +02:00
#FLAVOUR="mips-r2-hard"
LIBC_DIR_SUFFIX = "lib64"
2021-01-26 11:07:55 +01:00
; ;
"mips64el" )
2022-08-24 11:24:04 +02:00
MIPS_FLAGS = "-EL -mips64r6 -mabi=64"
2022-08-29 11:37:59 +02:00
#MIPS_FLAGS="-EL -mips64r2 -mabi=64"
2021-01-26 11:07:55 +01:00
FLAVOUR = "mipsel-r6-hard"
2022-08-24 11:24:04 +02:00
#FLAVOUR="mipsel-r2-hard"
LIBC_DIR_SUFFIX = "lib64"
2021-01-26 11:07:55 +01:00
; ;
2021-01-08 01:07:04 +01:00
*)
>& 2 echo 'unknown mips platform'
exit 1 ; ;
esac
2022-08-24 11:24:04 +02:00
local -r SYSROOT_DIR = ${ GCC_DIR } /sysroot
2021-01-26 11:07:55 +01:00
local -r STAGING_DIR = ${ SYSROOT_DIR } -stage
2021-01-08 01:07:04 +01:00
2021-01-26 11:07:55 +01:00
# Write a Toolchain file
# note: This is manadatory to use a file in order to have the CMake variable
# 'CMAKE_CROSSCOMPILING' set to TRUE.
# ref: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-linux
2021-10-27 08:46:15 +02:00
cat >" ${ TOOLCHAIN_FILE } " <<EOL
2021-01-26 11:07:55 +01:00
set( CMAKE_SYSTEM_NAME Linux)
set( CMAKE_SYSTEM_PROCESSOR ${ TARGET } )
2021-01-08 01:07:04 +01:00
2021-01-26 11:07:55 +01:00
set( CMAKE_SYSROOT ${ SYSROOT_DIR } )
set( CMAKE_STAGING_PREFIX ${ STAGING_DIR } )
2021-01-08 01:07:04 +01:00
2021-01-26 11:07:55 +01:00
set( tools ${ GCC_DIR } )
2021-10-27 08:46:15 +02:00
2022-08-29 11:37:59 +02:00
# R6
2022-08-24 11:24:04 +02:00
set( CMAKE_C_COMPILER \$ { tools} /bin/mips-mti-linux-gnu-gcc)
set( CMAKE_C_FLAGS " ${ MIPS_FLAGS } " )
set( CMAKE_CXX_COMPILER \$ { tools} /bin/mips-mti-linux-gnu-g++)
2022-08-29 11:37:59 +02:00
set( CMAKE_CXX_FLAGS " ${ MIPS_FLAGS } -L ${ SYSROOT_DIR } /usr/lib64 " )
# R2
#set(CMAKE_C_COMPILER \${tools}/bin/mips-img-linux-gnu-gcc)
#set(CMAKE_C_FLAGS "${MIPS_FLAGS}")
2022-08-24 11:24:04 +02:00
#set(CMAKE_CXX_COMPILER \${tools}/bin/mips-img-linux-gnu-g++)
#set(CMAKE_CXX_FLAGS "${MIPS_FLAGS}")
2021-01-08 01:07:04 +01:00
2021-01-26 11:07:55 +01:00
set( CMAKE_FIND_ROOT_PATH ${ GCC_DIR } )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set( CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
EOL
CMAKE_ADDITIONAL_ARGS += ( -DCMAKE_TOOLCHAIN_FILE= " ${ TOOLCHAIN_FILE } " )
2021-10-27 08:46:15 +02:00
QEMU_ARGS += ( -L " ${ SYSROOT_DIR } / ${ FLAVOUR } " )
2022-08-24 11:24:04 +02:00
local -r LIBC_DIR = ${ GCC_DIR } /mips-mti-linux-gnu/lib/${ FLAVOUR } /${ LIBC_DIR_SUFFIX }
#local -r LIBC_DIR=${GCC_DIR}/mips-img-linux-gnu/lib/${FLAVOUR}/${LIBC_DIR_SUFFIX}
2021-01-26 11:07:55 +01:00
QEMU_ARGS += ( -E LD_PRELOAD = " ${ LIBC_DIR } /libstdc++.so.6: ${ LIBC_DIR } /libgcc_s.so.1 " )
2021-01-08 01:07:04 +01:00
}
2022-08-31 14:38:21 +02:00
function expand_bootlin_config( ) {
# ref: https://toolchains.bootlin.com/
local -r GCC_DIR = ${ ARCHIVE_DIR } /${ GCC_RELATIVE_DIR }
case " ${ TARGET } " in
2022-09-01 20:48:30 +02:00
"aarch64" )
local -r POWER_URL = "https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--glibc--stable-2021.11-1.tar.bz2"
local -r GCC_PREFIX = "aarch64"
; ;
"aarch64be" )
local -r POWER_URL = "https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64be/tarballs/aarch64be--glibc--stable-2021.11-1.tar.bz2"
local -r GCC_PREFIX = "aarch64_be"
; ;
2022-08-31 14:38:21 +02:00
"ppc64le" )
local -r POWER_URL = "https://toolchains.bootlin.com/downloads/releases/toolchains/powerpc64le-power8/tarballs/powerpc64le-power8--glibc--stable-2021.11-1.tar.bz2"
local -r GCC_PREFIX = "powerpc64le"
; ;
"ppc64" )
local -r POWER_URL = "https://toolchains.bootlin.com/downloads/releases/toolchains/powerpc64-power8/tarballs/powerpc64-power8--glibc--stable-2021.11-1.tar.bz2"
local -r GCC_PREFIX = "powerpc64"
; ;
"ppc" )
#local -r POWER_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/powerpc-e500mc/tarballs/powerpc-e500mc--glibc--stable-2021.11-1.tar.bz2"
2022-09-01 14:50:50 +02:00
local -r POWER_URL = "https://toolchains.bootlin.com/downloads/releases/toolchains/powerpc-440fp/tarballs/powerpc-440fp--glibc--stable-2021.11-1.tar.bz2"
2022-08-31 14:38:21 +02:00
local -r GCC_PREFIX = "powerpc"
; ;
*)
>& 2 echo 'unknown power platform'
exit 1 ; ;
esac
local -r POWER_RELATIVE_DIR = " ${ TARGET } "
unpack " ${ POWER_URL } " " ${ POWER_RELATIVE_DIR } "
local -r EXTRACT_DIR = " ${ ARCHIVE_DIR } / $( basename ${ POWER_URL %.tar.bz2 } ) "
local -r POWER_DIR = ${ ARCHIVE_DIR } /${ POWER_RELATIVE_DIR }
if [ [ -d " ${ EXTRACT_DIR } " ] ] ; then
mv " ${ EXTRACT_DIR } " " ${ POWER_DIR } "
fi
local -r SYSROOT_DIR = " ${ POWER_DIR } / ${ GCC_PREFIX } -buildroot-linux-gnu/sysroot "
#local -r STAGING_DIR=${SYSROOT_DIR}-stage
# Write a Toolchain file
# note: This is manadatory to use a file in order to have the CMake variable
# 'CMAKE_CROSSCOMPILING' set to TRUE.
# ref: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-linux
cat >" ${ TOOLCHAIN_FILE } " <<EOL
set( CMAKE_SYSTEM_NAME Linux)
set( CMAKE_SYSTEM_PROCESSOR ${ GCC_PREFIX } )
set( CMAKE_SYSROOT ${ SYSROOT_DIR } )
#set(CMAKE_STAGING_PREFIX ${STAGING_DIR})
set( tools ${ POWER_DIR } )
set( CMAKE_C_COMPILER \$ { tools} /bin/${ GCC_PREFIX } -linux-gcc)
set( CMAKE_C_FLAGS " ${ POWER_FLAGS } " )
set( CMAKE_CXX_COMPILER \$ { tools} /bin/${ GCC_PREFIX } -linux-g++)
set( CMAKE_CXX_FLAGS " ${ POWER_FLAGS } -L ${ SYSROOT_DIR } /lib " )
set( CMAKE_FIND_ROOT_PATH ${ POWER_DIR } )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set( CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
EOL
CMAKE_ADDITIONAL_ARGS += ( -DCMAKE_TOOLCHAIN_FILE= " ${ TOOLCHAIN_FILE } " )
QEMU_ARGS += ( -L " ${ SYSROOT_DIR } " )
QEMU_ARGS += ( -E LD_PRELOAD = " ${ SYSROOT_DIR } /usr/lib/libstdc++.so.6: ${ SYSROOT_DIR } /lib/libgcc_s.so.1 " )
}
2021-01-08 01:07:04 +01:00
function build( ) {
cd " ${ PROJECT_DIR } " || exit 2
set -x
2021-01-26 11:07:55 +01:00
clean_build
2021-01-08 01:07:04 +01:00
cmake -S. -B" ${ BUILD_DIR } " " ${ CMAKE_DEFAULT_ARGS [@] } " " ${ CMAKE_ADDITIONAL_ARGS [@] } "
cmake --build " ${ BUILD_DIR } " --target all -j8 -v
set +x
}
function run_test( ) {
assert_defined QEMU_ARCH
if [ [ " ${ QEMU_ARCH } " = = "DISABLED" ] ] ; then
2021-10-27 08:46:15 +02:00
>& 2 echo " QEMU is disabled for ${ TARGET } "
2021-01-08 01:07:04 +01:00
return
fi
install_qemu
RUN_CMD = " ${ QEMU_INSTALL } /bin/qemu- ${ QEMU_ARCH } ${ QEMU_ARGS [*] } "
2021-01-10 00:48:21 +01:00
cd " ${ BUILD_DIR } " || exit 2
set -x
case ${ PROJECT } in
glop)
2021-08-23 14:46:34 +02:00
# shellcheck disable=SC2086
2021-04-06 19:03:39 +02:00
${ RUN_CMD } bin/simple_glop_program ; ;
2021-01-10 00:48:21 +01:00
or-tools)
for test_binary in \
" ${ BUILD_DIR } " /bin/simple_* \
" ${ BUILD_DIR } " /bin/*tsp* \
" ${ BUILD_DIR } " /bin/*vrp*; do
2021-08-23 14:46:34 +02:00
# shellcheck disable=SC2086
2021-04-06 19:03:39 +02:00
${ RUN_CMD } " ${ test_binary } "
2021-01-10 00:48:21 +01:00
done
; ;
*)
>& 2 echo " Unknown PROJECT ' ${ PROJECT } '... "
exit 1 ; ;
esac
set +x
2021-01-08 01:07:04 +01:00
}
function usage( ) {
local -r NAME = $( basename " $0 " )
echo -e " $NAME - Build using a cross toolchain.
SYNOPSIS
2021-01-26 11:07:55 +01:00
\t $NAME [ -h| --help] [ toolchain| build| qemu| test| all]
2021-01-08 01:07:04 +01:00
DESCRIPTION
\t Cross compile Google OR-Tools ( or Glop) using a cross toolchain.
\t You MUST define the following variables before running this script:
\t * PROJECT: glop or-tools
2021-11-11 22:15:00 +01:00
\t * TARGET:
\t \t x86_64
2022-09-01 20:48:30 +02:00
\t \t aarch64 aarch64be ( bootlin)
\t \t mips64 mips64el ( codespace)
\t \t ppc ( bootlin)
\t \t ppc64 ppc64le ( bootlin)
2021-01-08 01:07:04 +01:00
OPTIONS
\t -h --help: show this help text
2021-01-26 11:07:55 +01:00
\t toolchain: download, unpack toolchain and generate CMake toolchain file
\t build: toolchain + build the project using the toolchain file ( note: remove previous build dir)
\t qemu: download, unpack and build qemu
\t test: qemu + run all executable using qemu ( note: don' t build !)
\t all: build + test ( default)
2021-01-08 01:07:04 +01:00
2021-01-21 10:31:38 +01:00
EXAMPLES
* Using export:
2021-01-08 01:07:04 +01:00
export PROJECT = glop
export TARGET = aarch64-linux-gnu
2021-01-21 10:31:38 +01:00
$0
* One-liner:
2023-06-02 00:00:56 +02:00
PROJECT = or-tools TARGET = aarch64 $0 "
2021-01-08 01:07:04 +01:00
}
# Main
function main( ) {
2021-01-26 11:07:55 +01:00
case ${ 1 } in
-h | --help)
usage; exit ; ;
esac
2021-01-08 01:07:04 +01:00
assert_defined PROJECT
assert_defined TARGET
2021-08-23 14:46:34 +02:00
# shellcheck disable=SC2155
2021-04-06 17:57:58 +02:00
declare -r PROJECT_DIR = " $( cd -P -- " $( dirname -- " $0 " ) /.. " && pwd -P) "
2021-01-08 01:07:04 +01:00
declare -r ARCHIVE_DIR = " ${ PROJECT_DIR } /build_cross/archives "
declare -r BUILD_DIR = " ${ PROJECT_DIR } /build_cross/ ${ TARGET } "
2021-01-10 00:48:21 +01:00
declare -r TOOLCHAIN_FILE = ${ ARCHIVE_DIR } /toolchain_${ TARGET } .cmake
2021-01-08 01:07:04 +01:00
echo " Project: ' ${ PROJECT } ' "
echo " Target: ' ${ TARGET } ' "
echo " Project dir: ' ${ PROJECT_DIR } ' "
echo " Archive dir: ' ${ ARCHIVE_DIR } ' "
echo " Build dir: ' ${ BUILD_DIR } ' "
echo " toolchain file: ' ${ TOOLCHAIN_FILE } ' "
declare -a CMAKE_DEFAULT_ARGS = ( -G ${ CMAKE_GENERATOR :- "Unix Makefiles" } -DBUILD_DEPS= ON )
case ${ PROJECT } in
glop)
CMAKE_DEFAULT_ARGS += ( -DBUILD_CXX= OFF -DBUILD_GLOP= ON ) ; ;
or-tools)
CMAKE_DEFAULT_ARGS += ( -DBUILD_CXX= ON ) ; ;
*)
>& 2 echo " Unknown PROJECT ' ${ PROJECT } '... "
exit 1 ; ;
esac
declare -a CMAKE_ADDITIONAL_ARGS = ( )
2021-01-10 00:48:21 +01:00
declare -a QEMU_ARGS = ( )
2021-01-08 01:07:04 +01:00
case ${ TARGET } in
x86_64)
declare -r QEMU_ARCH = x86_64 ; ;
2022-09-01 20:48:30 +02:00
aarch64)
expand_bootlin_config
declare -r QEMU_ARCH = aarch64 ; ;
aarch64be)
expand_bootlin_config
declare -r QEMU_ARCH = aarch64_be ; ;
2021-01-08 01:07:04 +01:00
mips64)
expand_codescape_config
declare -r QEMU_ARCH = mips64 ; ;
mips64el)
expand_codescape_config
declare -r QEMU_ARCH = mips64el ; ;
2022-08-31 14:38:21 +02:00
ppc64le)
expand_bootlin_config
declare -r QEMU_ARCH = ppc64le ; ;
ppc64)
expand_bootlin_config
declare -r QEMU_ARCH = ppc64 ; ;
ppc)
expand_bootlin_config
declare -r QEMU_ARCH = ppc ; ;
2021-01-08 01:07:04 +01:00
*)
>& 2 echo " Unknown TARGET ' ${ TARGET } '... "
exit 1 ; ;
esac
2021-01-26 11:07:55 +01:00
declare -r QEMU_INSTALL = ${ ARCHIVE_DIR } /qemu-${ QEMU_ARCH }
case ${ 1 } in
toolchain)
exit ; ;
build)
build ; ;
qemu)
install_qemu ; ;
test )
run_test ; ;
*)
build
run_test ; ;
esac
2021-01-08 01:07:04 +01:00
}
2021-01-26 11:07:55 +01:00
main " ${ 1 :- all } "