@@ -1,5 +1,6 @@
|
|||||||
build/
|
build/
|
||||||
.clangd
|
.clangd
|
||||||
|
.nvim.lua
|
||||||
.clang-format
|
.clang-format
|
||||||
pyrightconfig.json
|
pyrightconfig.json
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,10 @@ When running directly outside the generated Modulus Docker image, set `PICO_SDK_
|
|||||||
|
|
||||||
Editor settings live in `modulus.json` under `tooling.editor`. Modulus generates the ignored `.clangd`, `.clang-format`, and `pyrightconfig.json` files; edit the JSON settings rather than these outputs. The clangd configuration routes Zero/shared code to the native compile database and Pico code to its firmware database.
|
Editor settings live in `modulus.json` under `tooling.editor`. Modulus generates the ignored `.clangd`, `.clang-format`, and `pyrightconfig.json` files; edit the JSON settings rather than these outputs. The clangd configuration routes Zero/shared code to the native compile database and Pico code to its firmware database.
|
||||||
|
|
||||||
|
Modulus also generates `.nvim.lua` for Neovim 0.11+ with `exrc` enabled. Review and trust it when Neovim asks; it preserves the existing LSP capabilities/keybindings and runs clangd 19 in the build container for this repo. Run `python3 modulus.py lsp` once to prepare both databases and the shared read-only header cache. Other editors can use `python3 modulus.py clangd` as their language-server command. Startup never downloads or builds anything, and never falls back to host clangd.
|
||||||
|
|
||||||
|
`tooling.lsp.clangd` configures the server executable, arguments, trusted compiler paths, and additional header roots. Product Vamp adds the bare-metal ARM compiler and `/opt/pico-sdk`; standard-library and SDK definitions open from an image-keyed cache under `$XDG_CACHE_HOME/modulus/clangd` (default `~/.cache/modulus/clangd`). Set `tooling.editor.nvim.enabled` to `false` for a hand-managed editor setup. Existing unowned `.nvim.lua` files are preserved.
|
||||||
|
|
||||||
## Package
|
## Package
|
||||||
|
|
||||||
Product packaging targets Raspberry Pi OS/Debian trixie on ARM64 and optionally builds Pico firmware. Set `PICO_SDK_PATH` when building the firmware artifact:
|
Product packaging targets Raspberry Pi OS/Debian trixie on ARM64 and optionally builds Pico firmware. Set `PICO_SDK_PATH` when building the firmware artifact:
|
||||||
|
|||||||
@@ -52,6 +52,14 @@
|
|||||||
},
|
},
|
||||||
"lsp": {
|
"lsp": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
"clangd": {
|
||||||
|
"query_drivers": [
|
||||||
|
"/usr/bin/gcc-12", "/usr/bin/g++-12",
|
||||||
|
"/usr/bin/aarch64-linux-gnu-gcc-12", "/usr/bin/aarch64-linux-gnu-g++-12",
|
||||||
|
"/usr/bin/arm-none-eabi-gcc", "/usr/bin/arm-none-eabi-g++"
|
||||||
|
],
|
||||||
|
"header_roots": ["/opt/pico-sdk"]
|
||||||
|
},
|
||||||
"compile_databases": [
|
"compile_databases": [
|
||||||
{
|
{
|
||||||
"name": "pico",
|
"name": "pico",
|
||||||
|
|||||||
+8
-15
@@ -19,6 +19,7 @@ COMMANDS = (
|
|||||||
"test",
|
"test",
|
||||||
"package",
|
"package",
|
||||||
"lsp",
|
"lsp",
|
||||||
|
"clangd",
|
||||||
"run",
|
"run",
|
||||||
)
|
)
|
||||||
COMMON_DIR = pathlib.Path("build") / "build_common"
|
COMMON_DIR = pathlib.Path("build") / "build_common"
|
||||||
@@ -60,6 +61,7 @@ def runtime_ready(root):
|
|||||||
return (
|
return (
|
||||||
(root / TOOLS_DIR / "configure.py").is_file()
|
(root / TOOLS_DIR / "configure.py").is_file()
|
||||||
and (root / TOOLS_DIR / "lsp.py").is_file()
|
and (root / TOOLS_DIR / "lsp.py").is_file()
|
||||||
|
and (root / TOOLS_DIR / "clangd.py").is_file()
|
||||||
and (root / TOOLS_DIR / "run.py").is_file()
|
and (root / TOOLS_DIR / "run.py").is_file()
|
||||||
and (root / RUNTIME_DIR / "modulus" / "cli.py").is_file()
|
and (root / RUNTIME_DIR / "modulus" / "cli.py").is_file()
|
||||||
and (root / RUNTIME_DIR / "modulus" / "export.py").is_file()
|
and (root / RUNTIME_DIR / "modulus" / "export.py").is_file()
|
||||||
@@ -485,22 +487,14 @@ def run_package(argv):
|
|||||||
|
|
||||||
def delegate(command, argv):
|
def delegate(command, argv):
|
||||||
root = repo_root()
|
root = repo_root()
|
||||||
ensure_runtime(root)
|
if command == "clangd":
|
||||||
|
if not runtime_ready(root):
|
||||||
|
print("Modulus clangd tooling is missing; run ./modulus.py configure first", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
ensure_runtime(root)
|
||||||
sys.path.insert(0, str(root / RUNTIME_DIR))
|
sys.path.insert(0, str(root / RUNTIME_DIR))
|
||||||
import modulus.cli
|
import modulus.cli
|
||||||
original_image_available = modulus.cli.docker_image_available
|
|
||||||
|
|
||||||
def current_build_image(context):
|
|
||||||
if not original_image_available(context):
|
|
||||||
return False
|
|
||||||
inspected = subprocess.run(
|
|
||||||
["docker", "image", "inspect", context.docker_image, "--format",
|
|
||||||
'{{index .Config.Labels "org.khodo.product-vamp.build-requirements"}}'],
|
|
||||||
capture_output=True, text=True, check=False,
|
|
||||||
)
|
|
||||||
return inspected.returncode == 0 and inspected.stdout.strip() == build_requirements_digest()
|
|
||||||
|
|
||||||
modulus.cli.docker_image_available = current_build_image
|
|
||||||
original_docker_run = modulus.cli.docker_run
|
original_docker_run = modulus.cli.docker_run
|
||||||
|
|
||||||
def docker_run_with_host_socket(context, command, docker_args=None, env_overrides=None):
|
def docker_run_with_host_socket(context, command, docker_args=None, env_overrides=None):
|
||||||
@@ -521,7 +515,6 @@ def delegate(command, argv):
|
|||||||
try:
|
try:
|
||||||
return modulus.cli.main(command)
|
return modulus.cli.main(command)
|
||||||
finally:
|
finally:
|
||||||
modulus.cli.docker_image_available = original_image_available
|
|
||||||
modulus.cli.docker_run = original_docker_run
|
modulus.cli.docker_run = original_docker_run
|
||||||
os.chdir(previous_cwd)
|
os.chdir(previous_cwd)
|
||||||
sys.argv = previous_argv
|
sys.argv = previous_argv
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iterator>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import hashlib
|
import hashlib
|
||||||
import importlib.util
|
import importlib.util
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
import unittest
|
import unittest
|
||||||
@@ -21,14 +20,15 @@ class BuildBootstrapTests(unittest.TestCase):
|
|||||||
package = types.ModuleType('modulus')
|
package = types.ModuleType('modulus')
|
||||||
cli = types.ModuleType('modulus.cli')
|
cli = types.ModuleType('modulus.cli')
|
||||||
package.cli = cli
|
package.cli = cli
|
||||||
available, docker_run = Mock(return_value=True), Mock()
|
docker_run = Mock()
|
||||||
cli.docker_image_available, cli.docker_run = available, docker_run
|
cli.docker_run = docker_run
|
||||||
cli.main = lambda command: cli.docker_image_available(types.SimpleNamespace(docker_image='test-image'))
|
cli.main = Mock(return_value=0)
|
||||||
for label, expected in [('',False), ('outdated',False), (digest,True)]:
|
with patch.dict(sys.modules, {'modulus':package, 'modulus.cli':cli}), \
|
||||||
result = subprocess.CompletedProcess([], 0, label+'\n', '')
|
patch.object(bootstrap, 'ensure_runtime') as prepare, \
|
||||||
with self.subTest(label=label), patch.dict(sys.modules, {'modulus':package, 'modulus.cli':cli}), \
|
patch.object(bootstrap, 'runtime_ready', return_value=True), \
|
||||||
patch.object(bootstrap, 'ensure_runtime'), patch.object(bootstrap.subprocess, 'run', return_value=result), \
|
patch.object(sys, 'path', list(sys.path)):
|
||||||
patch.object(sys, 'path', list(sys.path)):
|
self.assertEqual(bootstrap.delegate('clangd', []), 0)
|
||||||
self.assertEqual(bootstrap.delegate('configure', []), expected)
|
prepare.assert_not_called()
|
||||||
self.assertIs(cli.docker_image_available, available)
|
docker_run.assert_not_called()
|
||||||
self.assertIs(cli.docker_run, docker_run)
|
cli.main.assert_called_once_with('clangd')
|
||||||
|
self.assertIs(cli.docker_run, docker_run)
|
||||||
|
|||||||
Reference in New Issue
Block a user