11name : Build libLiteRtLmC
22
3- # Builds the LiteRT-LM C engine as a shared library from source.
4- # Strategy: build the project normally (all static archives), then post-link
5- # them into a single shared library. This avoids patching CMake targets.
3+ # Builds the LiteRT-LM C engine as a shared library using Bazel (the
4+ # upstream's primary build system). CMake was too fragile with its
5+ # ExternalProject dep chain; Bazel handles everything natively.
6+ #
7+ # Strategy: build //c:engine as a static archive via Bazel, then manually
8+ # link it (plus deps) into a shared library with the system linker.
69on :
710 workflow_dispatch :
811 inputs :
@@ -24,30 +27,30 @@ jobs:
2427 steps :
2528 - uses : actions/checkout@v4
2629
27- - name : install build deps
28- run : |
29- sudo apt-get update && sudo apt-get install -y \
30- cmake ninja-build g++ git
31-
3230 - name : clone litert-lm
3331 run : |
3432 git clone --depth=1 --branch=${{ env.LITERT_LM_TAG }} \
3533 https://github.com/google-ai-edge/litert-lm.git /tmp/litert-lm
3634
37- # Use the OUTER CMakeLists.txt — it orchestrates ExternalProject deps
38- # (protobuf, abseil, flatbuffers, TFLite, etc.) in the right order.
39- # PIC flags are critical: every .a must be position-independent to
40- # link into a .so later.
41- - name : cmake configure (outer)
35+ - name : bazel build C engine (static)
36+ working-directory : /tmp/litert-lm
37+ run : |
38+ bazelisk build //c:engine --compilation_mode=opt --copt=-fPIC \
39+ --action_env=CC=gcc --action_env=CXX=g++ \
40+ 2>&1 | tail -30
41+
42+ - name : locate built artifacts
43+ id : artifacts
44+ working-directory : /tmp/litert-lm
4245 run : |
43- cmake -S /tmp/litert-lm -B /tmp/litert-lm/build \
44- -DCMAKE_BUILD_TYPE=Release \
45- -DCMAKE_C_FLAGS="-fPIC" \
46- -DCMAKE_CXX_FLAGS="-fPIC" \
47- -DCMAKE_POSITION_INDEPENDENT_CODE=ON
46+ echo "=== engine .a ==="
47+ ENGINE_A=$(find bazel-bin/c -name '*.a' -type f | head -1)
48+ echo "engine_a=$ENGINE_A" >> $GITHUB_OUTPUT
49+ ls -la "$ENGINE_A" 2>/dev/null || echo "No .a found"
4850
49- - name : cmake build (full project)
50- run : cmake --build /tmp/litert-lm/build -j$(nproc)
51+ echo "=== all .a under bazel-bin ==="
52+ find bazel-bin -name '*.a' -type f | wc -l
53+ find bazel-bin -name '*.a' -type f | head -20
5154
5255 - name : create version script
5356 run : |
@@ -61,29 +64,30 @@ jobs:
6164 EOF
6265
6366 - name : post-link shared library
67+ working-directory : /tmp/litert-lm
6468 run : |
65- BUILD=/tmp/litert-lm/build
66-
67- # The C engine static lib (our API surface)
68- ENGINE_A=$(find $BUILD -name 'libc_engine.a' -type f | head -1)
69- echo "engine lib: $ENGINE_A"
70-
71- # All other static archives ( deps)
72- ALL_A=$(find $BUILD -name '*.a' -type f ! -name 'libc_engine.a' | sort)
69+ ENGINE_A="${{ steps.artifacts.outputs.engine_a }}"
70+ if [ -z "$ENGINE_A" ] || [ ! -f "$ENGINE_A" ]; then
71+ echo "::error::Engine .a not found"
72+ exit 1
73+ fi
74+
75+ # Collect all static deps from bazel-bin
76+ ALL_A=$(find bazel-bin -name '*.a' -type f ! -path "$ENGINE_A" | sort)
7377 echo "total .a files: $(echo "$ALL_A" | wc -l)"
7478
75- # Link: whole-archive the engine (so all litert_lm_* symbols survive),
76- # regular-link the deps (only pull what's referenced).
7779 g++ -shared -o /tmp/libLiteRtLmC.so \
7880 -Wl,--version-script=/tmp/litert_lm_exports.map \
79- -Wl,--whole-archive $ENGINE_A -Wl,--no-whole-archive \
81+ -Wl,--whole-archive " $ENGINE_A" -Wl,--no-whole-archive \
8082 $ALL_A \
8183 -Wl,--allow-multiple-definition \
8284 -lstdc++ -lpthread -ldl -lm
8385
8486 echo "=== output ==="
8587 ls -la /tmp/libLiteRtLmC.so
8688 echo "litert_lm_* symbols:"
89+ nm -D --defined-only /tmp/libLiteRtLmC.so | grep 'litert_lm_' | head -10
90+ echo "total litert_lm_* symbols:"
8791 nm -D --defined-only /tmp/libLiteRtLmC.so | grep -c 'litert_lm_'
8892
8993 - uses : actions/upload-artifact@v4
@@ -99,47 +103,47 @@ jobs:
99103 steps :
100104 - uses : actions/checkout@v4
101105
102- - name : install build deps
103- run : brew install cmake ninja
104-
105106 - name : clone litert-lm
106107 run : |
107108 git clone --depth=1 --branch=${{ env.LITERT_LM_TAG }} \
108109 https://github.com/google-ai-edge/litert-lm.git /tmp/litert-lm
109110
110- - name : cmake configure (outer)
111+ - name : bazel build C engine (static)
112+ working-directory : /tmp/litert-lm
111113 run : |
112- cmake -S /tmp/litert-lm -B /tmp/litert-lm/build \
113- -DCMAKE_BUILD_TYPE=Release \
114- -DCMAKE_POSITION_INDEPENDENT_CODE=ON
114+ bazelisk build //c:engine --compilation_mode=opt \
115+ 2>&1 | tail -30
115116
116- - name : cmake build (full project)
117- run : cmake --build /tmp/litert-lm/build -j$(sysctl -n hw.ncpu)
117+ - name : locate built artifacts
118+ id : artifacts
119+ working-directory : /tmp/litert-lm
120+ run : |
121+ ENGINE_A=$(find bazel-bin/c -name '*.a' -type f | head -1)
122+ echo "engine_a=$ENGINE_A" >> $GITHUB_OUTPUT
123+ ls -la "$ENGINE_A" 2>/dev/null || echo "No .a found"
124+ find bazel-bin -name '*.a' -type f | wc -l
118125
119126 - name : create export list
120127 run : |
121128 grep -E 'LITERT_LM_C_API_EXPORT' /tmp/litert-lm/c/engine.h -A1 | \
122129 grep 'litert_lm_' | sed 's/.*\(litert_lm_[a-z_]*\).*/\1/' | \
123130 sed 's/^/_/' | sort -u > /tmp/litert_lm_exports.txt
124- echo "export count: $(wc -l < /tmp/litert_lm_exports.txt)"
125- cat /tmp/litert_lm_exports.txt
131+ echo "exports: $(wc -l < /tmp/litert_lm_exports.txt)"
126132
127133 - name : post-link shared library
134+ working-directory : /tmp/litert-lm
128135 run : |
129- BUILD=/tmp/litert-lm/build
130-
131- ENGINE_A=$(find $BUILD -name 'libc_engine.a' -type f | head -1)
132- echo "engine lib: $ENGINE_A"
133-
134- ALL_A=$(find $BUILD -name '*.a' -type f ! -name 'libc_engine.a' | sort)
136+ ENGINE_A="${{ steps.artifacts.outputs.engine_a }}"
137+ ALL_A=$(find bazel-bin -name '*.a' -type f ! -path "$ENGINE_A" | sort)
135138 echo "total .a files: $(echo "$ALL_A" | wc -l)"
136139
137140 clang++ -dynamiclib -o /tmp/libLiteRtLmC.dylib \
138141 -Wl,-exported_symbols_list,/tmp/litert_lm_exports.txt \
139- -Wl,-all_load $ENGINE_A \
142+ -Wl,-all_load " $ENGINE_A" \
140143 $ALL_A \
141144 -framework Foundation -framework Metal -framework CoreFoundation \
142- -lstdc++ -lpthread -ldl -lm
145+ -lstdc++ -lpthread -ldl -lm \
146+ 2>&1 | tail -20
143147
144148 echo "=== output ==="
145149 ls -la /tmp/libLiteRtLmC.dylib
0 commit comments