Search code examples
autotoolsautoconfautomake

autotools - Fix undefined reference to `pow' and `floor'


An undefined reference to pow or floor is often caused by a missing or misplaced -lm option (see this question).

I saw this error in an open source repository after running through the autotools workflow: aclocal autoconf automake --add-missing ./configure make.

Here is the offending build command from the make output:

gcc -pthread -g -O2 -lm  -o 01_w_Defects bit_shift.o main.o buffer_overrun_dynamic.o memory_allocation_failure.o buffer_underrun_dynamic.o memory_leak.o cmp_funcadr.o not_return.o conflicting_cond.o null_pointer.o data_lost.o overrun_st.o data_overflow.o ow_memcpy.o data_underflow.o pow_related_errors.o dead_code.o ptr_subtraction.o dead_lock.o race_condition.o deletion_of_data_structure_sentinel.o redundant_cond.o double_free.o return_local.o double_lock.o sign_conv.o double_release.o sleep_lock.o endless_loop.o st_cross_thread_access.o free_nondynamic_allocated_memory.o st_overflow.o free_null_pointer.o stubs.o func_pointer.o st_underrun.o function_return_value_unchecked.o underrun_st.o improper_termination_of_block.o uninit_memory_access.o insign_code.o uninit_pointer.o invalid_extern_1.o uninit_var.o invalid_extern.o unlock_without_lock.o invalid_memory_access.o unused_var.o littlemem_st.o wrong_arguments_func_pointer.o livelock.o zero_division.o lock_never_unlock.o

As you can see, -lm comes before all of the files in the build command. It should come at the end. If I move -lm to the end and re-run the command, it works.

But this doesn't fix the root problem. What went wrong? Where should I look to find the issue or a potential fix? I imagine this issue could be fixed in either Makefile.am or configure.ac.


Solution

  • You're passing -lm as an LDFLAGS entry; it is not, it's instead a LIBS entry. The easy way to fix this is to avoid referencing -lm in Makefile.am at all and instead add to your configure.ac:

    AC_SEARCH_LIBS([pow], [m])
    

    This way if pow is defined in the C library (rare but there are a few OSes where that happens) nothing will be added to LIBS whereas if it is defined in libm, LIBS will be set to -lm; since LIBS is passed after the list of files, the linking will work.

    Further reference (written by me in the past): Finding Libraries on Autotools Mythbuster, --as-needed and linking order.