154 lines
4.9 KiB
Bash
154 lines
4.9 KiB
Bash
#!/bin/bash
|
||
# compile.sh — KL630 cross-compile (ARM armv7-a)
|
||
# Run inside Docker: docker run --rm -v "<host_path>:/workspace/kl630_build" kl630-dev bash /workspace/kl630_build/compile.sh
|
||
set -e
|
||
|
||
WORKSPACE=/workspace/kl630_build
|
||
BUILD_DIR=$WORKSPACE/build
|
||
OUTPUT=$BUILD_DIR/kp_firmware_host_stream
|
||
CC=arm-linux-gnueabihf-gcc
|
||
LIB_DIR=$WORKSPACE/lib
|
||
|
||
echo "=== Checking compiler ==="
|
||
which $CC || { echo "ERROR: $CC not found"; exit 1; }
|
||
$CC --version | head -1
|
||
|
||
mkdir -p $BUILD_DIR
|
||
|
||
CFLAGS="-DVATICS_PLATFORM -DKL630 -D_GNU_SOURCE -U_FORTIFY_SOURCE"
|
||
CFLAGS="$CFLAGS -march=armv7-a -mfpu=neon -mfloat-abi=hard -Os"
|
||
CFLAGS="$CFLAGS -Wall -Wno-unused-variable -Wno-unused-function"
|
||
|
||
INCLUDES="-I$WORKSPACE/include/host_stream"
|
||
INCLUDES="$INCLUDES -I$WORKSPACE/include/app_flow"
|
||
INCLUDES="$INCLUDES -I$WORKSPACE/include/app_flow/pre_post_proc"
|
||
INCLUDES="$INCLUDES -I$WORKSPACE/include/common"
|
||
|
||
# Prefer real SDK headers when available; fallback to local fake headers.
|
||
SDK_INCLUDE_CANDIDATES=(
|
||
#"$WORKSPACE/SDK/sdk/vtcs_root_vienna/include"
|
||
"$WORKSPACE/include/vtcs_root_vienna/include"
|
||
"$WORKSPACE/third_party/kl630_sdk/include"
|
||
)
|
||
SDK_SYSROOT_INCLUDE="$WORKSPACE/third_party/kl630_sdk/sysroot/usr/include"
|
||
#SDK_MODULES_ROOT="$WORKSPACE/SDK/sdk/modules"
|
||
SDK_MODULES_ROOT="$WORKSPACE/include/modules"
|
||
USE_FAKE_HEADERS=1
|
||
for SDK_INCLUDE_ROOT in "${SDK_INCLUDE_CANDIDATES[@]}"; do
|
||
if [ -d "$SDK_INCLUDE_ROOT" ]; then
|
||
INCLUDES="$INCLUDES -I$SDK_INCLUDE_ROOT"
|
||
if [ -d "$SDK_INCLUDE_ROOT/vmf" ]; then
|
||
INCLUDES="$INCLUDES -I$SDK_INCLUDE_ROOT/vmf"
|
||
fi
|
||
USE_FAKE_HEADERS=0
|
||
echo "=== Using SDK include: $SDK_INCLUDE_ROOT ==="
|
||
break
|
||
fi
|
||
done
|
||
if [ -d "$SDK_MODULES_ROOT" ]; then
|
||
INCLUDES="$INCLUDES -I$SDK_MODULES_ROOT"
|
||
fi
|
||
if [ -d "$SDK_SYSROOT_INCLUDE" ]; then
|
||
INCLUDES="$INCLUDES -I$SDK_SYSROOT_INCLUDE"
|
||
fi
|
||
if [ -d "$WORKSPACE/include/fake" ]; then
|
||
# Keep fake headers as the last fallback for components not shipped in this SDK pack.
|
||
INCLUDES="$INCLUDES -I$WORKSPACE/include/fake"
|
||
fi
|
||
if [ "$USE_FAKE_HEADERS" -eq 1 ]; then
|
||
echo "=== Header mode: fallback fake headers ==="
|
||
else
|
||
CFLAGS="$CFLAGS -DUSE_REAL_SDK_HEADERS=1"
|
||
echo "=== Header mode: real SDK headers + fake fallback ==="
|
||
fi
|
||
|
||
ALL_SRCS=$(ls \
|
||
$WORKSPACE/src/host_stream/*.c \
|
||
$WORKSPACE/src/app_flow/*.c \
|
||
$WORKSPACE/src/pre_post_proc/*.c \
|
||
2>/dev/null)
|
||
|
||
echo ""
|
||
echo "=== Source files ==="
|
||
for s in $ALL_SRCS; do echo " $s"; done
|
||
|
||
echo ""
|
||
echo "=== Compiling ==="
|
||
OBJ_FILES=()
|
||
COMPILE_ERRORS=0
|
||
|
||
for src in $ALL_SRCS; do
|
||
base=$(basename $src .c)
|
||
obj=$BUILD_DIR/${base}.o
|
||
echo " CC $base.c"
|
||
if $CC $CFLAGS $INCLUDES -c "$src" -o "$obj" 2>&1; then
|
||
OBJ_FILES+=("$obj")
|
||
else
|
||
echo " *** COMPILE ERROR: $src ***"
|
||
COMPILE_ERRORS=$((COMPILE_ERRORS + 1))
|
||
fi
|
||
done
|
||
|
||
if [ $COMPILE_ERRORS -gt 0 ]; then
|
||
echo ""
|
||
echo "ERROR: $COMPILE_ERRORS file(s) failed to compile."
|
||
exit 1
|
||
fi
|
||
|
||
echo ""
|
||
echo "=== All objects compiled ==="
|
||
|
||
# 建立 app_yolo symlink(versioned .so)
|
||
if [ ! -e "$LIB_DIR/libapp_yolo.so" ]; then
|
||
AYSO=$(ls $LIB_DIR/libapp_yolo.so* 2>/dev/null | head -1)
|
||
if [ -n "$AYSO" ]; then
|
||
ln -sf $(basename $AYSO) $LIB_DIR/libapp_yolo.so
|
||
echo " symlink: libapp_yolo.so -> $(basename $AYSO)"
|
||
fi
|
||
fi
|
||
|
||
# 建立 uClibc rpath-link symlinks
|
||
# 只建 libc.so.0/libc.so.1 供 rpath-link 解析 libvmf.so 的依賴
|
||
# 不建 libc.so 和 libpthread.so — 讓 -lc/-lpthread 繼續用 glibc startup
|
||
if [ -e "$LIB_DIR/libuClibc-1.0.34.so" ]; then
|
||
for name in libc.so.0 libc.so.1; do
|
||
[ ! -e "$LIB_DIR/$name" ] && ln -sf libuClibc-1.0.34.so $LIB_DIR/$name && echo " symlink: $name -> libuClibc-1.0.34.so"
|
||
done
|
||
else
|
||
echo "WARNING: libuClibc-1.0.34.so not found in $LIB_DIR"
|
||
echo " Transfer it from device: tftp -p -l /lib/libuClibc-1.0.34.so -r libuClibc-1.0.34.so <host_ip> 9069"
|
||
fi
|
||
|
||
echo ""
|
||
echo "=== Linking ==="
|
||
|
||
$CC -march=armv7-a -mfpu=neon -mfloat-abi=hard \
|
||
"${OBJ_FILES[@]}" \
|
||
-L$LIB_DIR \
|
||
-Wl,-rpath-link,$LIB_DIR \
|
||
-Wl,-rpath,\$ORIGIN/lib \
|
||
-Wl,--dynamic-linker,/lib/ld-uClibc.so.1 \
|
||
-Wl,--allow-shlib-undefined \
|
||
-Wl,--allow-multiple-definition \
|
||
-lvmf -lmembroker -lmsgbroker -lsyncringbuffer -liniparser \
|
||
-lvmf_nnm -lkutils -laio -lpthread -lm \
|
||
-lapp_yolo \
|
||
-o $OUTPUT \
|
||
&& echo "" \
|
||
&& echo "=== SUCCESS: $OUTPUT ===" \
|
||
|| { echo ""; echo "=== LINK FAILED ==="; exit 1; }
|
||
|
||
ls -lh $OUTPUT
|
||
|
||
echo ""
|
||
echo "=== Patching ELF for uClibc ==="
|
||
# Remove glibc dynamic linker (causes ld-uClibc to try loading itself as .so)
|
||
patchelf --remove-needed ld-linux-armhf.so.3 $OUTPUT
|
||
# Map glibc sonames to uClibc equivalents
|
||
patchelf --replace-needed libc.so.6 libc.so.0 $OUTPUT
|
||
patchelf --remove-needed libm.so.6 $OUTPUT
|
||
patchelf --remove-needed libpthread.so.0 $OUTPUT
|
||
|
||
echo "=== NEEDED after patch ==="
|
||
readelf -d $OUTPUT | grep NEEDED
|