
Gcc
Scan, configure, build, and size-analyze CMake-based ARM embedded firmware projects with arm-none-eabi-gcc from your coding agent.
Overview
gcc is an agent skill for the Build phase that scans, configures, builds, and memory-analyzes CMake ARM embedded projects using arm-none-eabi-gcc.
Install
npx skills add https://github.com/zhinkgit/embeddedskills --skill gccWhat is this skill?
- Scans workspace for CMake embedded projects (not raw Makefile-only trees)
- Enumerates CMakePresets.json configure and build presets
- Runs configure, build, rebuild, and clean via CMake
- Reports ELF text, data, bss, and memory footprint with arm-none-eabi-size
- Returns elf_file, flash_file, debug_file, and log_file paths for jlink or openocd follow-up
- CMake 3.21+ required
- 3 operation_mode safety levels (direct, risk summary, confirm)
- CMake-only scope (no pure Makefile projects)
Adoption & trust: 1 installs on skills.sh; 340 GitHub stars; 3/3 security scanners passed (skills.sh audits); trending (+100% hot-view momentum).
What problem does it solve?
You have a Cortex-M CMake repo but no reliable agent workflow to pick presets, build firmware, and read ELF size before flash.
Who is it for?
Indie firmware developers using CMakePresets with arm-none-eabi-gcc who want repeatable agent-driven builds and size checks.
Skip if: Pure Makefile firmware trees, non-ARM hosts-only apps, or teams that never use CMake for embedded.
When should I use this skill?
User asks to build, configure, rebuild, clean, or size-analyze an embedded CMake ARM GCC project or to list CMake presets.
What do I get? / Deliverables
You get configured builds, size reports, and artifact paths ready for jlink or openocd flashing and debug.
- Built ELF and related flash/debug artifact paths
- Build logs under configured log_dir
- ELF memory section size summary
Recommended Skills
Journey fit
Firmware compilation and ELF memory analysis happen during active product build, not launch or growth. Toolchain and CMake preset workflows integrate the cross-compiler with the repo and hand off binaries to flash/debug tools.
How it compares
Use instead of ad-hoc shell cmake chains when you want preset-aware scan, build, and ELF sizing in one skill.
Common Questions / FAQ
Who is gcc for?
Solo and small-team embedded builders using Claude Code, Cursor, or Codex on CMake + ARM GCC firmware repos.
When should I use gcc?
During Build when you need to enumerate presets, run configure/build/clean, or analyze ELF memory before handing binaries to a debugger skill.
Is gcc safe to install?
It runs local cmake and compiler commands on your machine; review the Security Audits panel on this page and use operation_mode 2 or 3 if you want summaries or confirmation before execution.
SKILL.md
READMESKILL.md - Gcc
{ "cmake_exe": "cmake", "toolchain_prefix": "arm-none-eabi-", "toolchain_path": "", "operation_mode": 1 } # gcc Claude Code skill,用于基于 CMake + arm-none-eabi-gcc 的嵌入式工程扫描、preset 枚举、配置、构建和 ELF 大小分析。 范围说明:当前仅支持 **CMake 型** 嵌入式 GCC 工程,不覆盖纯 `Makefile` 工程。 ## 功能 - 扫描目录下的嵌入式 CMake 工程 - 枚举 `CMakePresets.json` 中的 configure/build preset - 执行 `configure` / `build` / `rebuild` / `clean` - 分析 ELF 的 `text` / `data` / `bss` 和内存占用 - 返回 `elf_file` / `flash_file` / `debug_file` / `log_file` 等产物路径,便于继续交给 `jlink/openocd` ## 环境要求 - [CMake](https://cmake.org/) 3.21 或更高版本 - Ninja(推荐)或 Make - [Arm GNU Toolchain](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads)(提供 `arm-none-eabi-gcc`、`arm-none-eabi-size` 等) - Python 3.x(仅标准库,无额外依赖) ## 配置 ### 环境级配置(skill/config.json) 复制 `config.example.json` 为 `config.json`,根据实际环境修改: ```json { "cmake_exe": "cmake", "toolchain_prefix": "arm-none-eabi-", "toolchain_path": "", "operation_mode": 1 } ``` | 字段 | 必填 | 说明 | |------|------|------| | `cmake_exe` | 否 | `cmake` 路径或命令名,默认从 PATH 查找 | | `toolchain_prefix` | 否 | 工具链前缀,默认 `arm-none-eabi-` | | `toolchain_path` | 否 | 工具链 bin 目录,为空时从 PATH 查找 | | `operation_mode` | 否 | `1` 直接执行 / `2` 输出风险摘要 / `3` 执行前确认 | ### 工程级配置(workspace/.embeddedskills/config.json) 工程级共享配置保存在工作区的 `.embeddedskills/config.json` 中: ```json { "gcc": { "project": "", "preset": "", "log_dir": ".embeddedskills/build" } } ``` | 字段 | 说明 | |------|------| | `project` | 默认工程路径(相对 workspace) | | `preset` | 默认 CMake preset 名称 | | `log_dir` | 构建日志输出目录,默认 `.embeddedskills/build` | ### 参数解析优先级 参数解析顺序(从高到低): 1. CLI 显式参数 2. 环境级配置(skill/config.json) 3. 工程级配置(.embeddedskills/config.json) 4. state.json(上次构建记录) 5. 搜索/询问 ## 子命令 | 子命令 | 用途 | |--------|------| | `scan` | 搜索嵌入式 CMake 工程 | | `presets` | 列出 CMake preset | | `configure` | 生成构建系统 | | `build` | 增量编译 | | `rebuild` | 全量重建 | | `clean` | 清理构建目录 | | `size` | 分析 ELF 大小 | ## 使用说明 - `build` 前若尚未完成 `configure`,脚本会提示先执行 `configure` - 发现多个工程或多个 preset 时,只返回候选项,不自动猜测 - `build/rebuild` 成功后会返回 `elf_file`,同时复用为 `flash_file` 和 `debug_file` - `size` 默认分析最近一次构建产物;底层 `gcc_size.py` 额外支持两个 ELF 的对比分析 - `clean` 不会在自动流程中隐式执行 """GCC 嵌入式工程构建:configure / build / rebuild / clean。""" from __future__ import annotations import argparse import json import re import shutil import subprocess import sys import time from pathlib import Path ROOT_DIR = Path(__file__).resolve().parents[2] if str(ROOT_DIR) not in sys.path: sys.path.insert(0, str(ROOT_DIR)) from gcc_runtime import ( # noqa: E402 build_artifacts, default_config_path, get_state_entry, hidden_subprocess_kwargs, is_missing, load_json_file, load_local_config, load_project_config, load_workspace_state, make_result, make_timing, normalize_path, now_iso, output_json, parameter_context, resolve_param, save_project_config, update_state_entry, workspace_root, ) def _resolve_build_dir(project: Path, preset: str, presets_file: Path) -> Path: if presets_file.exists(): data = json.loads(presets_file.read_text(encoding="utf-8")) all_presets = {item["name"]: item for item in data.get("configurePresets", [])} preset_item = all_presets.get(preset, {}) binary_dir = preset_item.get("binaryDir", "") if not binary_dir: inherits = preset_item.get("inherits") if inherits and isinstance(inherits, str): binary_dir = all_presets.get(inherits, {}).get("binaryDir", "") if binary_dir: binary_dir = binary_dir.replace("${sourceDir}", str(project)) binary_dir = binary_dir.replace("${presetName}", preset) return Path(binary_dir) return project / "build" / preset def _resolve_workspace_path(workspace: Path, raw_path: str | None, default: str) -> str: value = default if is_missing(raw_path) else str(raw_path) path = Path(