Undefined Reference When Compling

I’m trying to setup a basic project for use on an ESP32 following the Guide For CMake in the AWS Docs

cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=freertos/tools/cmake/toolchains/xtensa-esp32.cmake -GNinja executes fine, but when I try to execute cmake --build build I get the following output:

[796/797] Linking CXX executable my_app
FAILED: my_app
cmd.exe /C "cd . && C:\xtensa-esp32-elf\bin\xtensa-esp32-elf-g++.exe  -mlongcalls  -nostdlib   -Wl,--gc-sections -Wl,--cref -Wl,--Map=aws_demos.map -Wl,--undefined=uxTopUsedPriority @CMakeFiles\my_app.rsp  -o my_app  && cd ."
freertos/esp-idf/freertos/libfreertos.a(tasks.c.obj):(.literal.xTaskIncrementTick+0x18): undefined reference to `vApplicationTickHook'
freertos/esp-idf/freertos/libfreertos.a(tasks.c.obj):(.literal.vTaskStartScheduler+0x14): undefined reference to `vApplicationGetIdleTaskMemory'
freertos/esp-idf/freertos/libfreertos.a(tasks.c.obj):(.literal.prvIdleTask+0x0): undefined reference to `vApplicationIdleHook'
freertos/esp-idf/freertos/libfreertos.a(tasks.c.obj): In function `xTaskIncrementTick':
D:\Documents\GitRepos\kraken-esp\build/../freertos/freertos_kernel/tasks.c:5162: undefined reference to `vApplicationTickHook'
D:\Documents\GitRepos\kraken-esp\build/../freertos/freertos_kernel/tasks.c:5162: undefined reference to `vApplicationTickHook'
freertos/esp-idf/freertos/libfreertos.a(tasks.c.obj): In function `vTaskStartScheduler':
D:\Documents\GitRepos\kraken-esp\build/../freertos/freertos_kernel/tasks.c:5162: undefined reference to `vApplicationGetIdleTaskMemory'
freertos/esp-idf/freertos/libfreertos.a(tasks.c.obj): In function `prvIdleTask':
D:\Documents\GitRepos\kraken-esp\build/../freertos/freertos_kernel/tasks.c:5162: undefined reference to `vApplicationIdleHook'
freertos/esp-idf/freertos/libfreertos.a(timers.c.obj):(.literal.xTimerCreateTimerTask+0x18): undefined reference to `vApplicationGetTimerTaskMemory'
freertos/esp-idf/freertos/libfreertos.a(timers.c.obj):(.literal.prvTimerTask+0x0): undefined reference to `vApplicationDaemonTaskStartupHook'
freertos/esp-idf/freertos/libfreertos.a(timers.c.obj): In function `xTimerCreateTimerTask':
D:\Documents\GitRepos\kraken-esp\build/../freertos/freertos_kernel/timers.c:344: undefined reference to `vApplicationGetTimerTaskMemory'
freertos/esp-idf/freertos/libfreertos.a(timers.c.obj): In function `prvTimerTask':
D:\Documents\GitRepos\kraken-esp\build/../freertos/freertos_kernel/timers.c:741: undefined reference to `vApplicationDaemonTaskStartupHook'
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

Any way I can fix this?

I would have a look at the following repo made by an AWS employee. I think you’re just missing some function definitions in your main.c.

I used this repo to start my custom project and it worked great for me! Just make sure to download all submodules when you clone the repo. I hope this fixes the issue you have.

1 Like

Any function that starts ‘Application’ is a callback function that the user (application writer) must provide themselves. You need to either disable the callback in FreeRTOSConfig.h, or provide an implementation of the callback. More information here: https://www.freertos.org/a00016.html

1 Like

Thanks very much! This is exactly what I needed

1 Like

Cheers, extremely new to using FreeRTOS so thanks for your help

Hey Joe, what did you do to solve this problem? I went through the GitHub instructions but can’t seem to figure out what exactly to add in my CMakeList or main.c to make the errors go away. I am getting the exactly same errors as you. undefined references in tasks.c and timers.c. My target board is ESP32 DevKitC.

[776/777] Linking CXX executable blink
FAILED: blink
cmd.exe /C "cd . && C:\PROGRA~1\ESPRES~1\ESP-ID~1\tools\bin\XT1FE9~1.EXE -mlongcalls -nostdlib   -Wl,--gc-sections -Wl,--cref -Wl,--Map=aws_demos.map -Wl,--undefined=uxTopUsedPriority @CMakeFiles\blink.rsp -o blink  && cd ."
FreeRTOS/esp-idf/esp32/libesp32.a(cpu_start.c.obj):(.literal.main_task+0x0): undefined reference to `app_main'
FreeRTOS/esp-idf/esp32/libesp32.a(cpu_start.c.obj): In function `main_task':
E:\EmbeddedWorkspace\ESP32\projects\blink\build/../FreeRTOS/vendors/espressif/esp-idf/components/esp32/cpu_start.c:544: undefined reference to `app_main'
FreeRTOS/esp-idf/freertos/libfreertos.a(tasks.c.obj):(.literal.xTaskIncrementTick+0x18): undefined reference to `vApplicationTickHook'
FreeRTOS/esp-idf/freertos/libfreertos.a(tasks.c.obj):(.literal.vTaskStartScheduler+0x14): undefined reference to `vApplicationGetIdleTaskMemory'
FreeRTOS/esp-idf/freertos/libfreertos.a(tasks.c.obj):(.literal.prvIdleTask+0x0): undefined reference to `vApplicationIdleHook'
FreeRTOS/esp-idf/freertos/libfreertos.a(tasks.c.obj): In function `xTaskIncrementTick':
E:\EmbeddedWorkspace\ESP32\projects\blink\build/../FreeRTOS/freertos_kernel/tasks.c:5162: undefined reference to `vApplicationTickHook'
E:\EmbeddedWorkspace\ESP32\projects\blink\build/../FreeRTOS/freertos_kernel/tasks.c:5162: undefined reference to `vApplicationTickHook'
FreeRTOS/esp-idf/freertos/libfreertos.a(tasks.c.obj): In function `vTaskStartScheduler':
E:\EmbeddedWorkspace\ESP32\projects\blink\build/../FreeRTOS/freertos_kernel/tasks.c:5162: undefined reference to `vApplicationGetIdleTaskMemory'
FreeRTOS/esp-idf/freertos/libfreertos.a(tasks.c.obj): In function `prvIdleTask':
E:\EmbeddedWorkspace\ESP32\projects\blink\build/../FreeRTOS/freertos_kernel/tasks.c:5162: undefined reference to `vApplicationIdleHook'
FreeRTOS/esp-idf/freertos/libfreertos.a(timers.c.obj):(.literal.xTimerCreateTimerTask+0x18): undefined reference to `vApplicationGetTimerTaskMemory'
FreeRTOS/esp-idf/freertos/libfreertos.a(timers.c.obj):(.literal.prvTimerTask+0x0): undefined reference to `vApplicationDaemonTaskStartupHook'
FreeRTOS/esp-idf/freertos/libfreertos.a(timers.c.obj): In function `xTimerCreateTimerTask':
E:\EmbeddedWorkspace\ESP32\projects\blink\build/../FreeRTOS/freertos_kernel/timers.c:344: undefined reference to `vApplicationGetTimerTaskMemory'
FreeRTOS/esp-idf/freertos/libfreertos.a(timers.c.obj): In function `prvTimerTask':
E:\EmbeddedWorkspace\ESP32\projects\blink\build/../FreeRTOS/freertos_kernel/timers.c:741: undefined reference to `vApplicationDaemonTaskStartupHook'
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

Thanks

Send over your CMakeLists and I’ll check it against mine

Hi, here’s what I have in my main (outermost) CMakeList

# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)

#include($ENV{IDF_PATH}/tools/cmake/project.cmake)

project(blink)

add_executable(blink main/blink.c)

# Tell IDF build to link against this target.
set(IDF_PROJECT_EXECUTABLE blink)

# Add some extra components. IDF_EXTRA_COMPONENT_DIRS is a variable used by ESP-IDF
# to collect extra components.
get_filename_component(
    EXTRA_COMPONENT_DIRS
    "FreeRTOS/freertos_kernel" ABSOLUTE
)
list(APPEND IDF_EXTRA_COMPONENT_DIRS ${EXTRA_COMPONENT_DIRS})

# Add FreeRTOS as a subdirectory. AFR_BOARD tells which board to target.
set(AFR_BOARD espressif.esp32_devkitc CACHE INTERNAL "")
add_subdirectory(FreeRTOS)

# Link against the mqtt library so that we can use it. Dependencies are transitively
# linked.
#target_link_libraries(blink PRIVATE AFR::freertos)
#target_link_libraries(blink kernel)
#target_link_libraries(blink AFR::mqtt)
#target_link_libraries(blink PRIVATE AFR::kernel::mcu_port)

I added freertos_kernel folder as an extra component by following the “component/foo” example. And I have commented the linked libraries out as they didn’t eliminate the errors.

Also, my project structure is like this:

  • build
  • freertos
  • main
    • blink.c
    • CMakeLists.txt
  • CMakeLists.txt

Any function that starts “Application” is a callback it is expected the application code to provide. To clear the warning either turn that feature off in FreeRTOSConfig.h, or provide an implementation of the callback function. If you google each such function you will find instructions on how to do either option.

Yes I tried that Richard, it didn’t work. Also, it also gives error for features that are already OFF in the config header. Its a linking error as mentioned in the github readme, but I do not know what module/component to link. Maybe you can help with that?

Here’s what it states:

### Linker Error: undefined reference to <some_function>

If you changed some configuration and run into this, usually it's because of 
missing dependent libraries/demos. To fix it, first find out which CMake target 
the missing functions belong to, normally it should be in the `CMakeLists.txt`
closest to the source file where the functions are defined. Then add the CMake
target to your application dependency list using the `target_link_libraries`
command in the root level `CMakeLists.txt` . For example,

1. Linker complains about `undefined reference to NumericComparisonInit` .
2. `NumericComparisonInit` is defined in `amazon-freertos/demos/ble/iot_ble_numericComparison.c` .
3. `amazon-freertos/demos/ble/CMakeLists.txt` defines the target `ble_numeric_comparison`
which has this source file.
4. Link `AFR::demo_ble_numeric_comparison` target with `target_link_libraries`
to your application target. ( `demo_` prefix is added because it's a demo module,
all target names can be found in the summary of CMake output)

The root cause problem is an improper FreeRTOS configuration as Richard already pointed out.
E.g. the linker complains about missing vApplicationTickHook definition because in your FreeRTOSConfig.h configUSE_TICK_HOOK is set to 1 and as documented you’ve to provide/defined a function vApplicationTickHook.
If you don’t want that hook set configUSE_TICK_HOOK is set to 0.
This applies to all the undefined references to those Application hooks.
Double check that you include the right (there should be only one) FreeRTOSConfig.h file and it’s contents. That should solve the issue.
The missing reference to app_main in your 2nd build log is a different story. That’s up to you to provide this function or add the source file where it’s defined to your CMakeLists.

I’m also having the same problems as somethingiot where I have “undefined references” to;

app_main
vApplicationTickHook
vApplicationIdleHook
vApplicationDaemonTaskStartupHook

And yes I have these defined in my code, where the last 3 were “cut and pasted” from the FreeRTOS libary into my code as;
//-----------------------------------------------------------/

extern void esp_vApplicationTickHook();
void IRAM_ATTR vApplicationTickHook()
{
esp_vApplicationTickHook();
}

//-----------------------------------------------------------/
extern void esp_vApplicationIdleHook();
void vApplicationIdleHook()
{
esp_vApplicationIdleHook();
}

//-----------------------------------------------------------/

void vApplicationDaemonTaskStartupHook( void )
{
}

Also as mentioned above, in the FreeRTOSConfig.h file mentioned above, the "configUSE_TICK_HOOK is defined as:

#define configUSE_TICK_HOOK ( CONFIG_FREERTOS_LEGACY_TICK_HOOK )

So what do I need to fix or check?

Any help would greatly be appreciated!

Tom

Did/can you verify that the source module containing the definitions of the hooks is compiled and linked i.e. the CMakelists are correct ?
If this is the case is this source module compiled as C or as C++ file ?
If it’s C++ you need to extern C (demangle) the hook functions.
I can’t say much about the missing app_main symbol. It might also be demangle problem or not …
Usually compilers use C++ for files with ‘cpp’ extension and ‘C’ for ‘c’.
However, this can be forced or overridden by dedicated compiler flags.

I changed my main.cpp file to main.c and the “undefined references” went away, including for “app_main”.

Thank you!

Tom

OK, I spoke to soon.

For my application I need to “link in” a library that has both c and cpp files, but I’m still getting “undefined reference” errors on both c and cpp functions. The “.h” files for the c files have the “#ifdef __cplusplus extern “C” {” before the declarations and the compiler appears to be able to “find” the .h files.

So any input on what I should check next or what I may be doing wrong?

Tom

I guess the source files were not properly added to your CMake files. Either they are not even compiled (are the corresponding object files being built ?) or they’re not properly added to your target dependencies (also configuring the linker command including the list of object files).
I afraid you’ve to debug your CMake files and/or check the CMake generated (make)files to see what’s going wrong.
If unsure about the correct symbols in compiled object files you can use ‚objdump‘ binutil (part of GNU toolchain) to check its contents.