-
Notifications
You must be signed in to change notification settings - Fork 0
Developer Guide
-
LLVM/Clang 17+ — C compiler (
clang-cl.exe, the MSVC-compatible Clang driver) -
Visual Studio 2019+ (or Build Tools for Visual Studio) — provides Windows SDK,
rc.exe, andlink.exe - CMake 3.16+
- Ninja build system
- Git
- Qt Creator (optional, as IDE)
Open a Developer Command Prompt for VS, then:
git clone https://github.com/KaiUR/CatiaMenuWin32 cd CatiaMenuWin32 cmake -S . -B build -G "Ninja" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang-cl cmake --build build
The executable is output to build/CatiaMenuWin32.exe.
- Open
CMakeLists.txtin Qt Creator - Select a Clang kit configured with the MSVC toolchain
- Add
-DCMAKE_C_COMPILER=clang-clto the CMake arguments - Build → Build All
Tip: Launch Qt Creator from a Developer Command Prompt for VS so that
rc.exeand the Windows SDK are on the PATH.
The workflow (.github/workflows/release.yml) runs on windows-latest using:
-
ilammy/msvc-dev-cmd— sets up the MSVC environment (Windows SDK,rc.exe,link.exe) -
LLVM/Clang (pre-installed on
windows-latest) as the C compiler - Ninja as the build backend
On a tagged release (v*) the workflow additionally:
- Builds with
-DCMAKE_C_COMPILER=clang-cl -DVERSION_OVERRIDE=<version> -
Authenticode-signs
CatiaMenuWin32.exevia PowerShell +signtool.exe(x64) - Commits the incremented
build_number.txtback tomainas a verified bot commit - Imports the GPG key, deletes the base tag, creates a GPG-signed tag with the full build number (e.g.
v1.2.0.31), and publishes the GitHub Release
The following secrets must be set in Settings → Secrets → Actions:
| Secret | Description |
|---|---|
CERTIFICATE |
Base64-encoded PFX file |
PASSWORD |
PFX password |
CERTHASH |
SHA1 thumbprint of the certificate |
CERTNAME |
Common name of the certificate |
The following secrets are used by crazy-max/ghaction-import-gpg@v6 to sign release tags:
| Secret | Description |
|---|---|
GPG_PRIVATE_KEY |
ASCII-armored GPG private key. Export with: gpg --armor --export-secret-keys KEY_ID
|
GPG_PASSPHRASE |
Passphrase protecting the GPG private key |
The imported key is configured as the git signing key; every release tag is created with git tag -s, producing a verified tag on GitHub. The committer identity baked into the key must match KaiUR / kairathjen@yahoo.com as set in the workflow.
src/ C source and header files
res/ Resource files (icons, manifest, resource.rc.in, version.h.in)
docs/ GitHub Pages documentation
.github/ GitHub Actions workflows and issue templates
| File | Purpose |
|---|---|
main.c / main.h
|
Entry point, WndProc, AppState struct |
window.c |
Window creation, menu, toolbar, layout |
tabs.c |
Custom tab bar, script buttons, filter |
paint.c |
GDI painting, script button rendering, tooltips |
sync.c |
GitHub sync thread, manifest, offline cache |
github.c |
HTTPS requests, JSON parsing, SHA verification |
runner.c |
Script execution, Python detection |
meta.c |
Script header metadata parsing |
settings.c |
Settings load/save, Settings dialog |
sources.c |
Script Sources dialog |
prefs.c |
Favourites, hidden scripts, notes, run counts |
help.c |
In-app help window |
updater.c |
Update checker and auto-update |
quickbar.c |
Floating Quick Launch Bar |
- Version is determined from the latest Git tag at CMake configure time
-
build_number.txtincrements by 1 on every CMake configure (local and CI) - Local builds show a
(local)suffix and skip the update check - CI workflow: tag push → build → sign → release → commit
build_number.txtback to main
- Develop on
developbranch - Open a pull request to
main - Merge the PR
- Tag from
main:git tag v1.x.x && git push origin v1.x.x - GitHub Actions builds, signs, and creates the release automatically
-
C11, Win32 API only — no external libraries
-
Unicode throughout —
WCHAR,L""literals,_snwprintf_s -
Memory-safe functions only — always use
_s(C11 Annex K) or bounded variants; never use functions flagged byclang-analyzer-security.insecureAPI:Never use Use instead Notes strcpy,wcscpystrcpy_s,wcscpy_salways pass _countof(dest)strcat,wcscatstrcat_s,wcscat_salways pass _countof(dest)strncpy,wcsncpystrncpy_s,wcsncpy_s_svariant guarantees NUL terminationsprintf,swprintfsprintf_s,swprintf_spass _countof(buf)snprintf,_snwprintf_snprintf_s,_snwprintf_suse _TRUNCATEas the count argumentfprintffprintf_svsprintf,vswprintfvsprintf_s,vswprintf_sgetsfgetsmemcpymemcpy_spass destSizethencountmemmovememmove_spass destSizethencountmemset(zeroing secrets)SecureZeroMemoryprevents compiler from eliding the zero -
All GDI painting double-buffered
-
All state in global
AppState gstruct -
Heap memory for scripts — use
Folder_Alloc/Folder_Free/Folder_Pushhelpers; alwaysfreeon every exit path -
Use
COL_BG(),COL_TEXT()etc. — never hardcode RGB values -
Cross-thread communication via
PostMessageonly
Getting Started
Using the App
Scripts
Reference
Development
Legal