#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" LOCAL_OCCT_SOURCE_DIR="${ROOT_DIR}/.cache/occt/occt" LEGACY_OCCT_SOURCE_DIR="/home/mes123456/working/WebCam/occt" if [[ -z "${OCCT_SOURCE_DIR:-}" ]]; then if [[ -f "${LOCAL_OCCT_SOURCE_DIR}/CMakeLists.txt" ]]; then OCCT_SOURCE_DIR="${LOCAL_OCCT_SOURCE_DIR}" else OCCT_SOURCE_DIR="${LEGACY_OCCT_SOURCE_DIR}" fi fi if [[ -z "${OCCT_BUILD_DIR:-}" ]]; then if [[ "${OCCT_SOURCE_DIR}" == "${LOCAL_OCCT_SOURCE_DIR}" ]]; then OCCT_BUILD_DIR="${ROOT_DIR}/.cache/bitbybit/occt-history-build-offline" else OCCT_BUILD_DIR="${ROOT_DIR}/.cache/bitbybit/occt-history-build" fi fi DIST_DIR="${OCCT_HISTORY_DIST_DIR:-${ROOT_DIR}/native/occt-history/dist}" PUBLIC_DIR="${OCCT_HISTORY_PUBLIC_DIR:-${ROOT_DIR}/public/native/occt-history}" PUBLISH_ARTIFACT="${OCCT_HISTORY_PUBLISH:-1}" JOBS="${JOBS:-$(nproc)}" FREECAD_WASM_SDK_DIR="${FREECAD_WASM_SDK_DIR:-}" if [[ "${FREECAD_WASM_NAMING_REQUIRED:-0}" == "1" && -z "${FREECAD_WASM_SDK_DIR}" ]]; then echo "FREECAD_WASM_SDK_DIR is required for build:freecad-naming-worker; refusing to produce an OCCT-only artifact." >&2 exit 1 fi if [[ -n "${FREECAD_WASM_SDK_DIR}" ]]; then FREECAD_WASM_SDK_DIR="${FREECAD_WASM_SDK_DIR}" node "${ROOT_DIR}/scripts/check-freecad-naming-sdk.mjs" >/dev/null fi if [[ ! -f "${OCCT_SOURCE_DIR}/CMakeLists.txt" ]]; then echo "OCCT source checkout not found: ${OCCT_SOURCE_DIR}" >&2 exit 1 fi if ! command -v emcmake >/dev/null || ! command -v em++ >/dev/null; then echo "Emscripten emcmake/em++ are required." >&2 exit 1 fi OCCT_CXX_FLAGS="-fexceptions" OCCT_CXX_RELEASE_FLAGS="-O0 -DNDEBUG -fexceptions" if [[ -n "${FREECAD_WASM_SDK_DIR}" ]]; then OCCT_CXX_FLAGS+=" -pthread" OCCT_CXX_RELEASE_FLAGS+=" -pthread" fi emcmake cmake -S "${OCCT_SOURCE_DIR}" -B "${OCCT_BUILD_DIR}" -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_MAKE_PROGRAM="$(command -v ninja)" \ -DCMAKE_CXX_FLAGS="${OCCT_CXX_FLAGS}" \ -DCMAKE_CXX_FLAGS_RELEASE="${OCCT_CXX_RELEASE_FLAGS}" \ -DBUILD_RELEASE_DISABLE_EXCEPTIONS=OFF \ -DBUILD_LIBRARY_TYPE=Static \ -DBUILD_MODULE_FoundationClasses=ON \ -DBUILD_MODULE_ModelingData=ON \ -DBUILD_MODULE_ModelingAlgorithms=ON \ -DBUILD_MODULE_Visualization=OFF \ -DBUILD_MODULE_ApplicationFramework=OFF \ -DBUILD_MODULE_DataExchange=ON \ -DBUILD_MODULE_Draw=OFF \ -DBUILD_ADDITIONAL_TOOLKITS="TKBO;TKFillet;TKOffset;TKDESTEP" \ -DBUILD_DOC_Overview=OFF \ -DBUILD_Inspector=OFF \ -DBUILD_SAMPLES_QT=OFF \ -DBUILD_USE_PCH=OFF \ -DUSE_FREETYPE=OFF \ -DUSE_TK=OFF \ -DUSE_TBB=OFF \ -DUSE_RAPIDJSON=OFF cmake --build "${OCCT_BUILD_DIR}" --target \ TKernel TKMath TKG2d TKG3d TKGeomBase TKGeomAlgo TKShHealing TKPrim TKTopAlgo TKBRep TKBool TKBO TKFillet TKOffset \ TKDE TKXSBase TKDESTEP \ --parallel "${JOBS}" mkdir -p "${DIST_DIR}" SOURCES=("${ROOT_DIR}/native/occt-history/occt_history.cpp") INCLUDES=("-I${OCCT_BUILD_DIR}/include/opencascade" "-I${OCCT_SOURCE_DIR}/src") DEFINES=() FREECAD_LIBRARIES=() FREECAD_LINK_OPTIONS=() if [[ -n "${FREECAD_WASM_SDK_DIR}" ]]; then BRIDGE_SOURCE="$(node -e 'const fs=require("node:fs"); const p=require("node:path"); const m=JSON.parse(fs.readFileSync(p.resolve(process.argv[1],"manifest.json"),"utf8")); console.log(p.isAbsolute(m.namingBridge.source) ? m.namingBridge.source : p.resolve(process.argv[1],m.namingBridge.source))' "${FREECAD_WASM_SDK_DIR}")" SOURCES+=("${BRIDGE_SOURCE}") while IFS= read -r include_dir; do INCLUDES+=("-I${include_dir}"); done < <(node -e 'const fs=require("node:fs"); const p=require("node:path"); const root=p.resolve(process.argv[1]); const m=JSON.parse(fs.readFileSync(p.resolve(root,"manifest.json"),"utf8")); for (const d of m.includeDirs) console.log(p.isAbsolute(d) ? d : p.resolve(root,d))' "${FREECAD_WASM_SDK_DIR}") while IFS= read -r library; do FREECAD_LIBRARIES+=("${library}"); done < <(node -e 'const fs=require("node:fs"); const p=require("node:path"); const root=p.resolve(process.argv[1]); const m=JSON.parse(fs.readFileSync(p.resolve(root,"manifest.json"),"utf8")); for (const l of m.libraries) console.log(p.isAbsolute(l.path) ? l.path : p.resolve(root,l.path))' "${FREECAD_WASM_SDK_DIR}") while IFS= read -r definition; do DEFINES+=("-D${definition}"); done < <(node -e 'const fs=require("node:fs"); const p=require("node:path"); const m=JSON.parse(fs.readFileSync(p.resolve(process.argv[1],"manifest.json"),"utf8")); for (const d of m.compileOptions.definitions) console.log(d)' "${FREECAD_WASM_SDK_DIR}") CXX_STANDARD="$(node -e 'const fs=require("node:fs"); const p=require("node:path"); const m=JSON.parse(fs.readFileSync(p.resolve(process.argv[1],"manifest.json"),"utf8")); console.log(m.compileOptions.cxxStandard)' "${FREECAD_WASM_SDK_DIR}")" FORCE_INCLUDE="$(node -e 'const fs=require("node:fs"); const p=require("node:path"); const root=p.resolve(process.argv[1]); const m=JSON.parse(fs.readFileSync(p.resolve(root,"manifest.json"),"utf8")); const v=m.compileOptions.forceInclude; console.log(p.isAbsolute(v) ? v : p.resolve(root,v))' "${FREECAD_WASM_SDK_DIR}")" HOST_ADAPTER="$(node -e 'const fs=require("node:fs"); const p=require("node:path"); const root=p.resolve(process.argv[1]); const m=JSON.parse(fs.readFileSync(p.resolve(root,"manifest.json"),"utf8")); const v=m.namingBridge.hostAdapter; console.log(p.isAbsolute(v) ? v : p.resolve(root,v))' "${FREECAD_WASM_SDK_DIR}")" FREECAD_LINK_OPTIONS+=("-include" "${FORCE_INCLUDE}" "-pthread" "--pre-js" "${HOST_ADAPTER}" "-sPTHREAD_POOL_SIZE=2") while IFS=$'\t' read -r asset_path preload_to; do FREECAD_LINK_OPTIONS+=("--preload-file" "${asset_path}@${preload_to}") done < <(node -e 'const fs=require("node:fs"); const p=require("node:path"); const root=p.resolve(process.argv[1]); const m=JSON.parse(fs.readFileSync(p.resolve(root,"manifest.json"),"utf8")); for (const a of m.runtimeAssets) { const v=p.isAbsolute(a.path) ? a.path : p.resolve(root,a.path); console.log(`${v}\t${a.preloadTo}`) }' "${FREECAD_WASM_SDK_DIR}") DEFINES+=("-DBITBYBIT_FREECAD_NAMING_LINKED=1") else CXX_STANDARD="c++17" fi em++ "${SOURCES[@]}" "${INCLUDES[@]}" "${DEFINES[@]}" "${FREECAD_LINK_OPTIONS[@]}" \ -I"${OCCT_BUILD_DIR}/include/opencascade" \ -I"${OCCT_SOURCE_DIR}/src" \ -std="${CXX_STANDARD}" -O2 -fexceptions --bind \ -Wl,--start-group \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKBO.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKFillet.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKOffset.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKBool.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKDESTEP.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKXSBase.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKDE.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKBRep.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKTopAlgo.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKPrim.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKShHealing.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKGeomAlgo.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKGeomBase.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKG3d.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKG2d.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKMath.a" \ "${OCCT_BUILD_DIR}/lin32/clang/lib/libTKernel.a" \ "${FREECAD_LIBRARIES[@]}" \ -Wl,--end-group \ -sMODULARIZE=1 -sEXPORT_ES6=1 -sENVIRONMENT=web,worker,node \ -sALLOW_MEMORY_GROWTH=1 -sINITIAL_MEMORY=134217728 -sMAXIMUM_MEMORY=2147483648 \ -sNO_EXIT_RUNTIME=1 \ -o "${DIST_DIR}/bitbybit-occt-history.js" cp "${ROOT_DIR}/native/occt-history/package.json" "${DIST_DIR}/package.json" if [[ "${PUBLISH_ARTIFACT}" == "1" ]]; then mkdir -p "${PUBLIC_DIR}" for artifact in "${DIST_DIR}"/bitbybit-occt-history.{js,wasm,data,worker.js}; do [[ -f "${artifact}" ]] && cp "${artifact}" "${PUBLIC_DIR}/$(basename "${artifact}")" done elif [[ "${PUBLISH_ARTIFACT}" != "0" ]]; then echo "OCCT_HISTORY_PUBLISH must be 0 or 1." >&2 exit 1 fi sha256sum "${DIST_DIR}"/bitbybit-occt-history.{js,wasm,data} 2>/dev/null || sha256sum "${DIST_DIR}/bitbybit-occt-history.js" "${DIST_DIR}/bitbybit-occt-history.wasm"