Skip to content

chore: cmake enhancement #2401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
694 changes: 688 additions & 6 deletions cmake/boards_db.cmake

Large diffs are not rendered by default.

10 changes: 4 additions & 6 deletions cmake/scripts/ccwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@

import io
import re
import pathlib
from pathlib import Path
import subprocess
import argparse

parser = argparse.ArgumentParser()
parser.add_argument(
"--source", "-i", type=pathlib.Path, required=True, help="input file being compiled"
)
parser.add_argument(
"--logdir", "-d", type=pathlib.Path, required=True, help="log directory"
"--source", "-i", type=Path, required=True, help="input file being compiled"
)
parser.add_argument("--logdir", "-d", type=Path, required=True, help="log directory")
parser.add_argument(
"cmd",
action="extend",
Expand All @@ -29,7 +27,7 @@
if proc.returncode != 0:
exit(proc.returncode)

with open(shargs.logdir / (shargs.source.name + ".log"), "w") as file:
with open(shargs.logdir / f"{shargs.source.name}.log", "w") as file:
print(" " + str(shargs.source), file=file)
for line in io.StringIO(proc.stderr):
if logline.match(line):
Expand Down
55 changes: 28 additions & 27 deletions cmake/scripts/cmake_easy_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import shutil
import tempfile
import os
import pathlib
from pathlib import Path
import json
from jinja2 import Environment, FileSystemLoader
import difflib
Expand All @@ -16,7 +16,7 @@
parser.add_argument(
"--cli",
"-x",
type=pathlib.Path,
type=Path,
required=False,
default=shutil.which("arduino-cli"),
help="path to arduino-cli",
Expand All @@ -30,12 +30,12 @@
)
output_args = parser.add_mutually_exclusive_group(required=True)
output_args.add_argument(
"--output", "-o", type=pathlib.Path, help="output file (CMake) with placeholders"
"--output", "-o", type=Path, help="output file (CMake) with placeholders"
)
output_args.add_argument(
"--sketch",
"-s",
type=pathlib.Path,
type=Path,
help="output file (CMake) filled given a sketch folder",
)

Expand All @@ -62,6 +62,13 @@
exit(-1)


# Path management
scriptname = Path(__file__).resolve()
corepath = scriptname.parent.parent.parent.resolve()
boards_txt = corepath / "boards.txt"
userhome = Path.home()


def arduino(*args):
# return (out.stdout, logfile)
# raises an exception if the command fails
Expand All @@ -76,16 +83,23 @@ def arduino(*args):
return (out, logfile)


def userhome_process(path):
lpath = str(path)
if path.is_relative_to(userhome):
lpath = f"~/{str(path.relative_to(userhome))}"
return lpath


def get_log(fname):
with open(fname) as file:
for line in file:
yield json.loads(line)


def get_boards(boardstxt):
def get_boards():

# we "reject" everything because we don't care about the values, only the keys
families = parse_file(boardstxt, lambda x: True)
# "reject" everything because we don't care about the values, only the keys
families = parse_file(boards_txt, lambda x: True)
del families["menu"]

boards = set()
Expand All @@ -97,7 +111,7 @@ def get_boards(boardstxt):

_, logf = arduino("lib", "list")

allboards = get_boards(pathlib.Path(__file__).parent.parent.parent / "boards.txt")
allboards = get_boards()


if shargs.board and shargs.board not in allboards:
Expand All @@ -119,11 +133,11 @@ def get_boards(boardstxt):
libpaths = dict()
for line in get_log(logf):
if line["msg"] == "Adding libraries dir":
libpaths[line["location"]] = pathlib.Path(line["dir"])
libpaths[line["location"]] = Path(line["dir"])

# platform lib path is already known, obviously, since that's where this script resides
if "user" in libpaths.keys():
userlibs = pathlib.Path(libpaths["user"])
userlibs = Path(libpaths["user"])
if userlibs.exists():
userlibs = userlibs.resolve()
libs = [u.name for u in userlibs.iterdir() if u.is_dir()]
Expand All @@ -137,7 +151,7 @@ def get_boards(boardstxt):
)
libs = list()
else:
userlibs = pathlib.Path.home() / "Arduino/libraries"
userlibs = Path.home() / "Arduino/libraries"
print(
f"""No user library path found through arduino-cli (falling back to {userlibs}).
This has likely to do with your arduino-cli configuration.
Expand All @@ -147,22 +161,13 @@ def get_boards(boardstxt):
)
libs = list()

corepath = pathlib.Path(__file__).parent.parent.parent.resolve()

j2_env = Environment(
loader=FileSystemLoader(str(corepath / "cmake" / "templates")),
trim_blocks=True,
lstrip_blocks=True,
)
cmake_template = j2_env.get_template("easy_cmake.cmake")


userhome = pathlib.Path.home()
if userlibs.is_relative_to(userhome):
userlibs = "~/" + str(userlibs.relative_to(userhome))
if corepath.is_relative_to(userhome):
corepath = "~/" + str(corepath.relative_to(userhome))

if shargs.sketch:
SOURCEFILE_EXTS = (".c", ".cpp", ".S", ".ino")
sources = {
Expand All @@ -180,19 +185,15 @@ def get_boards(boardstxt):
tgtname = ""
sources = set()

scriptname = pathlib.Path(__file__)
if scriptname.is_relative_to(userhome):
scriptname = "~/" + str(scriptname.relative_to(userhome))

with open(shargs.output or shargs.sketch / "CMakeLists.txt", "w") as out:
out.write(
cmake_template.render(
corepath=str(corepath).replace(
corepath=userhome_process(corepath).replace(
"\\", "\\\\"
), # escape backslashes for CMake
userlibs=str(userlibs).replace("\\", "\\\\"),
userlibs=userhome_process(userlibs).replace("\\", "\\\\"),
libs=libs,
scriptfile=scriptname,
scriptfile=userhome_process(scriptname),
tgtname=tgtname,
scrcfiles=sources,
boardname=shargs.board,
Expand Down
16 changes: 9 additions & 7 deletions cmake/scripts/cmake_gen.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/usr/bin/env python3

from pathlib import Path

SOURCEFILE_EXTS = (
".c",
".cpp",
Expand All @@ -20,7 +22,7 @@ def get_default_config():
)


def parse_configfile(file):
def parse_configfile(file: Path):
rawcfg = dict()

for line in open(file):
Expand All @@ -42,7 +44,7 @@ def parse_configfile(file):
return cfg


def get_sources(dir, recursive=False, relative_to=None):
def get_sources(dir: Path, recursive: bool = False, relative_to: Path = None):
if relative_to is None:
relative_to = dir
if recursive:
Expand All @@ -57,12 +59,12 @@ def get_sources(dir, recursive=False, relative_to=None):
}


def render(dir, template, config):
def render(dir: Path, template, config):
with open(dir / "CMakeLists.txt", "w") as outfile:
outfile.write(template.render(**config))


def get_static_libs(dir):
def get_static_libs(dir: Path):
result = dict()
cpu = ""
fpconf = "-" # format: f"{fpu}-{float_abi}"; this makes "-" by default
Expand All @@ -80,7 +82,7 @@ def get_static_libs(dir):
return result


def config_for_bareflat(dir, force_recurse=False):
def config_for_bareflat(dir: Path, force_recurse: bool = False):
# no library.properties
config = get_default_config()

Expand All @@ -98,7 +100,7 @@ def config_for_bareflat(dir, force_recurse=False):
return config


def config_for_modern(dir):
def config_for_modern(dir: Path):
# library.properties present, src/ present
config = get_default_config()
config.update(parse_configfile(dir / "library.properties"))
Expand All @@ -111,7 +113,7 @@ def config_for_modern(dir):
return config


def autoconfig(libdir):
def autoconfig(libdir: Path):
conf_file = libdir / "library.properties"
srcdir = libdir / "src"
if (
Expand Down
4 changes: 2 additions & 2 deletions cmake/scripts/cmake_updater_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

import argparse
import subprocess
import pathlib
from pathlib import Path
import sys

parser = argparse.ArgumentParser(
usage="updater hook for CMake files. Fully automatic, takes no argument."
)
shargs = parser.parse_args()

script_dir = pathlib.Path(__file__).parent # Arduino_Core_STM32/cmake/scripts
script_dir = Path(__file__).parent.resolve() # Arduino_Core_STM32/cmake/scripts
base_dir = script_dir.parent.parent # Arduino_Core_STM32
templates_dir = base_dir / "cmake" / "templates"

Expand Down
20 changes: 10 additions & 10 deletions cmake/scripts/generate_header.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
#!/usr/bin/env python3

import argparse
import pathlib
import re
from pathlib import Path

parser = argparse.ArgumentParser()
parser.add_argument(
"--source", "-i", type=pathlib.Path, required=True, help="ctags's output"
)
parser.add_argument(
"--out", "-o", type=pathlib.Path, required=True, help="header to generate"
)
parser.add_argument("--source", "-i", type=Path, required=True, help="ctags's output")
parser.add_argument("--out", "-o", type=Path, required=True, help="header to generate")

shargs = parser.parse_args()


externC_regex = re.compile(r'extern\s+"C"')
with open(shargs.source, "r") as infile:
with open(shargs.out, "w") as outfile:
for line in infile:
Expand All @@ -24,7 +20,11 @@
fields = line.split("\t")
kind = fields[3].split(":", 1)[1]
if kind == "function":
decl = ""
externC = externC_regex.search(fields[2])
if externC:
decl = 'extern "C" '
symname = fields[0]
signature = fields[5].split(":", 1)[1]
rtype = fields[6].split(":", 1)[1]
print(f"{rtype} {symname}{signature};", file=outfile)
print(f"{decl}{rtype} {symname}{signature};", file=outfile)
12 changes: 5 additions & 7 deletions cmake/scripts/includes.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
#!/usr/bin/env python3

import pathlib
from pathlib import Path
import argparse

import graphviz

parser = argparse.ArgumentParser()
parser.add_argument("-o", type=pathlib.Path, help="file to write the full graph to")
parser.add_argument(
"-t", type=pathlib.Path, help="file to write the transitive graph to"
)
parser.add_argument("-o", type=Path, help="file to write the full graph to")
parser.add_argument("-t", type=Path, help="file to write the transitive graph to")
parser.add_argument(
"logs",
type=pathlib.Path,
type=Path,
nargs="*",
action="extend",
help="list of log files to parse",
Expand All @@ -39,7 +37,7 @@ def parse_output(log):
for line in log:
d, h = line.rstrip().split(" ", 1)
d = d.count(".")
h = pathlib.Path(h)
h = Path(h)

if d == 0:
rootcause = h
Expand Down
6 changes: 3 additions & 3 deletions cmake/scripts/sizereport.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3

import pathlib
from pathlib import Path
import re
import subprocess
import argparse
Expand All @@ -9,14 +9,14 @@
parser.add_argument(
"-x",
"--tool",
type=pathlib.Path,
type=Path,
required=True,
help="path to `arm-none-eabi-size`",
)
parser.add_argument(
"-f",
"--binfile",
type=pathlib.Path,
type=Path,
required=True,
help="path to the binary to analyze",
)
Expand Down
10 changes: 4 additions & 6 deletions cmake/scripts/syms.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
#!/usr/bin/env python3

import pathlib
from pathlib import Path
import argparse

import graphviz

parser = argparse.ArgumentParser()
parser.add_argument(
"-m", "--mapfile", type=pathlib.Path, required=True, help="path to ld's map file"
"-m", "--mapfile", type=Path, required=True, help="path to ld's map file"
)
parser.add_argument("-f", "--fullgv", type=Path, help="file to write the full graph to")
parser.add_argument(
"-f", "--fullgv", type=pathlib.Path, help="file to write the full graph to"
)
parser.add_argument(
"-s", "--summarygv", type=pathlib.Path, help="file to write the summarized graph to"
"-s", "--summarygv", type=Path, help="file to write the summarized graph to"
)

shargs = parser.parse_args()
Expand Down
Loading
Loading