I'm trying to use complex.h
and math.h
in my embedded stm32f4 microcontroller code. Considering below sample code:
#include <math.h>
#include <complex.h>
#define PI 3.141593f
void sample_function(uint8_t s) {
float t = (float)1 / s;
float complex var1 = cexpf(2 * PI * I * t); // linker error undefined reference to cexpf
float complex var2 = cexpf(2 * PI * I); // this works
// print creal and cimag parts of var1 and var2
}
the code compiles but I get the linker error for undefined reference to cexpf
. But passing arguments known at compile time (such as PI
and const numbers) to cexpf
, gives no errors. This is the case for sinf
and cosf
functions also.
Linker options in CmakeLists.txt
:
target_link_options(${APPLICATION} PRIVATE
-T${APP_LINKER_SCRIPT}
${CPU_PARAMETERS}
-Wl,-Map=${APPLICATION}.map
-Wl,--start-group
-Wl,--no-warn-rwx-segments
-lc
-lm
# -lnosys
-lstdc++
-Wl,--end-group
-Wl,--print-memory-usage)
And output of arm-none-eabi-gcc -v
command:
$ arm-none-eabi-gcc -v
Using built-in specs.
COLLECT_GCC=arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-none-eabi/13.2.0/lto-wrapper
Target: arm-none-eabi
Configured with: /build/arm-none-eabi-gcc/src/gcc-13.2.0/configure --target=arm-none-eabi --prefix=/usr --with-sysroot=/usr/arm-none-eabi --with-native-system-header-dir=/include --libexecdir=/usr/lib --enable-languages=c,c++ --enable-plugins --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-system-zlib --with-newlib --with-headers=/usr/arm-none-eabi/include --with-python-dir=share/gcc-arm-none-eabi --with-gmp --with-mpfr --with-mpc --with-isl --with-libelf --enable-gnu-indirect-function --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-pkgversion='Arch Repository' --with-bugurl=https://bugs.archlinux.org/ --with-multilib-list=rmprofile
Thread model: single
Supported LTO compression algorithms: zlib zstd
gcc version 13.2.0 (Arch Repository)
Also in case of compiling and linking the code without var1
, the result of arm-none-eabi-readelf -a path/to/application.elf | grep "libmath"
is empty.
Does anyone know how should I resolve this?
Ok, after some searching I figured it out. The error could be resolved by adding the
-lm
flag after the object files. But as explained here thetarget_link_options
command sets the options before everything else and I should have usedtarget_link_libraries
command for that purpose. So the line below adds the link to math library after all object files.