2 # SPDX-License-Identifier: GPL-2.0-or-later
4 # This is an example of how to do a cross-build of OpenOCD using pkg-config.
5 # Cross-building with pkg-config is deceptively hard and most guides and
6 # tutorials are incomplete or give bad advice. Some of the traps that are easy
7 # to fall in but handled by this script are:
9 # * Polluting search paths and flags with values from the build system.
10 # * Faulty pkg-config wrappers shipped with distribution packaged cross-
12 # * Build failing because pkg-config discards some paths even though they are
13 # correctly listed in the .pc file.
14 # * Getting successfully built binaries that cannot find runtime data because
15 # paths refer to the build file system.
17 # This script is probably more useful as a reference than as a complete build
18 # tool but for some configurations it may be usable as-is. It only cross-builds
19 # libusb-1.0, hidapi, libftdi and capstone from source, but the script can be
20 # extended to build other prerequisites in a similar manner.
23 # export LIBUSB1_SRC=/path/to/libusb-1.0
24 # export HIDAPI_SRC=/path/to/hidapi
25 # export OPENOCD_CONFIG="--enable-..."
27 # /path/to/openocd/contrib/cross-build.sh <host-triplet>
29 # For static linking, a workaround is to
30 # export LIBUSB1_CONFIG="--enable-static --disable-shared"
32 # All the paths must not contain any spaces.
38 ## Source code paths, customize as necessary
39 : ${OPENOCD_SRC:="`dirname "$0"`/.."}
40 : ${LIBUSB1_SRC:=/path/to/libusb1}
41 : ${HIDAPI_SRC:=/path/to/hidapi}
42 : ${LIBFTDI_SRC:=/path/to/libftdi}
43 : ${CAPSTONE_SRC:=/path/to/capstone}
44 : ${LIBJAYLINK_SRC:=/path/to/libjaylink}
46 OPENOCD_SRC
=`readlink -m $OPENOCD_SRC`
47 LIBUSB1_SRC
=`readlink -m $LIBUSB1_SRC`
48 HIDAPI_SRC
=`readlink -m $HIDAPI_SRC`
49 LIBFTDI_SRC
=`readlink -m $LIBFTDI_SRC`
50 CAPSTONE_SRC
=`readlink -m $CAPSTONE_SRC`
51 LIBJAYLINK_SRC
=`readlink -m $LIBJAYLINK_SRC`
54 BUILD_DIR
=$WORK_DIR/$HOST_TRIPLET-build
55 LIBUSB1_BUILD_DIR
=$BUILD_DIR/libusb1
56 HIDAPI_BUILD_DIR
=$BUILD_DIR/hidapi
57 LIBFTDI_BUILD_DIR
=$BUILD_DIR/libftdi
58 CAPSTONE_BUILD_DIR
=$BUILD_DIR/capstone
59 LIBJAYLINK_BUILD_DIR
=$BUILD_DIR/libjaylink
60 OPENOCD_BUILD_DIR
=$BUILD_DIR/openocd
62 ## Root of host file tree
63 SYSROOT
=$WORK_DIR/$HOST_TRIPLET-root
65 ## Install location within host file tree
71 ## OpenOCD-only install dir for packaging
72 : ${OPENOCD_TAG:=`git --git-dir=$OPENOCD_SRC/.git describe --tags`}
73 PACKAGE_DIR
=$WORK_DIR/openocd_
${OPENOCD_TAG}_
${HOST_TRIPLET}
77 # Create pkg-config wrapper and make sure it's used
78 export PKG_CONFIG
=$WORK_DIR/$HOST_TRIPLET-pkg-config
80 cat > $PKG_CONFIG <<EOF
85 export PKG_CONFIG_DIR=
86 export PKG_CONFIG_LIBDIR=\${SYSROOT}$PREFIX/lib/pkgconfig:\${SYSROOT}$PREFIX/share/pkgconfig
87 export PKG_CONFIG_SYSROOT_DIR=\${SYSROOT}
89 # The following have to be set to avoid pkg-config to strip /usr/include and /usr/lib from paths
90 # before they are prepended with the sysroot path. Feels like a pkg-config bug.
91 export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=
92 export PKG_CONFIG_ALLOW_SYSTEM_LIBS=
99 rm -rf $SYSROOT $BUILD_DIR
102 # libusb-1.0 build & install into sysroot
103 if [ -d $LIBUSB1_SRC ] ; then
104 mkdir
-p $LIBUSB1_BUILD_DIR
105 cd $LIBUSB1_BUILD_DIR
106 $LIBUSB1_SRC/configure
--build=`$LIBUSB1_SRC/config.guess` --host=$HOST_TRIPLET \
107 --with-sysroot=$SYSROOT --prefix=$PREFIX \
110 make install DESTDIR
=$SYSROOT
113 # hidapi build & install into sysroot
114 if [ -d $HIDAPI_SRC ] ; then
115 mkdir
-p $HIDAPI_BUILD_DIR
117 $HIDAPI_SRC/configure
--build=`$HIDAPI_SRC/config.guess` --host=$HOST_TRIPLET \
118 --with-sysroot=$SYSROOT --prefix=$PREFIX \
121 make install DESTDIR
=$SYSROOT
124 # libftdi build & install into sysroot
125 if [ -d $LIBFTDI_SRC ] ; then
126 mkdir
-p $LIBFTDI_BUILD_DIR
127 cd $LIBFTDI_BUILD_DIR
128 # note : libftdi versions < 1.5 requires libusb1 static
129 # hint use : # export LIBUSB1_CONFIG="--enable-static ..."
130 # not needed since libftdi-1.5 when LIBFTDI_CONFIG="-DSTATICLIBS=OFF ..."
132 # fix <toolchain>.cmake file
133 ESCAPED_SYSROOT
=$
(printf '%s\n' "$SYSROOT" |
sed -e 's/[\/&]/\\&/g')
134 sed -i -E "s/(SET\(CMAKE_FIND_ROOT_PATH\s+).+\)/\1${ESCAPED_SYSROOT})/" \
135 ${LIBFTDI_SRC}/cmake
/Toolchain-
${HOST_TRIPLET}.cmake
137 cmake
$LIBFTDI_CONFIG \
138 -DCMAKE_TOOLCHAIN_FILE=${LIBFTDI_SRC}/cmake
/Toolchain-
${HOST_TRIPLET}.cmake \
139 -DCMAKE_INSTALL_PREFIX=${PREFIX} \
140 -DPKG_CONFIG_EXECUTABLE=`which pkg-config` \
142 make install DESTDIR
=$SYSROOT
145 # capstone build & install into sysroot
146 if [ -d $CAPSTONE_SRC ] ; then
147 mkdir
-p $CAPSTONE_BUILD_DIR
148 cd $CAPSTONE_BUILD_DIR
149 cp -r $CAPSTONE_SRC/* .
150 make install DESTDIR
=$SYSROOT PREFIX
=$PREFIX \
151 CROSS
="${HOST_TRIPLET}-" \
153 # fix the generated capstone.pc
154 CAPSTONE_PC_FILE
=${SYSROOT}${PREFIX}/lib
/pkgconfig
/capstone.pc
155 sed -i '/^libdir=/d' $CAPSTONE_PC_FILE
156 sed -i '/^includedir=/d' $CAPSTONE_PC_FILE
157 sed -i '/^archive=/d' $CAPSTONE_PC_FILE
158 sed -i '1s;^;prefix=/usr \
159 exec_prefix=${prefix} \
160 libdir=${exec_prefix}/lib \
161 includedir=${prefix}/include/capstone\n\n;' $CAPSTONE_PC_FILE
164 # libjaylink build & install into sysroot
165 if [ -d $LIBJAYLINK_SRC ] ; then
166 mkdir
-p $LIBJAYLINK_BUILD_DIR
167 cd $LIBJAYLINK_BUILD_DIR
168 $LIBJAYLINK_SRC/configure
--build=`$LIBJAYLINK_SRC/config.guess` --host=$HOST_TRIPLET \
169 --with-sysroot=$SYSROOT --prefix=$PREFIX \
172 make install DESTDIR
=$SYSROOT
175 # OpenOCD build & install into sysroot
176 mkdir
-p $OPENOCD_BUILD_DIR
177 cd $OPENOCD_BUILD_DIR
178 $OPENOCD_SRC/configure
--build=`$OPENOCD_SRC/config.guess` --host=$HOST_TRIPLET \
179 --with-sysroot=$SYSROOT --prefix=$PREFIX \
182 make install-strip DESTDIR
=$SYSROOT
184 # Separate OpenOCD install w/o dependencies. OpenOCD will have to be linked
185 # statically or have dependencies packaged/installed separately.
186 make install-strip DESTDIR
=$PACKAGE_DIR