# Atmel Studio `master` carries `bootloader.atsln`, so this branch does too: `ide/bootloader.atsln` builds the loader from the same source Ninja does, to a **byte-identical `.text`** — the `tsb_asm` tier in its 512-byte section (`check-flags.py` below is what holds the flag sets equal, so the size is Ninja's own). CMake remains the build system; the solution is here so the port opens in Studio as its predecessor did. ## One project, of four tiers A `.cppproj` is one binary at one set of flags. `tsb_asm` is the tier that occupies the same 512-byte section `master`'s `tsb` project targeted, which is the one worth opening in Studio. The other three tiers (`tsb_pure`, `tsb_tricks`, `tsb_policy`) are not here. They differ from `tsb_asm` in their source file, their section size, and — for `tsb_policy` — two loop flags; nothing about that is a Studio concern, and what they exist to demonstrate is a size gradient only the CMake size tests measure. Adding one is a copy of `tsb_asm/tsb_asm.cppproj` in its own directory, with its name, its GUID, its source path and its `--section-start` changed (`0x7c00` for the 1 KiB tiers), plus four lines in the solution. `avrdevice` is a project property, so each project gets its own directory: Studio builds into `/` whatever `OutputDirectory` says, and two projects sharing a directory would share one object file. ## Debug keeps `-Os` Both configurations compile at `-Os`; Debug adds only `-gdwarf-4`. The `.text` is therefore identical in both, which is the point — a loader's section is a **correctness** bound and not a budget. A debug configuration that silently overruns the section is worse than none, and DWARF costs no flash, so the optimisation level stays where correctness needs it. ## What Studio needs from the machine libavr from the **submodule**, found at `$(MSBuildProjectDirectory)\..\..\libavr\include` — correct by construction, and anchored to the project because a plain relative path resolves against the generated makefile's directory (the configuration's output directory), not the project's. There is no `LIBAVR_ROOT` escape hatch: a variable exported in a shell is invisible to Studio launched from the Start menu, and the failure reads as a missing `libavr/libavr.hpp` — which is what the submodule answers. A GCC 16.1 toolchain registered as flavour `avr-g++-16.1.0`, nothing older reaching `-std=c++26`. ## Generating and gating One generated file is required before the project will load at all, and one command checks the flags have not drifted (both from libavr's `tools/atmelstudio/`): ```sh python libavr/tools/atmelstudio/componentinfo.py \ ide/tsb_asm/tsb_asm.componentinfo.xml --device ATmega328P python libavr/tools/atmelstudio/check-flags.py \ --solution ide/bootloader.atsln --project tsb_asm --target tsb_asm \ --compile-commands build/atmega328p-generated/compile_commands.json \ --log build/as-tsb_asm.log ``` Release is what the gate compares — the presets define no debug build, and Debug differs from Release only in `-gdwarf-4`. Legacy (the yazoalfa-era submodules) stays on `master`.