diff --git a/.circleci/config.yml b/.circleci/config.yml index 580f5fe2e..d04a33959 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,25 +18,34 @@ jobs: MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py) echo "MATRIX_JSON=$MATRIX_JSON" - BUILDSYSTEM_TOOLCHAIN=( - "cmake aarch64-gcc" - "cmake arm-clang" - "cmake arm-gcc" - "cmake esp-idf" - "cmake msp430-gcc" - "cmake riscv-gcc" + BUILDSYSTEM_LIST=( + "cmake" + "make" + ) + + TOOLCHAIN_LIST=( + "aarch64-gcc" + "arm-clang" + "arm-gcc" + "esp-idf" + "msp430-gcc" + "riscv-gcc" ) # only build IAR if not forked PR, since IAR token is not shared if [ -z $CIRCLE_PR_USERNAME ]; then - BUILDSYSTEM_TOOLCHAIN+=("cmake arm-iar") + TOOLCHAIN_LIST+=("arm-iar") fi gen_build_entry() { local build_system="$1" local toolchain="$2" local family="$3" - local resource_class="$4" + local build_args="" + + if [[ "$toolchain" == "arm-iar" || "$build_system" == "make" ]]; then + build_args="--one-per-family" + fi if [[ "$toolchain" == "esp-idf" ]]; then echo " - build-vm:" >> .circleci/config2.yml @@ -49,17 +58,21 @@ jobs: echo " build-system: ['$build_system']" >> .circleci/config2.yml echo " toolchain: ['$toolchain']" >> .circleci/config2.yml echo " family: $family" >> .circleci/config2.yml - echo " resource_class: ['$resource_class']" >> .circleci/config2.yml + echo " resource_class: ['large']" >> .circleci/config2.yml + echo " build-args: ['$build_args']" >> .circleci/config2.yml } - for e in "${BUILDSYSTEM_TOOLCHAIN[@]}"; do - e_arr=($e) - build_system="${e_arr[0]}" - toolchain="${e_arr[1]}" - FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\"") - echo "FAMILY_${toolchain}=$FAMILY" + for build_system in "${BUILDSYSTEM_LIST[@]}"; do + for toolchain in "${TOOLCHAIN_LIST[@]}"; do + # make does not support these toolchains + if [ "$build_system" == "make" ] && { [ "$toolchain" == "arm-clang" ] || [ "$toolchain" == "arm-iar" ] || [ "$toolchain" == "esp-idf" ]; }; then + continue + fi - gen_build_entry "$build_system" "$toolchain" "$FAMILY" "large" + FAMILY=$(echo $MATRIX_JSON | jq -r ".\"$toolchain\"") + echo "FAMILY_${toolchain}=$FAMILY" + gen_build_entry "$build_system" "$toolchain" "$FAMILY" + done done - continuation/continue: @@ -67,9 +80,5 @@ jobs: workflows: set-matrix: - # Only build PR here, Push will be built by github action. - when: - and: - - not: << pipeline.git.branch.is_default >> jobs: - set-matrix diff --git a/.circleci/config2.yml b/.circleci/config2.yml index 869597289..77bc4f790 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -66,6 +66,9 @@ commands: type: string family: type: string + build-args: + type: string + default: "" steps: - checkout @@ -107,7 +110,7 @@ commands: no_output_timeout: 20m command: | if [ << parameters.toolchain >> == esp-idf ]; then - docker run --rm -v $PWD:/project -w /project espressif/idf:v5.3.2 python tools/build.py << parameters.family >> + docker run --rm -v $PWD:/project -w /project espressif/idf:v5.3.2 python tools/build.py << parameters.build-args >> << parameters.family >> else # Toolchain option default is gcc if [ << parameters.toolchain >> == arm-clang ]; then @@ -121,7 +124,7 @@ commands: # 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 >> + python tools/build.py -s << parameters.build-system >> $TOOLCHAIN_OPTION -j 4 << parameters.build-args >> << parameters.family >> fi jobs: @@ -137,6 +140,9 @@ jobs: type: string family: type: string + build-args: + type: string + default: "" docker: - image: cimg/base:current @@ -147,6 +153,7 @@ jobs: build-system: << parameters.build-system >> toolchain: << parameters.toolchain >> family: << parameters.family >> + build-args: << parameters.build-args >> # Build using VM build-vm: @@ -160,6 +167,9 @@ jobs: type: string family: type: string + build-args: + type: string + default: "" machine: image: ubuntu-2404:current @@ -170,6 +180,7 @@ jobs: build-system: << parameters.build-system >> toolchain: << parameters.toolchain >> family: << parameters.family >> + build-args: << parameters.build-args >> workflows: build: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 77f2d573f..a1bacbc27 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,10 +56,11 @@ jobs: echo "hil_matrix=$HIL_MATRIX_JSON" echo "hil_matrix=$HIL_MATRIX_JSON" >> $GITHUB_OUTPUT - # --------------------------------------- - # Build CMake: only one-per-family. - # Full built is done by CircleCI in PR - # --------------------------------------- + # ------------------------------------------------------------------------------ + # CMake build: only one-per-family. Full built is done by CircleCI in PR + # Note: + # For Make and IAR build: will be done on CircleCI only (one-per-family too) + # ------------------------------------------------------------------------------ cmake: needs: set-matrix uses: ./.github/workflows/build_util.yml @@ -70,7 +71,7 @@ jobs: - 'aarch64-gcc' #- 'arm-clang' - 'arm-gcc' - - 'esp-idf' + #- 'esp-idf' - 'msp430-gcc' - 'riscv-gcc' with: @@ -137,52 +138,6 @@ jobs: header: code-metrics path: metrics_compare.md - - # --------------------------------------- - # Build Make: only build on push with one-per-family - # --------------------------------------- - make: - if: github.event_name == 'push' - needs: set-matrix - uses: ./.github/workflows/build_util.yml - strategy: - fail-fast: false - matrix: - toolchain: - - 'aarch64-gcc' - #- 'arm-clang' - - 'arm-gcc' - - 'msp430-gcc' - - 'riscv-gcc' - - 'rx-gcc' - with: - build-system: 'make' - toolchain: ${{ matrix.toolchain }} - build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }} - one-per-family: true - - # --------------------------------------- - # Build IAR - # Since IAR Token secret is not passed to forked PR, only build non-forked PR with make. - # cmake is built by circle-ci. Due to IAR limit capacity, only build oe per family - # --------------------------------------- - arm-iar: - if: false # disable for now since we got reach capacity limit too often - #if: github.event_name == 'push' && github.repository_owner == 'hathach' - needs: set-matrix - uses: ./.github/workflows/build_util.yml - secrets: inherit - strategy: - fail-fast: false - matrix: - build-system: - - 'make' - with: - build-system: ${{ matrix.build-system }} - toolchain: 'arm-iar' - build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)['arm-iar']) }} - one-per-family: true - # --------------------------------------- # Build Make/CMake on Windows/MacOS # --------------------------------------- @@ -193,10 +148,9 @@ jobs: fail-fast: false matrix: os: [ windows-latest, macos-latest ] - build-system: [ 'make', 'cmake' ] with: os: ${{ matrix.os }} - build-system: ${{ matrix.build-system }} + build-system: 'cmake-make' toolchain: 'arm-gcc-${{ matrix.os }}' build-args: '["stm32h7"]' one-per-family: true diff --git a/.github/workflows/build_util.yml b/.github/workflows/build_util.yml index 36043a1d5..2fc0eead0 100644 --- a/.github/workflows/build_util.yml +++ b/.github/workflows/build_util.yml @@ -68,6 +68,9 @@ jobs: run: | if [ "$TOOLCHAIN" == "esp-idf" ]; then docker run --rm -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py ${{ matrix.arg }} + elif [ "${{ inputs.build-system }}" == "cmake-make" ] || [ "${{ inputs.build-system }}" == "make-cmake" ]; then + python tools/build.py -s make ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} + python tools/build.py -s cmake ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} else python tools/build.py -s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ steps.set-one-per-family.outputs.build_option }} ${{ matrix.arg }} fi diff --git a/examples/build_system/make/toolchain/gcc_common.mk b/examples/build_system/make/toolchain/gcc_common.mk index 0cbb6774d..42fd01183 100644 --- a/examples/build_system/make/toolchain/gcc_common.mk +++ b/examples/build_system/make/toolchain/gcc_common.mk @@ -31,6 +31,9 @@ CFLAGS += \ -Wreturn-type \ -Wredundant-decls \ +CFLAGS_CLANG += \ + -Wno-error=unknown-warning-option + # -Wmissing-prototypes \ # conversion is too strict for most mcu driver, may be disable sign/int/arith-conversion # -Wconversion diff --git a/hw/bsp/kinetis_k/family.mk b/hw/bsp/kinetis_k/family.mk index e95cdb717..7a51a77d8 100644 --- a/hw/bsp/kinetis_k/family.mk +++ b/hw/bsp/kinetis_k/family.mk @@ -9,11 +9,13 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_KINETIS_K \ LDFLAGS += \ - -nostartfiles \ - --specs=nosys.specs --specs=nano.specs \ -Wl,--defsym,__stack_size__=0x400 \ -Wl,--defsym,__heap_size__=0 +LDFLAGS_GCC += \ + -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ + SRC_C += \ src/portable/nxp/khci/dcd_khci.c \ src/portable/nxp/khci/hcd_khci.c \ diff --git a/hw/bsp/kinetis_kl/family.mk b/hw/bsp/kinetis_kl/family.mk index 8d113aecf..aec53d486 100644 --- a/hw/bsp/kinetis_kl/family.mk +++ b/hw/bsp/kinetis_kl/family.mk @@ -9,11 +9,13 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_KINETIS_KL \ LDFLAGS += \ - -nostartfiles \ - -specs=nosys.specs -specs=nano.specs \ -Wl,--defsym,__stack_size__=0x400 \ -Wl,--defsym,__heap_size__=0 +LDFLAGS_GCC += \ + -nostartfiles \ + -specs=nosys.specs -specs=nano.specs \ + SRC_C += \ src/portable/nxp/khci/dcd_khci.c \ src/portable/nxp/khci/hcd_khci.c \ diff --git a/tools/build.py b/tools/build.py index e4909f45f..c4f1558c0 100755 --- a/tools/build.py +++ b/tools/build.py @@ -142,16 +142,12 @@ def make_one_example(example, board, make_option): r = 2 else: start_time = time.monotonic() - # skip -j for circleci - if not os.getenv('CIRCLECI'): - make_option += ' -j' - make_args = ["make", "-C", f"examples/{example}", f"BOARD={board}"] + make_args = ["make", "-C", f"examples/{example}", f"BOARD={board}", '-j', str(parallel_jobs)] if make_option: make_args += shlex.split(make_option) - make_args.append("all") if clean_build: run_cmd(make_args + ["clean"]) - build_result = run_cmd(make_args) + build_result = run_cmd(make_args + ['all']) r = 0 if build_result.returncode == 0 else 1 print_build_result(board, example, r, time.monotonic() - start_time) diff --git a/tools/metrics.py b/tools/metrics.py index bb84f803e..c3b366e42 100644 --- a/tools/metrics.py +++ b/tools/metrics.py @@ -195,17 +195,13 @@ def compare_maps(base_file, new_file, filters=None): def format_diff(base, new, diff): """Format a diff value with percentage.""" - if base == 0 and new == 0: - return "0" - if base == 0: - return f"{new} (new)" - if new == 0: - return f"{base} ➡ 0" if diff == 0: - return f"{base} ➡ {new}" + return f"{new}" + if base == 0 or new == 0: + return f"{base} ➙ {new}" pct = (diff / base) * 100 sign = "+" if diff > 0 else "" - return f"{base} ➡ {new} ({sign}{diff}, {sign}{pct:.1f}%)" + return f"{base} ➙ {new} ({sign}{diff}, {sign}{pct:.1f}%)" def get_sort_key(sort_order): @@ -232,10 +228,11 @@ def write_compare_markdown(comparison, path, sort_order='size'): sections = comparison["sections"] md_lines = [ - "# TinyUSB Code Size Different Report", + "# Size Difference Report", "", - f"**Base:** `{comparison['base_file']}`", - f"**New:** `{comparison['new_file']}`", + "Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds." + "", + "Note: If there is no change, only one value is shown.", "", ]