Skip to content

Commit 8c0a382

Browse files
committed
refactor: enhanced user interface
- wrappers - keywords - renaming - nicer syntax for external libraries - embed `updatedb()` in `set_board()` - support build.opt - changed default for REATIVE_MACRO (since 2.3.0) - NDEBUG defined by default (since... whenever) - added a generic setting to disable HAL modules internally: - added argparse to the scripts in CI/update
1 parent 0deb6c2 commit 8c0a382

11 files changed

+338
-266
lines changed

CI/update/cmake_core.py

+7-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env python3
22

3+
import argparse
34
import sys
45
from pathlib import Path
56
from jinja2 import Environment, FileSystemLoader
@@ -8,25 +9,18 @@
89
sys.path.append(str(script_path.parent))
910
from utils.cmake_gen import *
1011

11-
if len(sys.argv) != 2 :
12-
print("Usage: cmake_core.py <.../cores/arduino>")
13-
print("Generates a CMakeLists.txt describing a core")
14-
print("The resulting static library will be named \"core\".")
12+
parser = argparse.ArgumentParser()
13+
parser.add_argument("corepath", type=Path, help="path to .../cores/arduino")
14+
15+
shargs = parser.parse_args()
1516

16-
rootdir = Path(sys.argv[1]).resolve()
17-
script_path = Path(__file__).parent.resolve()
1817
templates_dir = script_path / "templates"
1918
j2_env = Environment(
2019
loader=FileSystemLoader(str(templates_dir)), trim_blocks=True, lstrip_blocks=True
2120
)
2221
cmake_template = j2_env.get_template("CMakeLists.txt")
2322

24-
if not (rootdir.exists() and rootdir.is_dir()) :
25-
print(f"Can't find {rootdir}/")
26-
exit(1)
27-
28-
29-
config = config_for_bareflat(rootdir, force_recurse=True)
23+
config = config_for_bareflat(shargs.corepath, force_recurse=True)
3024
config["target"] = "core"
3125
config["objlib"] = False
32-
render(rootdir, cmake_template, config)
26+
render(shargs.corepath, cmake_template, config)

CI/update/cmake_libs.py

+13-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env python3
22

3+
import argparse
34
import sys
45
from pathlib import Path
56
from jinja2 import Environment, FileSystemLoader
@@ -8,35 +9,31 @@
89
sys.path.append(str(script_path.parent))
910
from utils.cmake_gen import *
1011

11-
if len(sys.argv) != 2 :
12-
print("Usage: cmake_libs.py <.../libraries>")
13-
print("Generates a CMakeLists.txt for each library in the folder")
14-
print("Usage: cmake_libs.py <.../AwesomeArduinoLibrary>")
15-
print("Generates a CMakeLists.txt for the specified library")
16-
print("The resulting library targets will be named like their folders.")
12+
parser = argparse.ArgumentParser()
13+
input_dirs = parser.add_mutually_exclusive_group(required=True)
14+
input_dirs.add_argument("--library", "-l", type=Path, help="path to a single library to parse")
15+
input_dirs.add_argument("--libraries", "-L", type=Path, help="path to a folder of libraries")
16+
parser.add_argument("--depends", "-d", action="extend", nargs="*", default=list(), help="additional dependencies of the libraries to parse")
1717

18+
shargs = parser.parse_args()
1819

19-
rootdir = Path(sys.argv[1]).resolve()
20-
script_path = Path(__file__).parent.resolve()
2120
templates_dir = script_path / "templates"
2221
j2_env = Environment(
2322
loader=FileSystemLoader(str(templates_dir)), trim_blocks=True, lstrip_blocks=True
2423
)
2524
cmake_template = j2_env.get_template("CMakeLists.txt")
2625

27-
if not rootdir.exists() :
28-
print(f"Can't find {rootdir}/")
29-
exit(1)
30-
31-
if rootdir.name == "libraries" :
32-
for lib in rootdir.iterdir() :
26+
if shargs.libraries is not None :
27+
for lib in shargs.libraries.iterdir() :
3328
if not lib.is_dir() :
3429
continue
3530

3631
config = autoconfig(lib)
3732
config["extra_libs"].add("core")
33+
config["extra_libs"].update(shargs.depends)
3834
render(lib, cmake_template, config)
3935
else :
40-
config = autoconfig(rootdir)
36+
config = autoconfig(shargs.library)
4137
config["extra_libs"].add("core")
42-
render(rootdir, cmake_template, config)
38+
config["extra_libs"].update(shargs.depends)
39+
render(shargs.library, cmake_template, config)

CI/update/cmake_variant.py

+6-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env python3
22

3+
import argparse
34
import sys
45
from pathlib import Path
56
from jinja2 import Environment, FileSystemLoader
@@ -8,24 +9,19 @@
89
sys.path.append(str(script_path.parent))
910
from utils.cmake_gen import *
1011

11-
if len(sys.argv) != 2 :
12-
print("Usage: cmake_variant.py <.../variants>")
13-
print("Generates a CMakeLists.txt describing a variant folder")
14-
print("The resulting static library will be named \"variant\".")
12+
parser = argparse.ArgumentParser()
13+
parser.add_argument("variantspath", type=Path, help="path to .../variants/")
14+
15+
shargs = parser.parse_args()
1516

16-
rootdir = Path(sys.argv[1]).resolve()
17-
script_path = Path(__file__).parent.resolve()
1817
templates_dir = script_path / "templates"
1918
j2_env = Environment(
2019
loader=FileSystemLoader(str(templates_dir)), trim_blocks=True, lstrip_blocks=True
2120
)
2221
cmake_template = j2_env.get_template("CMakeLists.txt")
2322

24-
if not (rootdir.exists() and rootdir.is_dir()) :
25-
print(f"Can't find {rootdir}/")
26-
exit(1)
2723

28-
for family in rootdir.iterdir() :
24+
for family in shargs.variantspath.iterdir() :
2925
if not family.is_dir() :
3026
continue
3127
for variant in family.iterdir() :

CMakeLists.txt

+5-80
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,6 @@ include(ensure_ctags)
88
project("Arduino_Core_STM32" CXX C ASM)
99

1010

11-
set(FEAT_NANOC ON CACHE BOOL "Use nano libc?")
12-
set(FEAT_FPF OFF CACHE BOOL "nanolibc: enable %f in printf?")
13-
set(FEAT_FSF OFF CACHE BOOL "nanolibc: enable %f in scanf?")
14-
set(FEAT_TIMER ON CACHE BOOL "Timer support")
15-
16-
set(BUILD_OPT "s" CACHE STRING "Optimization level")
17-
set(BUILD_DBG OFF CACHE BOOL "Enable debug symbols")
18-
set(BUILD_LTO OFF CACHE BOOL "Enable Link-Time-Optimisations")
19-
set(BUILD_RELPATH ON CACHE BOOL "make __FILE__ be relative instead of absolute")
20-
set(BUILD_NDEBUG ON CACHE BOOL "define the NDEBUG macro?")
21-
22-
2311
set(BUILD_CORE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cores/arduino")
2412
set(BUILD_SYSTEM_PATH "${CMAKE_CURRENT_SOURCE_DIR}/system")
2513
set(BUILD_LIB_PATH "${CMAKE_CURRENT_SOURCE_DIR}/libraries")
@@ -34,67 +22,11 @@ ensure_ctags(${CTAGS_PATH} ${AUTODL_CTAGS})
3422

3523
add_library(base_config INTERFACE)
3624

37-
if(${BUILD_RELPATH})
38-
# $<TARGET_PROPERTY:SOURCE_DIR> is evaluated by the final consumer, no base_config
39-
target_compile_options(base_config INTERFACE
40-
"-fmacro-prefix-map=$<TARGET_PROPERTY:SOURCE_DIR>=."
41-
)
42-
endif()
43-
44-
if(${BUILD_NDEBUG})
45-
add_compile_definitions(base_config INTERFACE NDEBUG)
46-
endif()
47-
48-
49-
if (${FEAT_NANOC})
50-
target_link_options(base_config INTERFACE
51-
"--specs=nano.specs"
52-
)
53-
if (${FEAT_FPF})
54-
target_link_options(base_config INTERFACE
55-
"SHELL:-u _printf_float"
56-
)
57-
endif()
58-
if(${FEAT_FSF})
59-
target_link_options(base_config INTERFACE
60-
"SHELL:-u _scanf_float"
61-
)
62-
endif()
63-
endif()
64-
65-
if (${FEAT_TIMER})
66-
target_compile_definitions(base_config INTERFACE
67-
HAL_TIM_MODULE_ENABLE
68-
)
69-
else ()
70-
# triggers a user-directed warning
71-
target_compile_definitions(base_config INTERFACE
72-
HAL_TIM_MODULE_DISABLED
73-
)
74-
endif()
75-
76-
if (${BUILD_OPT} MATCHES "^[0-3gs]$")
77-
target_compile_options(base_config INTERFACE
78-
-O${BUILD_OPT}
79-
)
80-
else()
81-
message(SEND_ERROR "Bad value for BUILD_OPT: got `${BUILD_OPT}`, expected one of 0123gs.")
82-
endif()
83-
84-
if (${BUILD_DBG})
85-
target_compile_options(base_config INTERFACE
86-
-g
87-
)
88-
endif()
89-
90-
if (${BUILD_LTO})
91-
target_compile_options(base_config INTERFACE
92-
-flto
93-
)
94-
target_link_options(base_config INTERFACE
95-
-flto
96-
)
97-
endif()
25+
# better than an if/else because these may be defined later
26+
target_link_libraries(base_config INTERFACE
27+
$<TARGET_NAME_IF_EXISTS:user_settings>
28+
$<TARGET_NAME_IF_EXISTS:board>
29+
)
9830

9931
# generic compilation options
10032
target_link_libraries(base_config INTERFACE board)
@@ -145,8 +77,6 @@ target_include_directories(base_config INTERFACE
14577
"${BUILD_SYSTEM_PATH}/Middlewares/OpenAMP/open-amp/lib/include"
14678
"${BUILD_SYSTEM_PATH}/Middlewares/OpenAMP/libmetal/lib/include"
14779
"${BUILD_SYSTEM_PATH}/Middlewares/OpenAMP/virtual_driver"
148-
149-
"${BUILD_LIB_PATH}/SrcWrapper/src"
15080
)
15181

15282
add_subdirectory(${BUILD_CORE_PATH})
@@ -156,11 +86,6 @@ add_subdirectory(${BUILD_LIB_PATH})
15686

15787
add_library(stm32_runtime INTERFACE)
15888
target_link_libraries(stm32_runtime INTERFACE
159-
# note: there may be recursive dependencies between core and SrcWrapper (v. <= 2.2.0)
160-
# this would require some --Wl,--start-group / -Wl,--end-group
161-
# but SrcWrapper is an object library, not an archive, so it isn't necessary
162-
# (this means the linker takes all the object unconditionally, as opposed to an archive where it picks what it needs)
163-
# note: SrcWrapper in particular MUST be an object library, due to possible weak+strong symbols (cf. library.properties)
16489
base_config
16590

16691
SrcWrapper

cmake/build_sketch.cmake

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
## core feature
2+
3+
set(SCRIPTS_FOLDER ${CMAKE_CURRENT_LIST_DIR}/../scripts)
4+
include(sketch_preprocess_sources)
5+
include(convert_file)
6+
7+
function(build_sketch)
8+
cmake_parse_arguments(PARSE_ARGV 0 SKBD "" "TARGET" "SOURCES;DEPENDS")
9+
10+
if(DEFINED SKBD_UNPARSED_ARGUMENTS OR DEFINED SKBD_KEYWORDS_MISSING_VALUES)
11+
message(SEND_ERROR "Invalid call to build_sketch(); some arguments went unparsed")
12+
endif()
13+
14+
if(NOT DEFINED SKBD_TARGET)
15+
message(SEND_ERROR "Invalid call to build_sketch(); please specify a TARGET")
16+
return()
17+
elseif(NOT DEFINED SKBD_SOURCES)
18+
message(SEND_ERROR "Invalid call to build_sketch(); please specify some SOURCES")
19+
return()
20+
endif()
21+
22+
add_executable(${SKBD_TARGET})
23+
target_include_directories(base_config INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
24+
25+
foreach(SRCS IN LISTS SKBD_SOURCES)
26+
sketch_preprocess_sources(OUTPUT_VARIABLE SRCS SOURCES ${SRCS})
27+
target_sources(${SKBD_TARGET} PRIVATE ${SRCS})
28+
endforeach()
29+
30+
target_link_libraries(${SKBD_TARGET} PRIVATE stm32_runtime)
31+
if(DEFINED SKBD_DEPENDS)
32+
target_link_libraries(${SKBD_TARGET} PRIVATE ${SKBD_DEPENDS})
33+
endif()
34+
35+
get_target_property(OUTDIR ${SKBD_TARGET} BINARY_DIR)
36+
set(MAPFILE ${OUTDIR}/${SKBD_TARGET}.map)
37+
38+
target_link_options(${SKBD_TARGET} PRIVATE
39+
LINKER:-Map,${MAPFILE}
40+
)
41+
42+
# this is here to make CMake et al. aware that the map file
43+
# is generated along with the binary
44+
add_custom_command(TARGET ${SKBD_TARGET} POST_BUILD
45+
COMMAND ${CMAKE_COMMAND} -E true # essentially a no-op
46+
BYPRODUCTS ${MAPFILE}
47+
)
48+
49+
if(EXISTS ${PYTHON3})
50+
add_custom_command(TARGET ${SKBD_TARGET} POST_BUILD
51+
COMMAND ${PYTHON3} ${SCRIPTS_FOLDER}/sizereport.py -x ${CMAKE_SIZE} -f $<TARGET_FILE:${SKBD_TARGET}> --progmem ${BOARD_MAXSIZE} --datamem ${BOARD_MAXDATASIZE}
52+
)
53+
else() # STREQUAL "PYTHON3-NOTFOUND"
54+
message(WARNING "python3 not found; the final size report will not be displayed")
55+
endif()
56+
57+
elf2bin(${SKBD_TARGET})
58+
elf2hex(${SKBD_TARGET})
59+
endfunction()

cmake/convert_file.cmake

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
function(elf2bin ELFTGT)
3+
add_custom_command(TARGET ${ELFTGT} POST_BUILD
4+
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${ELFTGT}> $<TARGET_FILE:${ELFTGT}>.bin
5+
)
6+
set_property(TARGET ${ELFTGT} APPEND PROPERTY ADDITIONAL_CLEAN_FILES "$<TARGET_FILE:${ELFTGT}>.bin")
7+
endfunction()
8+
9+
function(elf2hex ELFTGT)
10+
add_custom_command(TARGET ${ELFTGT} POST_BUILD
11+
COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:${ELFTGT}> $<TARGET_FILE:${ELFTGT}>.hex
12+
)
13+
set_property(TARGET ${ELFTGT} APPEND PROPERTY ADDITIONAL_CLEAN_FILES "$<TARGET_FILE:${ELFTGT}>.hex")
14+
endfunction()
15+
16+
function(gv2svg GVFILE)
17+
get_filename_component(ABSGV ${GVFILE} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_BINARY_DIR})
18+
get_filename_component(GVNAME ${GVFILE} NAME)
19+
20+
# HACK: all this to get the final SVG file as a visible target with the same name as the file
21+
add_custom_target(${GVNAME}.svg DEPENDS ${ABSGV})
22+
add_custom_command(TARGET ${GVNAME}.svg POST_BUILD
23+
COMMAND ${SFDP} -Tsvg -o ${ABSGV}.svg ${ABSGV}
24+
)
25+
set_property(TARGET ${GVNAME}.svg APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${ABSGV}.svg)
26+
27+
endfunction()

cmake/external_library.cmake

+17-8
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
11

22
set(CI_FOLDER ${CMAKE_CURRENT_LIST_DIR}/../CI)
33

4-
function(external_library LIBPATH)
5-
if(NOT EXISTS ${LIBPATH}/CMakeLists.txt)
4+
function(external_library)
5+
cmake_parse_arguments(PARSE_ARGV 0 XLIB "FORCE" "PATH" "DEPENDS")
6+
7+
if(DEFINED XLIB_UNPARSED_ARGUMENTS OR DEFINED XLIB_KEYWORDS_MISSING_VALUES)
8+
message(SEND_ERROR "Invalid call to external_library(); some arguments went unparsed")
9+
endif()
10+
11+
if(NOT DEFINED XLIB_PATH)
12+
message(SEND_ERROR "Invalid call to external_library(); please specify a PATH")
13+
return()
14+
endif()
15+
16+
if(NOT EXISTS ${XLIB_PATH}/CMakeLists.txt OR ${XLIB_FORCE})
617
execute_process(
7-
COMMAND ${PYTHON3} ${CI_FOLDER}/update/cmake_libs.py ${LIBPATH}
18+
COMMAND ${PYTHON3} ${CI_FOLDER}/update/cmake_libs.py -l ${XLIB_PATH} -d ${XLIB_DEPENDS}
19+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
820
)
921
endif()
10-
get_filename_component(LIBNAME ${LIBPATH} NAME)
11-
add_subdirectory(
12-
${LIBPATH}
13-
${CMAKE_CURRENT_BINARY_DIR}/${LIBNAME}
14-
)
22+
get_filename_component(LIBNAME ${XLIB_PATH} NAME)
23+
add_subdirectory(${XLIB_PATH} ${LIBNAME})
1524
endfunction()

0 commit comments

Comments
 (0)