diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..1c0fdfd
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "libavr"]
+ path = libavr
+ url = ../libavr.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4fe2d3a..3a9bbaa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,18 +2,19 @@ cmake_minimum_required(VERSION 3.28)
project(fantemp LANGUAGES CXX)
-# libavr from a local checkout (LIBAVR_ROOT) or the forge; the toolchain
-# file comes from the same checkout via CMakePresets.json.
-include(FetchContent)
+# libavr rides as the pinned submodule; LIBAVR_ROOT (cache or environment)
+# overrides it for tandem development against a working tree. The toolchain
+# file comes from the submodule via CMakePresets.json either way.
if(NOT LIBAVR_ROOT AND DEFINED ENV{LIBAVR_ROOT})
set(LIBAVR_ROOT $ENV{LIBAVR_ROOT})
endif()
-if(LIBAVR_ROOT)
- FetchContent_Declare(libavr SOURCE_DIR ${LIBAVR_ROOT})
-else()
- FetchContent_Declare(libavr GIT_REPOSITORY git@git.blackmark.me:avr/libavr.git GIT_TAG main)
+if(NOT LIBAVR_ROOT)
+ set(LIBAVR_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/libavr)
endif()
-FetchContent_MakeAvailable(libavr)
+if(NOT EXISTS ${LIBAVR_ROOT}/CMakeLists.txt)
+ message(FATAL_ERROR "libavr not found at ${LIBAVR_ROOT} — run: git submodule update --init libavr")
+endif()
+add_subdirectory(${LIBAVR_ROOT} libavr-build)
add_executable(fantemp src/main.cpp)
target_link_libraries(fantemp PRIVATE libavr)
diff --git a/CMakePresets.json b/CMakePresets.json
index cd08300..67dce93 100644
--- a/CMakePresets.json
+++ b/CMakePresets.json
@@ -6,7 +6,7 @@
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
- "toolchainFile": "$env{LIBAVR_ROOT}/cmake/avr-toolchain.cmake",
+ "toolchainFile": "${sourceDir}/libavr/cmake/avr-toolchain.cmake",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
diff --git a/README.md b/README.md
index 5b6cc76..9d8ab2b 100644
--- a/README.md
+++ b/README.md
@@ -12,10 +12,13 @@ log) is gone: the Beta equation and the cubic fan curve are evaluated
consteval into flash tables — the firmware itself never touches floating
point.
-Build against a libavr checkout:
+libavr rides as the `libavr/` submodule, pinned to the commit this firmware
+builds against; `LIBAVR_ROOT` (cache or environment) overrides it for
+development against a working tree:
```sh
-LIBAVR_ROOT=/path/to/libavr cmake --preset atmega328p-generated
+git submodule update --init libavr
+cmake --preset atmega328p-generated
cmake --build --preset atmega328p-generated
```
@@ -25,15 +28,13 @@ cmake --build --preset atmega328p-generated
builds the same firmware — byte-identical `.text` and `.data` to the CMake
build — from the same sources, with the flags mirrored by hand.
-Studio expects libavr checked out **beside this repo**, and finds it at
-`$(MSBuildProjectDirectory)\..\..\libavr\include` — anchored to the project
-rather than written relative to the generated makefile, which runs from the
-configuration's output directory and would need a different number of `..`.
-Unlike the CMake build there is no `LIBAVR_ROOT` to point elsewhere: an
-environment variable set in a shell is not visible to Studio launched from the
-Start menu, which fails as a missing `libavr/libavr.hpp` rather than as anything
-about the variable. Pinning libavr as a submodule is the better answer and is on
-libavr's task list.
+Studio finds libavr in the **submodule**, at
+`$(MSBuildProjectDirectory)\..\libavr\include` — correct by construction, and
+anchored to the project rather than written relative to the generated makefile,
+which runs from the configuration's output directory and would need a different
+number of `..`. Unlike the CMake build there is no `LIBAVR_ROOT` to point
+elsewhere: an environment variable set in a shell is not visible to Studio
+launched from the Start menu — which is what the submodule answers.
It also needs a GCC 16.1 toolchain registered as flavour `avr-g++-16.1.0`;
nothing older can compile `-std=c++26`.
diff --git a/ide/fantemp.cppproj b/ide/fantemp.cppproj
index 2119627..64dd873 100644
--- a/ide/fantemp.cppproj
+++ b/ide/fantemp.cppproj
@@ -57,7 +57,7 @@
- $(MSBuildProjectDirectory)\..\..\libavr\include
+ $(MSBuildProjectDirectory)\..\libavr\include
Optimize for size (-Os)
@@ -86,7 +86,7 @@
- $(MSBuildProjectDirectory)\..\..\libavr\include
+ $(MSBuildProjectDirectory)\..\libavr\include
Optimize debugging experience (-Og)
diff --git a/libavr b/libavr
new file mode 160000
index 0000000..43b1f34
--- /dev/null
+++ b/libavr
@@ -0,0 +1 @@
+Subproject commit 43b1f34ed102f11da82491370ea688b1c912e09e