Hello Everybody,
I am trying to build a firmware which is using two functions from the Keil SAM-ESV7_SFP 2.4.5 library. The compile process is okay, but I can not get the linking going.
*** Using Compiler 'V5.06 update 6 (build 750)', folder: 'C:\Keil_v5\ARM\ARMCC\Bin' Build target 'Target' compiling afe_dma.c... linking... .\Objects\Target.axf: Error: L6218E: Undefined symbol Afe_SendData(AfeDma*, AfeCmd*) (referred from receiver.o). .\Objects\Target.axf: Error: L6218E: Undefined symbol Afe_ConfigureDma(AfeDma*, Afec*, unsigned char, _Xdmad*) (referred from receiver.o). Not enough information to list image symbols. Not enough information to list load addresses in the image map. Finished: 2 information, 0 warning and 2 error messages. ".\Objects\Target.axf" - 2 Error(s), 0 Warning(s). Target not created. Build Time Elapsed: 00:00:01
Now the weird part: The two functions Afe_SendData and Afe_ConfigureDma is defined in the afe_dma.c which gets compiled succesfully. The afe_dma.o gets generated in the Objects subfolder.
I have tried to remove the afe_dma.c from the sources and I got the same exact error as I should, but when I put it back, the file gets compiled, but the error stays.
I have tried to clean and rebuild the project several times. There are no weird characters in the paths of the project, Keil tools or the include paths.
Why the linker does not recognize the the compiled afe_dma.o? Is there a way to explicitly tell the linker to link a specific *.o file?
Thank you very much.
The original error message rather strongly indicates that our problem is with mixing C and C++ code: receiver.o was built by the C++ compiler, whereas afe_dma.o was built by the C compiler.
Note how the error message refers not only to the name of the purportedly missing functions, but also their argument types? Well, if "receiver.o" had been a C source module, the linker would not know the argument types. Only C++ compilers mangle those into the names of functions as presented to the linker, because they need that extra information for argument type-based function/operator overloading.
You have two main possibilities at this point: make sure all modules are compiled as the same language (either all C++, or all C), or use the mechanisms provided by C++ to mark declarations as belonging to C objects.
Yes, my Receiver.c was set to C++ file type, I do not remember setting that, probably misclicked something. This is a silly mistake from my part, which I have never encountered before. The code is working now.
Thank both of you very much for your help, and I sorry that I robbed your valuable time.
No worries, C++ / .CPP induced name mangling catches a lot of people out, glad it is resolved.