I am developing a static library for a client, to be used on a Cortex M4F processor. As a test platform, I am using a Texas Instruments Tiva C series board. When trying to link an executable against this library, I am getting the error ...project0.axf ...uses VFP register arguments, ../../libsleep.a(setters_getters.o) does not. but none of the past solutions I have found are working.
- I read this question and its answers, which was helpful, but ultimately didn't solved my issue. It did inspire the next bullet point:
- I have copy-pasted the
gccflags for my library compiling step from the executable make file to make sure they are the same. - I have verified that I am using the same ARM GNU Toolchain compiler (same executable),
arm-none-eabi-gcc, when making the library and the executable. I am also usingarm-none-eabi-gcc-arfrom that toolchain to make the static library.
So far, I have confirmed that I can compile an executable for my laptop which links against my static library (compiled for my laptop, of course) just to check there's not some error in the library code.
I am now trying to modify TI's project0 in their TivaWare SDK to simply call some functions from this library as part of the loop that blink the lights. Before modifying this, I confirmed that I can make this executable (as TI ships it) and flash it to the Tiva board. Once I add the function calls and modify the Makefile to add the .a, it no longer builds. (Check the end of this post for the error messages I get from make.
Past questions pointed me towards the importance of setting -mfloat-abi= the same when compiling the library and the executable. Looking at the TivaWare makedefs file, which ultimately configures these flags, I copy and pasted them into the script I use to build the library. FWIW, both steps are using -mfloat-abi=hard.
Just to sanity check myself, I also tried compiling the library with -mfloat-abi=soft and =softp just to verify I wasn't confused about the error and getting it backwards.
Here are the two steps I ultimately use to build my library; the gcc args after the -Is are copy-pasted out of TI's makefile, trying to make sure those are exactly the same.
STATIC_LIB_NAME="libsleep.a"
for file in $(ls src/lib/*.c)
do
# replace .../some_file.c with .../some_file.o
out_file="$OBJECT_DEST"/"$(echo "$file" | cut -d '.' -f 1 | cut -d '/' -f 3).o"
arm-none-eabi-gcc -Isrc/include/ -Isrc \
-mcpu=cortex-m4 -mthumb \
-mfpu=fpv4-sp-d16 -mfloat-abi=hard \
-Dgcc \
-Os \
-ffunction-sections \
-fdata-sections \
-MD \
-std=c99 \
-Wall \
-pedantic \
-DPART_${PART} \
-DTARGET_IS_TM4C129_RA1 \
-c $file -o $out_file
done
arm-none-eabi-gcc-ar rcs "$STATIC_LIB_DEST"/"$STATIC_LIB_NAME" "$OBJECT_DEST"/*.o
For copyright reasons, I cannot share TI's makefile, but the only line I modified was adding a step to the build rule for the .axf file on project0:
${COMPILER}/project0.axf: ${STATIC_LIB_DIR}/libsleep.a
Running make in that directory gives me an error like the following for each .o file in libsleep.a. update: Here, setters_getters.c is one of the source files compiled into setters_getters.o in the bash for loop above with -mfloat-abi=hard.
arm-none-eabi-ld: error: gcc/project0.axf uses VFP register arguments, ../../output/static/libsleep.a(setters_getters.o) does not
arm-none-eabi-ld: failed to merge target specific data of file ../../output/static/libsleep.a(setters_getters.o)
Just in case it's helpful, after the above error for each object file, I get a bunch of undefined reference errors, but I expect that's just related to the previous linking steps failing.
arm-none-eabi-ld: /path/to/arm-gnu-toolchain-12.2.mpacbti-rel1-darwin-arm64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libc.a(libc_a-sbrkr.o): in function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'