#!/bin/sh # SPDX-License-Identifier: GPL-2.0-or-later # This is an example of how to do a cross-build of OpenOCD using pkg-config. # Cross-building with pkg-config is deceptively hard and most guides and # tutorials are incomplete or give bad advice. Some of the traps that are easy # to fall in but handled by this script are: # # * Polluting search paths and flags with values from the build system. # * Faulty pkg-config wrappers shipped with distribution packaged cross- # toolchains. # * Build failing because pkg-config discards some paths even though they are # correctly listed in the .pc file. # * Getting successfully built binaries that cannot find runtime data because # paths refer to the build file system. # # This script is probably more useful as a reference than as a complete build # tool but for some configurations it may be usable as-is. It only cross-builds # libusb-1.0, hidapi, libftdi and capstone from source, but the script can be # extended to build other prerequisites in a similar manner. # # Usage: # export LIBUSB1_SRC=/path/to/libusb-1.0 # export HIDAPI_SRC=/path/to/hidapi # export OPENOCD_CONFIG="--enable-..." # cd /work/dir # /path/to/openocd/contrib/cross-build.sh # # For static linking, a workaround is to # export LIBUSB1_CONFIG="--enable-static --disable-shared" # # All the paths must not contain any spaces. set -e -x WORK_DIR=$PWD ## Source code paths, customize as necessary : ${OPENOCD_SRC:="`dirname "$0"`/.."} : ${LIBUSB1_SRC:=/path/to/libusb1} : ${HIDAPI_SRC:=/path/to/hidapi} : ${LIBFTDI_SRC:=/path/to/libftdi} : ${CAPSTONE_SRC:=/path/to/capstone} : ${LIBJAYLINK_SRC:=/path/to/libjaylink} OPENOCD_SRC=`readlink -m $OPENOCD_SRC` LIBUSB1_SRC=`readlink -m $LIBUSB1_SRC` HIDAPI_SRC=`readlink -m $HIDAPI_SRC` LIBFTDI_SRC=`readlink -m $LIBFTDI_SRC` CAPSTONE_SRC=`readlink -m $CAPSTONE_SRC` LIBJAYLINK_SRC=`readlink -m $LIBJAYLINK_SRC` HOST_TRIPLET=$1 BUILD_DIR=$WORK_DIR/$HOST_TRIPLET-build LIBUSB1_BUILD_DIR=$BUILD_DIR/libusb1 HIDAPI_BUILD_DIR=$BUILD_DIR/hidapi LIBFTDI_BUILD_DIR=$BUILD_DIR/libftdi CAPSTONE_BUILD_DIR=$BUILD_DIR/capstone LIBJAYLINK_BUILD_DIR=$BUILD_DIR/libjaylink OPENOCD_BUILD_DIR=$BUILD_DIR/openocd ## Root of host file tree SYSROOT=$WORK_DIR/$HOST_TRIPLET-root ## Install location within host file tree : ${PREFIX=/usr} ## Make parallel jobs : ${MAKE_JOBS:=1} ## OpenOCD-only install dir for packaging : ${OPENOCD_TAG:=`git --git-dir=$OPENOCD_SRC/.git describe --tags`} PACKAGE_DIR=$WORK_DIR/openocd_${OPENOCD_TAG}_${HOST_TRIPLET} ####### # Create pkg-config wrapper and make sure it's used export PKG_CONFIG=$WORK_DIR/$HOST_TRIPLET-pkg-config cat > $PKG_CONFIG <.cmake file ESCAPED_SYSROOT=$(printf '%s\n' "$SYSROOT" | sed -e 's/[\/&]/\\&/g') sed -i -E "s/(SET\(CMAKE_FIND_ROOT_PATH\s+).+\)/\1${ESCAPED_SYSROOT})/" \ ${LIBFTDI_SRC}/cmake/Toolchain-${HOST_TRIPLET}.cmake cmake $LIBFTDI_CONFIG \ -DCMAKE_TOOLCHAIN_FILE=${LIBFTDI_SRC}/cmake/Toolchain-${HOST_TRIPLET}.cmake \ -DCMAKE_INSTALL_PREFIX=${PREFIX} \ -DPKG_CONFIG_EXECUTABLE=`which pkg-config` \ $LIBFTDI_SRC make install DESTDIR=$SYSROOT fi # capstone build & install into sysroot if [ -d $CAPSTONE_SRC ] ; then mkdir -p $CAPSTONE_BUILD_DIR cd $CAPSTONE_BUILD_DIR cp -r $CAPSTONE_SRC/* . make install DESTDIR=$SYSROOT PREFIX=$PREFIX \ CROSS="${HOST_TRIPLET}-" \ $CAPSTONE_CONFIG # fix the generated capstone.pc CAPSTONE_PC_FILE=${SYSROOT}${PREFIX}/lib/pkgconfig/capstone.pc sed -i '/^libdir=/d' $CAPSTONE_PC_FILE sed -i '/^includedir=/d' $CAPSTONE_PC_FILE sed -i '/^archive=/d' $CAPSTONE_PC_FILE sed -i '1s;^;prefix=/usr \ exec_prefix=${prefix} \ libdir=${exec_prefix}/lib \ includedir=${prefix}/include/capstone\n\n;' $CAPSTONE_PC_FILE fi # libjaylink build & install into sysroot if [ -d $LIBJAYLINK_SRC ] ; then mkdir -p $LIBJAYLINK_BUILD_DIR cd $LIBJAYLINK_BUILD_DIR $LIBJAYLINK_SRC/configure --build=`$LIBJAYLINK_SRC/config.guess` --host=$HOST_TRIPLET \ --with-sysroot=$SYSROOT --prefix=$PREFIX \ $LIBJAYLINK_CONFIG make -j $MAKE_JOBS make install DESTDIR=$SYSROOT fi # OpenOCD build & install into sysroot mkdir -p $OPENOCD_BUILD_DIR cd $OPENOCD_BUILD_DIR $OPENOCD_SRC/configure --build=`$OPENOCD_SRC/config.guess` --host=$HOST_TRIPLET \ --with-sysroot=$SYSROOT --prefix=$PREFIX \ $OPENOCD_CONFIG make -j $MAKE_JOBS make install-strip DESTDIR=$SYSROOT # Separate OpenOCD install w/o dependencies. OpenOCD will have to be linked # statically or have dependencies packaged/installed separately. make install-strip DESTDIR=$PACKAGE_DIR