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
-lmflag after the object files. But as explained here thetarget_link_optionscommand sets the options before everything else and I should have usedtarget_link_librariescommand for that purpose. So the line below adds the link to math library after all object files.