summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2025-12-01 17:31:43 +0700
committerhathach <[email protected]>2025-12-01 18:37:16 +0700
commita337a6d337c0cdd50981ba2040aee99966ae3152 (patch)
treeb77597744e229b7cffc48ba6dc7f5216c1d6570f
parentdf6f13600324b42710ae71d5320a9f2eae8303a5 (diff)
run linkermap as post build for size analyze
-rw-r--r--.circleci/config2.yml4
-rw-r--r--hw/bsp/family_support.cmake19
-rw-r--r--hw/bsp/rp2040/family.cmake7
-rwxr-xr-xtools/build.py58
-rwxr-xr-xtools/get_deps.py2
5 files changed, 58 insertions, 32 deletions
diff --git a/.circleci/config2.yml b/.circleci/config2.yml
index ab0fd7ba1..869597289 100644
--- a/.circleci/config2.yml
+++ b/.circleci/config2.yml
@@ -119,7 +119,9 @@ commands:
TOOLCHAIN_OPTION="--toolchain gcc"
fi
- python tools/build.py -s << parameters.build-system >> $TOOLCHAIN_OPTION << parameters.family >>
+ # circleci docker return $nproc as 36 core, limit parallel to 4 (resource-class = large)
+ # Required for IAR, also prevent crashed/killed by docker
+ python tools/build.py -s << parameters.build-system >> $TOOLCHAIN_OPTION -j 4 << parameters.family >>
fi
jobs:
diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake
index 5afec32c2..1f91d0910 100644
--- a/hw/bsp/family_support.cmake
+++ b/hw/bsp/family_support.cmake
@@ -226,14 +226,26 @@ endfunction()
# Add linkermap target (https://github.com/hathach/linkermap)
function(family_add_linkermap TARGET)
- set(LINKERMAP_OPTION "")
+ set(LINKERMAP_OPTION_LIST)
+ if (DEFINED LINKERMAP_OPTION)
+ separate_arguments(LINKERMAP_OPTION_LIST UNIX_COMMAND ${LINKERMAP_OPTION})
+ endif ()
+
if (ARGC GREATER 1)
- set(LINKERMAP_OPTION "${ARGV1}")
+ separate_arguments(ARG_OPTION_LIST UNIX_COMMAND ${ARGV1})
+ list(APPEND LINKERMAP_OPTION_LIST ${ARG_OPTION_LIST})
endif ()
+
+ # target
add_custom_target(${TARGET}-linkermap
- COMMAND python ${LINKERMAP_PY} -j -m ${LINKERMAP_OPTION} $<TARGET_FILE:${TARGET}>.map
+ COMMAND python ${LINKERMAP_PY} -j -m ${LINKERMAP_OPTION_LIST} $<TARGET_FILE:${TARGET}>.map
VERBATIM
)
+
+ # post build
+ add_custom_command(TARGET ${TARGET} POST_BUILD
+ COMMAND python ${LINKERMAP_PY} -j -m ${LINKERMAP_OPTION_LIST} $<TARGET_FILE:${TARGET}>.map
+ VERBATIM)
endfunction()
#-------------------------------------------------------------
@@ -345,6 +357,7 @@ function(family_configure_common TARGET RTOS)
endif ()
endif ()
+ # Generate linkermap target and post build. LINKERMAP_OPTION can be set with -D to change default options
family_add_linkermap(${TARGET})
# run size after build
diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake
index 5d6d8b40e..390d6072c 100644
--- a/hw/bsp/rp2040/family.cmake
+++ b/hw/bsp/rp2040/family.cmake
@@ -222,6 +222,8 @@ function(family_add_default_example_warnings TARGET)
endif()
endfunction()
+
+# TODO merge with family_configure_common from family_support.cmake
function(family_configure_target TARGET RTOS)
if (RTOS STREQUAL noos OR RTOS STREQUAL "")
set(RTOS_SUFFIX "")
@@ -239,10 +241,15 @@ function(family_configure_target TARGET RTOS)
pico_add_extra_outputs(${TARGET})
pico_enable_stdio_uart(${TARGET} 1)
+
+ target_link_options(${TARGET} PUBLIC "LINKER:-Map=$<TARGET_FILE:${TARGET}>.map")
target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_board${RTOS_SUFFIX} tinyusb_additions)
family_flash_openocd(${TARGET})
family_flash_jlink(${TARGET})
+
+ # Generate linkermap target and post build. LINKERMAP_OPTION can be set with -D to change default options
+ family_add_linkermap(${TARGET})
endfunction()
diff --git a/tools/build.py b/tools/build.py
index ce4d0ef1a..5328a987f 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -5,6 +5,7 @@ import os
import sys
import time
import subprocess
+import shlex
from pathlib import Path
from multiprocessing import Pool
@@ -29,9 +30,12 @@ parallel_jobs = os.cpu_count()
# Helper
# -----------------------------
def run_cmd(cmd):
- #print(cmd)
- r = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- title = f'Command Error: {cmd}'
+ if isinstance(cmd, str):
+ raise TypeError("run_cmd expects a list/tuple of args, not a string")
+ args = cmd
+ cmd_display = " ".join(args)
+ r = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ title = f'Command Error: {cmd_display}'
if r.returncode != 0:
# print build output if failed
if os.getenv('GITHUB_ACTIONS'):
@@ -42,7 +46,7 @@ def run_cmd(cmd):
print(title)
print(r.stdout.decode("utf-8"))
elif verbose:
- print(cmd)
+ print(cmd_display)
print(r.stdout.decode("utf-8"))
return r
@@ -87,10 +91,10 @@ def cmake_board(board, build_args, build_flags_on):
start_time = time.monotonic()
build_dir = f'cmake-build/cmake-build-{board}'
- build_flags = ''
+ build_flags = []
if len(build_flags_on) > 0:
- build_flags = ' '.join(f'-D{flag}=1' for flag in build_flags_on)
- build_flags = f'-DCFLAGS_CLI="{build_flags}"'
+ cli_flags = ' '.join(f'-D{flag}=1' for flag in build_flags_on)
+ build_flags.append(f'-DCFLAGS_CLI={cli_flags}')
build_dir += '-f1_' + '_'.join(build_flags_on)
family = find_family(board)
@@ -101,25 +105,22 @@ def cmake_board(board, build_args, build_flags_on):
if build_utils.skip_example(example, board):
ret[2] += 1
else:
- rcmd = run_cmd(f'idf.py -C examples/{example} -B {build_dir}/{example} -G Ninja '
- f'-DBOARD={board} {build_flags} build')
+ rcmd = run_cmd([
+ 'idf.py', '-C', f'examples/{example}', '-B', f'{build_dir}/{example}', '-GNinja',
+ f'-DBOARD={board}', *build_flags, 'build'
+ ])
ret[0 if rcmd.returncode == 0 else 1] += 1
else:
- rcmd = run_cmd(f'cmake examples -B {build_dir} -G Ninja -DBOARD={board} -DCMAKE_BUILD_TYPE=MinSizeRel '
- f'{build_args} {build_flags}')
+ rcmd = run_cmd([
+ 'cmake', 'examples', '-B', build_dir, '-GNinja',
+ f'-DBOARD={board}', '-DCMAKE_BUILD_TYPE=MinSizeRel',
+ '-DLINKERMAP_OPTION=-q -f tinyusb/src', *build_args, *build_flags
+ ])
if rcmd.returncode == 0:
- cmd = f"cmake --build {build_dir}"
- njobs = parallel_jobs
-
- # circleci docker return $nproc as 36 core, limit parallel according to resource class.
- # Required for IAR, also prevent crashed/killed by docker
- if os.getenv('CIRCLECI'):
- resource_class = { 'small': 1, 'medium': 2, 'medium+': 3, 'large': 4 }
- for rc in resource_class:
- if rc in os.getenv('CIRCLE_JOB'):
- njobs = resource_class[rc]
- break
- cmd += f' --parallel {njobs}'
+ cmd = [
+ "cmake", "--build", build_dir,
+ '--parallel', str(parallel_jobs)
+ ]
rcmd = run_cmd(cmd)
ret[0 if rcmd.returncode == 0 else 1] += 1
@@ -141,9 +142,12 @@ def make_one_example(example, board, make_option):
# skip -j for circleci
if not os.getenv('CIRCLECI'):
make_option += ' -j'
- make_cmd = f"make -C examples/{example} BOARD={board} {make_option}"
- # run_cmd(f"{make_cmd} clean")
- build_result = run_cmd(f"{make_cmd} all")
+ make_args = ["make", "-C", f"examples/{example}", f"BOARD={board}"]
+ if make_option:
+ make_args += shlex.split(make_option)
+ make_args.append("all")
+ # run_cmd(make_args + ["clean"])
+ build_result = run_cmd(make_args)
r = 0 if build_result.returncode == 0 else 1
print_build_result(board, example, r, time.monotonic() - start_time)
@@ -180,7 +184,7 @@ def build_boards_list(boards, build_defines, build_system, build_flags_on):
for b in boards:
r = [0, 0, 0]
if build_system == 'cmake':
- build_args = ' '.join(f'-D{d}' for d in build_defines)
+ build_args = [f'-D{d}' for d in build_defines]
r = cmake_board(b, build_args, build_flags_on)
elif build_system == 'make':
build_args = ' '.join(f'{d}' for d in build_defines)
diff --git a/tools/get_deps.py b/tools/get_deps.py
index c60766e50..47cc5c7dd 100755
--- a/tools/get_deps.py
+++ b/tools/get_deps.py
@@ -15,7 +15,7 @@ deps_mandatory = {
'159e31b689577dbf69cf0683bbaffbd71fa5ee10',
'all'],
'tools/linkermap': ['https://github.com/hathach/linkermap.git',
- 'e1a7a990fcd6eb1dbae13c2eb9fb0ca9db7ac483',
+ '1f47651142646398c7746e109ae0481732aeb564',
'all'],
'tools/uf2': ['https://github.com/microsoft/uf2.git',
'c594542b2faa01cc33a2b97c9fbebc38549df80a',