Description / Steps to reproduce the issue
Description / Steps to reproduce the issue
CONFIG_PIC does not appear to be wired up correctly in the CMake build. I
found three related problems while comparing it against the Makefile build, and
I am raising them together because fixing any one of them in isolation looks
wrong without a decision on the others. I have a one-line change for the first,
but it is not obviously the right thing to do on its own — hence an issue rather
than a PR.
1. ELF applications get two contradictory flags for the same register
arch/arm/src/cmake/elf.cmake:30:
nuttx_elf_compile_options_ifdef(CONFIG_PIC --fixed-r10 -mpic-register=r10)
These say opposite things about r10. -mpic-register=r10 tells the compiler
r10 holds the module's data base; --fixed-r10 tells it r10 is unavailable.
GCC rejects the combination outright once -fpic is in effect:
$ arm-none-eabi-gcc -mcpu=cortex-m55 -mthumb -fpic -msingle-pic-base \
--fixed-r10 -mpic-register=r10 -c t.c -o t.o
cc1: error: unable to use 'r10' for PIC register
It is not currently fatal only because of problem 2 below — without -fpic the
same pair merely warns:
$ arm-none-eabi-gcc -mcpu=cortex-m55 -mthumb --fixed-r10 -mpic-register=r10 \
-c t.c -o t.o
cc1: warning: '-mpic-register=' is useless without '-fpic'
The Makefile build keeps the two apart deliberately: it puts --fixed-r10 in
CFLAGS (base firmware) and filters it back out of CPICFLAGS/CELFFLAGS
(modules). The CMake build applies both to the module side.
To reproduce, on master:
$ cmake -B build -DBOARD_CONFIG=mps3-an547:picostest -GNinja \
-DCMAKE_EXPORT_COMPILE_COMMANDS=1
$ grep -o -- "--fixed-r10 [^ ]*" build/compile_commands.json | head -1
--fixed-r10 -mpic-register=r10
$ ninja arch/arm/src/common/CMakeFiles/STARTUP_OBJS.dir/crt0.c.o
[1/1] Building C object arch/arm/src/common/CMakeFiles/STARTUP_OBJS.dir/crt0.c.o
cc1: warning: '-mpic-register=' is useless without '-fpic'
(mps3-an547:picostest is the only defconfig in the tree with CONFIG_PIC=y.)
2. ELF applications are not built position-independent at all
The warning above is the symptom: nothing gives these targets -fpic under
CONFIG_PIC. In the CMake build PICFLAGS is applied only under
CONFIG_BUILD_PIC (arch/arm/src/cmake/gcc.cmake:243-248), which is a
different feature — a position-independent kernel, using r9.
The Makefile build does give them -fpic, via
CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
where ARCHPICFLAGS is -fpic -msingle-pic-base -mpic-register=r10. So the
two build systems disagree about whether a CONFIG_PIC ELF application is
position-independent, and the CMake side looks incomplete rather than
deliberately different.
3. The base firmware never reserves r10
CONFIG_PIC appears in exactly two places in the whole CMake build, both in
elf.cmake, both on the module side:
$ grep -rn "CONFIG_PIC" --include="*.cmake" --include="CMakeLists.txt" . \
| grep -v BUILD_PIC
arch/arm/src/cmake/elf.cmake:30:nuttx_elf_compile_options_ifdef(CONFIG_PIC --fixed-r10 -mpic-register=r10)
arch/arm/src/cmake/elf.cmake:33: CONFIG_PIC --unresolved-symbols=ignore-in-object-files --emit-relocs)
Nothing adds --fixed-r10 to the base firmware, so the firmware is free to
allocate r10 — the register a PIC module reaches its own data through. A base
firmware routine that calls back into module code (qsort() with a module
comparison function is the standard case) then arrives with a bad data base.
That is the same defect the Makefile side has, which I have raised separately
in the PR "arch/arm: stop boards silently discarding --fixed-r10".
Why I have not simply sent a patch
Removing --fixed-r10 from elf.cmake:30 is a one-liner and I have it ready.
On its own, though:
- it fixes no observable failure, because problem 2 keeps the error latent;
- it does not silence the warning, which comes from the
-mpic-register=r10
that remains (verified by building crt0.c with the change applied);
- it leaves problem 3 — the defect that actually corrupts a callback —
untouched.
Fixing problem 3 centrally is also not a one-liner. The obvious approach,
add_compile_options(--fixed-r10) under CONFIG_PIC, does not work: directory
scoped options reach the ELF application targets too, recreating exactly the
rejected combination from problem 1. I confirmed that scoping behaviour with a
minimal CMake project — a directory-level option appears on a target that also
carries its own target_compile_options. Doing it properly needs either a
kernel-scoped option list (the tree has NUTTX_ELF_APP_COMPILE_OPTIONS and
NUTTX_MOD_APP_COMPILE_OPTIONS, but no firmware-only equivalent) or a generator
expression keyed on a per-target marker property.
So the real question is what CONFIG_PIC is intended to mean in the CMake
build, which someone who knows that design should answer before flags are moved
around. I am happy to write the patch once there is a direction.
On which OS does this issue occur?
[OS: Mac]
What is the version of your OS?
26.5.1 (Darwin 25.5.0, arm64)
NuttX Version
master (7df7c6ee)
Issue Architecture
[Arch: arm]
Issue Area
[Area: Build System]
Host information
macOS 26.5.1 (Darwin 25.5.0, arm64)
cmake 4.3.4, ninja 1.13.1
Arm GNU Toolchain 15.2.Rel1 (arm-none-eabi-gcc 15.2.1)
Verification
Description / Steps to reproduce the issue
Description / Steps to reproduce the issue
CONFIG_PICdoes not appear to be wired up correctly in the CMake build. Ifound three related problems while comparing it against the Makefile build, and
I am raising them together because fixing any one of them in isolation looks
wrong without a decision on the others. I have a one-line change for the first,
but it is not obviously the right thing to do on its own — hence an issue rather
than a PR.
1. ELF applications get two contradictory flags for the same register
arch/arm/src/cmake/elf.cmake:30:These say opposite things about r10.
-mpic-register=r10tells the compilerr10 holds the module's data base;
--fixed-r10tells it r10 is unavailable.GCC rejects the combination outright once
-fpicis in effect:It is not currently fatal only because of problem 2 below — without
-fpicthesame pair merely warns:
The Makefile build keeps the two apart deliberately: it puts
--fixed-r10inCFLAGS(base firmware) and filters it back out ofCPICFLAGS/CELFFLAGS(modules). The CMake build applies both to the module side.
To reproduce, on
master:(
mps3-an547:picostestis the only defconfig in the tree withCONFIG_PIC=y.)2. ELF applications are not built position-independent at all
The warning above is the symptom: nothing gives these targets
-fpicunderCONFIG_PIC. In the CMake buildPICFLAGSis applied only underCONFIG_BUILD_PIC(arch/arm/src/cmake/gcc.cmake:243-248), which is adifferent feature — a position-independent kernel, using r9.
The Makefile build does give them
-fpic, viawhere
ARCHPICFLAGSis-fpic -msingle-pic-base -mpic-register=r10. So thetwo build systems disagree about whether a
CONFIG_PICELF application isposition-independent, and the CMake side looks incomplete rather than
deliberately different.
3. The base firmware never reserves r10
CONFIG_PICappears in exactly two places in the whole CMake build, both inelf.cmake, both on the module side:Nothing adds
--fixed-r10to the base firmware, so the firmware is free toallocate r10 — the register a PIC module reaches its own data through. A base
firmware routine that calls back into module code (
qsort()with a modulecomparison function is the standard case) then arrives with a bad data base.
That is the same defect the Makefile side has, which I have raised separately
in the PR "arch/arm: stop boards silently discarding --fixed-r10".
Why I have not simply sent a patch
Removing
--fixed-r10fromelf.cmake:30is a one-liner and I have it ready.On its own, though:
-mpic-register=r10that remains (verified by building
crt0.cwith the change applied);untouched.
Fixing problem 3 centrally is also not a one-liner. The obvious approach,
add_compile_options(--fixed-r10)underCONFIG_PIC, does not work: directoryscoped options reach the ELF application targets too, recreating exactly the
rejected combination from problem 1. I confirmed that scoping behaviour with a
minimal CMake project — a directory-level option appears on a target that also
carries its own
target_compile_options. Doing it properly needs either akernel-scoped option list (the tree has
NUTTX_ELF_APP_COMPILE_OPTIONSandNUTTX_MOD_APP_COMPILE_OPTIONS, but no firmware-only equivalent) or a generatorexpression keyed on a per-target marker property.
So the real question is what
CONFIG_PICis intended to mean in the CMakebuild, which someone who knows that design should answer before flags are moved
around. I am happy to write the patch once there is a direction.
On which OS does this issue occur?
[OS: Mac]
What is the version of your OS?
26.5.1 (Darwin 25.5.0, arm64)
NuttX Version
master (
7df7c6ee)Issue Architecture
[Arch: arm]
Issue Area
[Area: Build System]
Host information
Verification