From 16889edd8a80d3d272333266af157328e6929d06 Mon Sep 17 00:00:00 2001 From: Lars Kakavandi-Nielsen Date: Wed, 22 Jul 2026 16:16:07 +0200 Subject: [PATCH 1/3] 256: Fixing using lower case o when setting optimisation level -o0 was replaced with -O0 to correctly set optimisation level. This issue only happens with build target LINUX Fixes #256 --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 7d2a256..91bb4d1 100755 --- a/Makefile +++ b/Makefile @@ -96,8 +96,8 @@ COMPILER := $(if $(filter CPP,$(VARIANT)),$(CXX),$(CC)) INC_DIRS += $(UT_CORE_DIR)/sysroot/usr/include UT_CONTROL_COMPILER := $(CC) else -COMPILER := $(if $(filter CPP,$(VARIANT)),g++ -ggdb -o0 -Wall, gcc -ggdb -o0 -Wall) -UT_CONTROL_COMPILER := gcc -ggdb -o0 -Wall +COMPILER := $(if $(filter CPP,$(VARIANT)),g++ -ggdb -O0 -Wall, gcc -ggdb -O0 -Wall) +UT_CONTROL_COMPILER := gcc -ggdb -O0 -Wall endif # Common object file setup From 8646879948ab5c4d4e58f02ee8a348abfda32b10 Mon Sep 17 00:00:00 2001 From: Ulrond <131959864+Ulrond@users.noreply.github.com> Date: Mon, 27 Jul 2026 21:53:06 +0100 Subject: [PATCH 2/3] test: guard against mistyped and missing compiler flags Adds check_makefile_flags to the tests suite, alongside the existing check_macros static gate. Two checks: scan walks the build files for a lowercase -o glued to an optimisation level (-o0, -os, -og). gcc accepts these silently and a later -o $@ on the same command line wins, so nothing ever fails - which is why #256 went unnoticed. expect asks make printenv what COMPILER and UT_CONTROL_COMPILER actually expand to and asserts -ggdb -O0 -Wall are present, catching the flags being dropped as well as mistyped. Runs before the framework build so a flag typo is reported in seconds rather than after a full compile. Expectations apply to TARGET=linux only; arm takes its compiler from the SDK. Verified by reintroducing -o0: both checks fail, exit 1. Refs #256 --- tests/Makefile | 14 ++- tests/check_makefile_flags.py | 223 ++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+), 2 deletions(-) create mode 100755 tests/check_makefile_flags.py diff --git a/tests/Makefile b/tests/Makefile index 17b7c0d..4556c02 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -22,6 +22,7 @@ BIN_DIR := $(ROOT_DIR)/build/bin ECHOE = /bin/echo -e TARGET_EXEC = ut-test PYTHON_SCRIPT = $(ROOT_DIR)/check_macros_usage.py +FLAGS_SCRIPT = $(ROOT_DIR)/check_makefile_flags.py # Switch on Linux & disable asserts for the testing suites CFLAGS += -DNDEBUG @@ -44,6 +45,8 @@ endif ifneq ($(TARGET),arm) TARGET = linux +# arm takes its compiler from the SDK, so only linux has flags of our own to assert +EXPECTED_FLAGS = --expect COMPILER=-ggdb,-O0,-Wall --expect UT_CONTROL_COMPILER=-ggdb,-O0,-Wall endif BUILD_DIR := $(ROOT_DIR)/build/${TARGET}/obj @@ -66,9 +69,11 @@ export BUILD_WEAK_STUBS_SRC GREEN='\033[0;32m' NC='\033[0m' -.PHONY: clean list build all +.PHONY: clean list build all check_macros check_makefile_flags -all: framework check_macros +# check_makefile_flags runs first: it is static, and a flag typo is cheaper to +# hear about now than after a full framework build +all: check_makefile_flags framework check_macros build: @${ECHOE} ${GREEN}Build [$@] ${NC} @@ -110,3 +115,8 @@ cleanall: check_macros: @echo "Running macro usage check..." @$(PYTHON_SCRIPT) $(HEADER_FILE) $(USAGE_FILE) + +# Target to check the build files for mistyped or missing compiler flags +check_makefile_flags: + @echo "Running makefile flag check..." + @$(FLAGS_SCRIPT) $(ROOT_DIR)/.. --make-arg TARGET=$(TARGET) --make-arg VARIANT=$(VARIANT) $(EXPECTED_FLAGS) diff --git a/tests/check_makefile_flags.py b/tests/check_makefile_flags.py new file mode 100755 index 0000000..267c927 --- /dev/null +++ b/tests/check_makefile_flags.py @@ -0,0 +1,223 @@ +#!/usr/bin/env python3 +# /* +# * If not stated otherwise in this file or this component's LICENSE file the +# * following copyright and licenses apply: +# * +# * Copyright 2023 RDK Management +# * +# * Licensed under the Apache License, Version 2.0 (the "License"); +# * you may not use this file except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.apache.org/licenses/LICENSE-2.0 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# */ + +"""Guard against mistyped compiler flags in the build files. + +Two checks, both static enough to run before anything is compiled: + + scan walk the build files looking for a lowercase `-o` immediately + followed by an optimisation level (`-o0`, `-os`, `-og`, ...). + Lowercase `-o` means "write output to this file", so `-o0` asks + for a file named `0` rather than setting optimisation. gcc accepts + it silently, and a later `-o $@` on the same command line wins, so + nothing ever fails - see ut-core issue #256 / ut-control issue #130. + + expect ask `make printenv` what a variable actually expands to and assert + the flags we intend are present. This catches the flag being + dropped or overwritten as well as mistyped. +""" + +import argparse +import os +import re +import subprocess +import sys + +# ANSI escape codes for colored output +RED = "\033[91m" +GREEN = "\033[92m" +YELLOW = "\033[93m" +RESET = "\033[0m" + +# Build files worth scanning: makefiles and the shell scripts that drive them. +SCANNED_NAMES = ("Makefile", "makefile", "GNUmakefile") +SCANNED_SUFFIXES = (".mk", ".sh") + +# Directories holding third party or generated content, not our build files. +SKIPPED_DIRS = {".git", "build", "framework", "sysroot", "cpp_libs", "node_modules"} + +# A lowercase -o glued directly to an optimisation level. The trailing lookahead +# keeps `-o3rdparty.o` and similar output filenames out of the results. +OPT_TYPO_PATTERN = re.compile(r"(? Date: Tue, 4 Aug 2026 17:37:39 +0100 Subject: [PATCH 3/3] test: consolidate tests/Makefile .PHONY into a single complete list The .PHONY declaration added alongside the compiler-flag check duplicated the one already present earlier in the file, and neither listed every recipe-only target. With 'framework', 'run', 'rebuild' and 'cleanall' missing, a stray file or directory of the same name made GNU make treat the target as up to date and skip the recipe entirely. Collapse both declarations into one covering all ten targets. --- tests/Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 4556c02..0cf659f 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -52,8 +52,6 @@ BUILD_DIR := $(ROOT_DIR)/build/${TARGET}/obj $(info TARGET [$(TARGET)]) -.PHONY: clean list all - # Here is a list of exports from this makefile to the next export BIN_DIR export SRC_DIRS @@ -69,7 +67,11 @@ export BUILD_WEAK_STUBS_SRC GREEN='\033[0;32m' NC='\033[0m' -.PHONY: clean list build all check_macros check_makefile_flags +# Every target in this makefile is recipe-only, so declare them all phony in one +# place: a stray file or directory sharing a target name must not stop the recipe +# from running. +.PHONY: all build run rebuild framework list clean cleanall \ + check_macros check_makefile_flags # check_makefile_flags runs first: it is static, and a flag typo is cheaper to # hear about now than after a full framework build