Skip to content

Commit 597cae6

Browse files
committed
build: rework Makefile and InfiniSim container workflow
1 parent 6572b50 commit 597cae6

3 files changed

Lines changed: 281 additions & 0 deletions

File tree

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ cmake_install.cmake
1111
Makefile
1212
build
1313
tools
14+
# Exception: include the root Makefile
15+
!Makefile
1416

1517
# Resulting binary files
1618
*.a
@@ -55,3 +57,12 @@ src/arm-none-eabi
5557
node_modules
5658
package.json
5759
package-lock.json
60+
61+
# Local simulation and container virtualization artifacts
62+
build_lv_sim/
63+
InfiniSim/
64+
.podman/
65+
.containers/
66+
67+
# Local duplicate helper script (tracked copy lives in tools/)
68+
run-infinisim-podman.sh

Makefile

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
.PHONY: check-runtime ensure-firmware-image build build-infinisim run-infinisim clean help
2+
3+
# Default target
4+
.DEFAULT_GOAL := build
5+
6+
# Build directories
7+
BUILD_DIR ?= build
8+
INFINISIM_DIR ?= build_lv_sim/InfiniSim
9+
INFINISIM_BUILD_DIR ?= $(INFINISIM_DIR)/build
10+
11+
# Container configuration
12+
CONTAINER_RUNTIME ?= $(shell if command -v podman >/dev/null 2>&1; then echo podman; elif command -v docker >/dev/null 2>&1; then echo docker; fi)
13+
CONTAINER_VOLUME_SUFFIX := $(shell if [ "$(CONTAINER_RUNTIME)" = "podman" ]; then echo ":Z"; fi)
14+
FIRMWARE_IMAGE_NAME ?= infinitime-build
15+
INFINISIM_IMAGE_NAME ?= infinisim-build
16+
REBUILD_IMAGE ?= 0
17+
18+
check-runtime:
19+
@if [ -z "$(CONTAINER_RUNTIME)" ]; then \
20+
echo "Error: neither podman nor docker is installed." >&2; \
21+
echo "Install one container runtime and try again." >&2; \
22+
echo "Examples:" >&2; \
23+
echo " Fedora: sudo dnf install podman" >&2; \
24+
echo " Debian/Ubuntu: sudo apt install podman" >&2; \
25+
echo " Docker alternative: https://docs.docker.com/engine/install/" >&2; \
26+
echo "Then verify with: podman --version or docker --version" >&2; \
27+
exit 1; \
28+
fi
29+
30+
ensure-firmware-image: check-runtime
31+
@if [ "$(REBUILD_IMAGE)" = "1" ] || ! $(CONTAINER_RUNTIME) image inspect "$(FIRMWARE_IMAGE_NAME)" >/dev/null 2>&1; then \
32+
echo "[1/2] Building firmware container image: $(FIRMWARE_IMAGE_NAME)"; \
33+
$(CONTAINER_RUNTIME) build -t "$(FIRMWARE_IMAGE_NAME)" -f docker/Dockerfile docker; \
34+
else \
35+
echo "[1/2] Firmware container image already exists: $(FIRMWARE_IMAGE_NAME)"; \
36+
fi
37+
38+
help:
39+
@echo "InfiniTime Build System"
40+
@echo "======================="
41+
@echo ""
42+
@echo "Targets:"
43+
@echo " make build Build the InfiniTime firmware in container (default)"
44+
@echo " make build-infinisim Build InfiniSim simulator in container"
45+
@echo " make run-infinisim Run the InfiniSim simulator"
46+
@echo " make clean Clean build directories"
47+
@echo ""
48+
@echo "Environment Variables:"
49+
@echo " CONTAINER_RUNTIME Container runtime (auto: podman, fallback: docker)"
50+
@echo " BUILD_DIR Firmware build directory (default: build)"
51+
@echo " INFINISIM_DIR InfiniSim source directory (default: build_lv_sim/InfiniSim)"
52+
@echo " INFINISIM_BUILD_DIR Simulator build directory (default: build_lv_sim/InfiniSim/build)"
53+
@echo " FIRMWARE_IMAGE_NAME Firmware image name (default: infinitime-build)"
54+
@echo " INFINISIM_IMAGE_NAME Simulator image name (default: infinisim-build)"
55+
@echo " REBUILD_IMAGE Rebuild container image when set to 1"
56+
@echo ""
57+
@echo "Examples:"
58+
@echo " make build # Build firmware in container"
59+
@echo " make build REBUILD_IMAGE=1"
60+
@echo " make build-infinisim # Build simulator in container"
61+
@echo " make run-infinisim # Run simulator"
62+
63+
# Build firmware in container
64+
build: ensure-firmware-image
65+
@if [ -f "$(BUILD_DIR)/CMakeCache.txt" ]; then \
66+
if ! grep -q '^CMAKE_HOME_DIRECTORY:INTERNAL=/sources$$' "$(BUILD_DIR)/CMakeCache.txt"; then \
67+
echo "[prep] Removing incompatible CMake cache in $(BUILD_DIR) for container build"; \
68+
rm -rf "$(BUILD_DIR)"; \
69+
fi; \
70+
fi
71+
@echo "[2/2] Building firmware..."
72+
@$(CONTAINER_RUNTIME) run --rm -it \
73+
-v "$(CURDIR):/sources$(CONTAINER_VOLUME_SUFFIX)" \
74+
-e "BUILD_DIR=/sources/$(BUILD_DIR)" \
75+
-e "OUTPUT_DIR=/sources/$(BUILD_DIR)/output" \
76+
"$(FIRMWARE_IMAGE_NAME)"
77+
78+
# Build InfiniSim simulator in container
79+
build-infinisim: check-runtime
80+
@echo "[1/3] Preparing InfiniSim build..."
81+
@if [ ! -x "tools/run-infinisim-podman.sh" ]; then \
82+
echo "Error: tools/run-infinisim-podman.sh is missing or not executable" >&2; \
83+
exit 1; \
84+
fi
85+
@INFINISIM_DIR="$(INFINISIM_DIR)" CONTAINER_RUNTIME="$(CONTAINER_RUNTIME)" IMAGE_NAME="$(INFINISIM_IMAGE_NAME)" REBUILD_IMAGE="$(REBUILD_IMAGE)" tools/run-infinisim-podman.sh --no-run
86+
87+
# Run the InfiniSim simulator
88+
run-infinisim: check-runtime
89+
@if [ ! -x "tools/run-infinisim-podman.sh" ]; then \
90+
echo "Error: tools/run-infinisim-podman.sh is missing or not executable" >&2; \
91+
exit 1; \
92+
fi
93+
@echo "[3/3] Starting simulator..."
94+
@INFINISIM_DIR="$(INFINISIM_DIR)" CONTAINER_RUNTIME="$(CONTAINER_RUNTIME)" IMAGE_NAME="$(INFINISIM_IMAGE_NAME)" REBUILD_IMAGE="$(REBUILD_IMAGE)" tools/run-infinisim-podman.sh
95+
96+
# Clean build directories
97+
clean:
98+
@echo "Cleaning build directories..."
99+
@rm -rf $(BUILD_DIR)
100+
@rm -rf $(INFINISIM_BUILD_DIR)
101+
@echo "Clean complete"
102+
103+
# Phony targets
104+
.PHONY: check-runtime ensure-firmware-image build build-infinisim run-infinisim clean help

tools/run-infinisim-podman.sh

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5+
if [[ -f "${SCRIPT_DIR}/../CMakeLists.txt" && -d "${SCRIPT_DIR}/../src" ]]; then
6+
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
7+
elif [[ -f "${SCRIPT_DIR}/CMakeLists.txt" && -d "${SCRIPT_DIR}/src" ]]; then
8+
ROOT_DIR="${SCRIPT_DIR}"
9+
else
10+
echo "Error: could not locate repository root." >&2
11+
exit 1
12+
fi
13+
SIM_DIR="${INFINISIM_DIR:-${ROOT_DIR}/build_lv_sim/InfiniSim}"
14+
if [[ "${SIM_DIR}" != /* ]]; then
15+
SIM_DIR="${ROOT_DIR}/${SIM_DIR}"
16+
fi
17+
IMAGE_NAME="${IMAGE_NAME:-infinisim-build}"
18+
CONTAINER_RUNTIME="${CONTAINER_RUNTIME:-}"
19+
BUILD_DIR="${BUILD_DIR:-build}"
20+
INFINISIM_REPO="${INFINISIM_REPO:-https://github.com/InfiniTimeOrg/InfiniSim.git}"
21+
INFINISIM_REF="${INFINISIM_REF:-main}"
22+
UPDATE_INFINISIM="${UPDATE_INFINISIM:-0}"
23+
REBUILD_IMAGE=0
24+
RUN_BINARY=1
25+
SIM_ARGS=()
26+
27+
usage() {
28+
cat <<'EOF'
29+
Usage: tools/run-infinisim-podman.sh [options] [-- <infinisim-args>]
30+
31+
Options:
32+
--rebuild-image Rebuild Podman image without cache
33+
--no-run Only build, do not execute ./build/infinisim
34+
-h, --help Show this help
35+
36+
Environment variables:
37+
IMAGE_NAME Podman image name (default: infinisim-build)
38+
CONTAINER_RUNTIME Runtime to use (podman or docker, auto-detected if empty)
39+
INFINISIM_DIR InfiniSim source directory (default: build_lv_sim/InfiniSim)
40+
INFINISIM_REPO InfiniSim git repository URL
41+
INFINISIM_REF InfiniSim git reference to clone (default: main)
42+
UPDATE_INFINISIM Set to 1 to update existing clone to INFINISIM_REF
43+
BUILD_DIR Build directory inside InfiniSim (default: build)
44+
45+
Examples:
46+
tools/run-infinisim-podman.sh
47+
tools/run-infinisim-podman.sh --rebuild-image
48+
tools/run-infinisim-podman.sh -- --hide-status
49+
EOF
50+
}
51+
52+
while [[ $# -gt 0 ]]; do
53+
case "$1" in
54+
--rebuild-image)
55+
REBUILD_IMAGE=1
56+
shift
57+
;;
58+
--no-run)
59+
RUN_BINARY=0
60+
shift
61+
;;
62+
-h|--help)
63+
usage
64+
exit 0
65+
;;
66+
--)
67+
shift
68+
SIM_ARGS=("$@")
69+
break
70+
;;
71+
*)
72+
echo "Unknown option: $1" >&2
73+
usage
74+
exit 1
75+
;;
76+
esac
77+
done
78+
79+
if [[ -z "${CONTAINER_RUNTIME}" ]]; then
80+
if command -v podman >/dev/null 2>&1; then
81+
CONTAINER_RUNTIME="podman"
82+
elif command -v docker >/dev/null 2>&1; then
83+
CONTAINER_RUNTIME="docker"
84+
else
85+
echo "Error: neither podman nor docker is installed or available in PATH." >&2
86+
exit 1
87+
fi
88+
fi
89+
90+
if [[ ! -d "${SIM_DIR}" ]]; then
91+
echo "[prep] InfiniSim source not found at ${SIM_DIR}; cloning ${INFINISIM_REF}"
92+
mkdir -p "$(dirname "${SIM_DIR}")"
93+
git clone --depth 1 --branch "${INFINISIM_REF}" "${INFINISIM_REPO}" "${SIM_DIR}"
94+
fi
95+
96+
if [[ ! -d "${SIM_DIR}/.git" ]]; then
97+
echo "Error: ${SIM_DIR} exists but is not a git checkout." >&2
98+
exit 1
99+
fi
100+
101+
if [[ "${UPDATE_INFINISIM}" == "1" ]]; then
102+
echo "[prep] Updating InfiniSim checkout to ${INFINISIM_REF}"
103+
git -C "${SIM_DIR}" fetch --depth 1 origin "${INFINISIM_REF}"
104+
git -C "${SIM_DIR}" reset --hard FETCH_HEAD
105+
fi
106+
107+
VOLUME_SUFFIX=""
108+
if [[ "${CONTAINER_RUNTIME}" == "podman" ]]; then
109+
VOLUME_SUFFIX=":Z"
110+
fi
111+
112+
cd "${SIM_DIR}"
113+
114+
PATCHED_CMAKELISTS=0
115+
cleanup() {
116+
if [[ ${PATCHED_CMAKELISTS} -eq 1 && -f "${SIM_DIR}/CMakeLists.txt.copilot-backup" ]]; then
117+
mv "${SIM_DIR}/CMakeLists.txt.copilot-backup" "${SIM_DIR}/CMakeLists.txt"
118+
fi
119+
}
120+
trap cleanup EXIT
121+
122+
if [[ -f "${SIM_DIR}/CMakeLists.txt" ]] && [[ ! -f "${ROOT_DIR}/src/displayapp/localization/Localization.h" ]] && grep -q "displayapp/localization/Localization.h" "${SIM_DIR}/CMakeLists.txt"; then
123+
echo "[prep] Detected incompatible localization entries in InfiniSim/CMakeLists.txt; patching for current branch"
124+
cp "${SIM_DIR}/CMakeLists.txt" "${SIM_DIR}/CMakeLists.txt.copilot-backup"
125+
sed -i \
126+
-e '/displayapp\/localization\/Localization\.h/d' \
127+
-e '/displayapp\/localization\/Localization\.cpp/d' \
128+
"${SIM_DIR}/CMakeLists.txt"
129+
PATCHED_CMAKELISTS=1
130+
fi
131+
132+
echo "[1/4] Initializing submodules"
133+
git submodule update --init --recursive
134+
135+
if [[ ${REBUILD_IMAGE} -eq 1 ]]; then
136+
echo "[2/4] Rebuilding container image (no cache): ${IMAGE_NAME}"
137+
"${CONTAINER_RUNTIME}" build --no-cache -t "${IMAGE_NAME}" -f .devcontainer/Dockerfile .
138+
else
139+
if ! "${CONTAINER_RUNTIME}" image inspect "${IMAGE_NAME}" >/dev/null 2>&1; then
140+
echo "[2/4] Building container image: ${IMAGE_NAME}"
141+
"${CONTAINER_RUNTIME}" build -t "${IMAGE_NAME}" -f .devcontainer/Dockerfile .
142+
else
143+
echo "[2/4] Container image already exists: ${IMAGE_NAME}"
144+
fi
145+
fi
146+
147+
echo "[3/4] Building InfiniSim in container"
148+
"${CONTAINER_RUNTIME}" run --rm -it \
149+
-v "${SIM_DIR}:/sources${VOLUME_SUFFIX}" \
150+
-v "${ROOT_DIR}:/sources/InfiniTime${VOLUME_SUFFIX}" \
151+
-e "BUILD_DIRECTORY=${BUILD_DIR}" \
152+
-w /sources \
153+
"${IMAGE_NAME}"
154+
155+
if [[ ${RUN_BINARY} -eq 1 ]]; then
156+
BIN_PATH="${SIM_DIR}/${BUILD_DIR}/infinisim"
157+
if [[ ! -x "${BIN_PATH}" ]]; then
158+
echo "Error: binary not found at ${BIN_PATH}" >&2
159+
exit 1
160+
fi
161+
162+
echo "[4/4] Running simulator: ${BIN_PATH} ${SIM_ARGS[*]:-}"
163+
"${BIN_PATH}" "${SIM_ARGS[@]}"
164+
else
165+
echo "[4/4] Build finished (execution skipped by --no-run)"
166+
fi

0 commit comments

Comments
 (0)