j123b567 / scpi-parser

Open Source SCPI device library
BSD 2-Clause "Simplified" License
463 stars 194 forks source link

arm cross-compilation requires additional flags #141

Closed MisterHW closed 1 year ago

MisterHW commented 1 year ago

To be able to compile the static library using the Arm GNU Toolchain, its particular tools must be used.

Subsequently, the appropriate ‘-m’ options need to be set to compile libscpi, otherwise an

xxx.elf uses VFP register arguments, libscpi.a does not

error is encountered when linking in one's own project, as hard or soft floats must be used consistently.

However, "Passing variables on the command line overrides assignments in the sub-makefile but exported variables do not override assignments in the sub-makefile." (source) So it seems it is not possible to simply pass CFLAGS in the command line, and one is not supposed to export CFLAGS directly.

Option 1: Modify libscpi/Makefile, Export Options

In libscpi/Makefile:

CFLAGS += $(MODE) -Wextra -Wmissing-prototypes -Wimplicit -Iinc

In one's own project directory, an additional makefile is created or amended, containing:

# cpu
CPU = -mcpu=cortex-m7

# fpu
FPU = -mfpu=fpv5-sp-d16

# float-abi
FLOAT-ABI = -mfloat-abi=hard

# -m options
MODE= $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
export MODE

# ...
libscpi:
    make -C Middlewares/Third_Party/libscpi static

Option 2: Modify libscpi/Makefile, Pass Variable In Command Line

In libscpi/Makefile:

CFLAGS += $(MODE) -Wextra -Wmissing-prototypes -Wimplicit -Iinc

CLion Example

Under Run > Edit Configurations ..., click + to 'Add New Configuration' and select Makefile Target (see makefiles-support).

The following fields need to be set, and that is where MODE is introduced:

Makefile $PROJECT_DIR$/Third_Party/scpi-parser/libscpi/Makefile
Targets clean static
Arguments CC=arm-none-eabi-gcc AR=arm-none-eabi-ar MODE="-mcpu=cortex-m7 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard"
WorkingDirectory $PROJECT_DIR$/Third_Party/scpi-parser/libscpi

grafik

Hint : you'll also need to specify the path to make.

Unlike Makefile Applications, Makefile Target configurations use the path to make from Settings | Build, Execution, Deployment | Build Tools | Make regardless of the currently selected toolchain. (e.g. path\to\mingw64\bin\mingw32-make.exe).

Proposed Changes

Introduce variable as per https://github.com/MisterHW/scpi-parser/commit/c394eb954fe1ede45c9372e795b4705f9c7e25c9 . Compatibility: If MODE doesn't exist, it will be ignored.

Allow makefile to be used directly for cross-compiling (e.g. when treated as a git submodule). 
This requires CC and AR to be passed for a particular toolchain, but CFLAGS must 
also specify CPU and FPU options -> introduce MODE variable. CFLAGS cannot be passed 
without need to override in the makefile, so a new variable is needed.
j123b567 commented 1 year ago

But there is still no need for nonstandard MODE to be part of the libscpi. You can just pass the MODE content to the CFLAGS and LDFLAGS as needed.

CFLAGS="$(MODE)" LDFLAGS="$(MODE)" make
MisterHW commented 1 year ago

I tried the following:

# cpu
CPU = -mcpu=cortex-m7
# fpu
FPU = -mfpu=fpv5-sp-d16
# float-abi
FLOAT-ABI = -mfloat-abi=hard
# -m options
MODE= $(CPU) -mthumb $(FPU) $(FLOAT-ABI)

clean:
  make -C libscpi clean
scpi:
  CC="arm-none-eabi-gcc" AR="arm-none-eabi-ar" CFLAGS="$(MODE)" make -C libscpi static

Which appears to be working. This eliminates Option 1. Unfortunately, I don't see how that would translate to the CLion Makefile Target setup. It may not be possible at all.

Closing for now. Feel free to suggest what should happen to the associated commit.