pcbjam/scripts/kicad/build-pcbnew.sh

176 lines
5.9 KiB
Shell
Raw Normal View History

#!/bin/bash
# Build KiCad PCBnew for WebAssembly
# This builds the PCB editor as a standalone WASM application
#
# Usage:
# ./scripts/kicad/build-pcbnew.sh [options]
#
# Options:
# --no-clean Skip cleaning the build directory (default: clean before build)
# --skip-deps Skip building dependencies
# --debug Build with debug symbols
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPT_DIR}/../common/env.sh"
source "${SCRIPT_DIR}/../common/versions.sh"
source "${SCRIPT_DIR}/../common/functions.sh"
KICAD_DIR="${PROJECT_ROOT}/kicad"
KICAD_BUILD="${BUILD_ROOT}/kicad-pcbnew"
KICAD_STAMP="${BUILD_ROOT}/stamps/kicad-pcbnew.stamp"
WASM_LAYER="${PROJECT_ROOT}/wasm"
WX_BUILD="${BUILD_ROOT}/wxwidgets-universal"
# Parse arguments - clean by default
NO_CLEAN=0
SKIP_DEPS=0
DEBUG=0
for arg in "$@"; do
case $arg in
--no-clean)
NO_CLEAN=1
;;
--skip-deps)
SKIP_DEPS=1
;;
--debug)
DEBUG=1
;;
esac
done
# Step 1: Clean build directory (default behavior)
if [ $NO_CLEAN -eq 0 ]; then
log_info "Cleaning KiCad PCBnew build directory..."
rm -rf "${KICAD_BUILD}" "${KICAD_STAMP}"
else
log_info "Skipping clean (--no-clean specified)"
fi
# Step 2: Build dependencies
if [ $SKIP_DEPS -eq 0 ]; then
log_info "Building dependencies..."
"${SCRIPT_DIR}/../deps/build-all-deps.sh" --all
else
log_info "Skipping dependencies (--skip-deps specified)"
fi
# Step 3: Check if already built (only relevant with --no-clean)
if [ $NO_CLEAN -eq 1 ] && check_stamp "${KICAD_STAMP}"; then
log_info "KiCad PCBnew already built, skipping..."
exit 0
fi
# Step 4: Verify wxWidgets is built
if [ ! -f "${WX_BUILD}/lib/libwx_baseu-3.2.a" ]; then
log_error "wxWidgets not found. Please build wxWidgets first with:"
log_error " ./scripts/build-wxuniversal-wasm.sh"
exit 1
fi
log_info "Building KiCad PCBnew ${KICAD_VERSION} for WASM..."
# Step 5: Set build type
if [ $DEBUG -eq 1 ]; then
BUILD_TYPE="Debug"
EXTRA_FLAGS="-g -O0"
else
BUILD_TYPE="Release"
EXTRA_FLAGS="-O2"
fi
# Step 6: Create build directory
mkdir -p "${KICAD_BUILD}"
cd "${KICAD_BUILD}"
# Step 6.1: Build stub libraries for missing symbols
STUBS_DIR="${PROJECT_ROOT}/wasm/stubs"
STUBS_BUILD="${BUILD_ROOT}/stubs"
mkdir -p "${STUBS_BUILD}"
log_info "Building stub libraries..."
# Compile libgit2 stub
emcc -c "${STUBS_DIR}/libgit2_stub.c" -o "${STUBS_BUILD}/libgit2_stub.o"
emar rcs "${STUBS_BUILD}/libgit2_stub.a" "${STUBS_BUILD}/libgit2_stub.o"
# Compile curl stub
emcc -c "${STUBS_DIR}/curl_stub.c" -o "${STUBS_BUILD}/curl_stub.o"
emar rcs "${STUBS_BUILD}/libcurl_stub.a" "${STUBS_BUILD}/curl_stub.o"
log_info "Stub libraries built"
# Step 6.5: Verify WASM support is in KiCad fork
# The kicad submodule should already have WASM port detection and kiplatform support
KICAD_CMAKE="${KICAD_DIR}/CMakeLists.txt"
if ! grep -q "msw|qt|gtk|osx|wasm" "${KICAD_CMAKE}"; then
log_error "KiCad fork is missing WASM port detection support."
log_error "Please ensure the kicad submodule has WASM modifications."
exit 1
fi
KIPLATFORM_CMAKE="${KICAD_DIR}/libs/kiplatform/CMakeLists.txt"
if ! grep -q "KICAD_WX_PORT STREQUAL wasm" "${KIPLATFORM_CMAKE}"; then
log_error "KiCad fork is missing kiplatform WASM support."
log_error "Please ensure the kicad submodule has WASM modifications."
exit 1
fi
log_info "KiCad WASM support verified"
# Step 7: Configure KiCad with CMake
# We use CMAKE_MODULE_PATH to inject our compatibility layer
log_info "Configuring KiCad with CMake..."
emcmake cmake "${KICAD_DIR}" \
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DCMAKE_INSTALL_PREFIX="${SYSROOT}" \
-DCMAKE_MODULE_PATH="${WASM_LAYER}/cmake" \
-DSYSROOT="${SYSROOT}" \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_CXX_FLAGS="${EXTRA_FLAGS} -pthread -sUSE_ZLIB=1 -DKICAD_USE_PLATFORM_WASM=1 -I${SYSROOT}/include" \
-DCMAKE_C_FLAGS="${EXTRA_FLAGS} -pthread -sUSE_ZLIB=1 -I${SYSROOT}/include" \
-DCMAKE_EXE_LINKER_FLAGS="-pthread -sUSE_ZLIB=1 -sASYNCIFY=1 -sASYNCIFY_STACK_SIZE=65536 -sUSE_PTHREADS=1 -sPTHREAD_POOL_SIZE=4 -sALLOW_MEMORY_GROWTH=1 -sINITIAL_MEMORY=256MB -sMAXIMUM_MEMORY=4GB -L${SYSROOT}/lib ${STUBS_BUILD}/libgit2_stub.a ${STUBS_BUILD}/libcurl_stub.a" \
-DCMAKE_PREFIX_PATH="${SYSROOT};${WX_BUILD}" \
-DwxWidgets_CONFIG_EXECUTABLE="${WX_BUILD}/wx-config" \
\
-DKICAD_BUILD_QA_TESTS=OFF \
-DKICAD_SPICE=OFF \
-DKICAD_USE_EGL=OFF \
-DKICAD_USE_BUNDLED_GLEW=ON \
\
-DZSTD_ROOT="${SYSROOT}" \
-DZSTD_INCLUDE_DIR="${SYSROOT}/include" \
-DZSTD_LIBRARY="${SYSROOT}/lib/libzstd.a" \
-DGLM_INCLUDE_DIR="${SYSROOT}/include" \
-DBOOST_ROOT="${SYSROOT}" \
-DBoost_INCLUDE_DIR="${SYSROOT}/include" \
-DBoost_LIBRARY_DIR="${SYSROOT}/lib" \
-DBoost_NO_SYSTEM_PATHS=ON \
-DBoost_NO_BOOST_CMAKE=ON \
-DFREETYPE_INCLUDE_DIR_ft2build="${SYSROOT}/include/freetype2" \
-DFREETYPE_INCLUDE_DIR_freetype2="${SYSROOT}/include/freetype2" \
-DFREETYPE_LIBRARY="${SYSROOT}/lib/libfreetype.a" \
-DHarfBuzz_INCLUDE_DIR="${SYSROOT}/include/harfbuzz" \
-DHarfBuzz_LIBRARY="${SYSROOT}/lib/libharfbuzz.a" \
-DOCC_INCLUDE_DIR="${SYSROOT}/include/opencascade" \
-DOCC_LIBRARY_DIR="${SYSROOT}/lib" \
-DProtobuf_INCLUDE_DIR="${SYSROOT}/include" \
-DProtobuf_LIBRARY="${SYSROOT}/lib/libprotobuf.a" \
-DProtobuf_LITE_LIBRARY="${SYSROOT}/lib/libprotobuf-lite.a" \
-DODBC_CONFIG:STRING="stub-for-wasm" \
-DODBCLIB:STRING="" \
-DODBC_CFLAGS:STRING="" \
-DODBC_LINK_FLAGS:STRING="" \
-DODBC_LIBRARIES:STRING="" \
\
-DBUILD_GITHUB_PLUGIN=OFF \
-DKICAD_PCM=OFF
# Step 8: Build pcbnew target
log_info "Building pcbnew..."
JOBS=${JOBS:-$(sysctl -n hw.ncpu 2>/dev/null || nproc 2>/dev/null || echo 4)}
emmake make -j${JOBS} pcbnew
# Step 9: Create stamp file
create_stamp "${KICAD_STAMP}"
log_info "KiCad PCBnew build complete!"
log_info "Output: ${KICAD_BUILD}/pcbnew/pcbnew.js"