Topic : Undefined reference when linking

Forum : ARM

Original Post
Post Information Post
May 5, 2009 - 4:29pm
Guest

Hi.
I am working with Ride 7 ver. 7.18.0903 and Rkint-ARM for Ride 7 ver. 1.18.0903.

I have passed a program that works with another microprocessor to an STM32 microprocessor.
After compiling all the modules and libraries without error I found that some symbols defined in the libraries are not found by the linker.
To simplify the problem I have used the systick example and I have added a new module with only one function. I have called this function from the main module and I get the following linker error:

Running: LD
\"C:\Archivos de programa\Raisonance\Ride\arm-gcc\bin\arm-none-eabi-gcc.exe" -mcpu=cortex-m3 -mthumb -Wl,-T -Xlinker "C:\USERS\STM32\SysTick proves linker\obj\SysTick.elf.ld" -u _start -Wl,-static -Wl,--gc-sections -nostartfiles -Wl,-Map -Xlinker "C:\USERS\STM32\SysTick proves linker\lst\SysTick.map"
C:\USERS\STM32\SysTick proves linker\obj\main.o: In function `main':
C:\USERS\STM32\SysTick proves linker/main.c:79: undefined reference to `cc'
collect2: ld returned 1 exit status

cc is the name of the function that I call from main function.

Does anyone know how to solve the problem?

Best regards.
Francesc

Replies
Post Information Post
+1
+1
-1
May 6, 2009 - 11:53am
Raisonance Support Team

Hi,

I have received your project. Thanks.

The problem comes from the fact that the name of your file that contains the "cc" function is ended with '.C' instead of '.c'. GCC recognizes input file types according to the file name extension, and it is case-sensitive, and '.C' is for C++ while '.c' is for C. :/

I checked on your project that you just need to rename your file (or just the extension) in lower case and everything is fine.
Please search the GCC documentation if you need more information.

Best Regards,

Vincent

+1
0
-1
May 5, 2009 - 4:58pm
Raisonance Support Team

Hi,

If I understand correctly, you have made a library that includes a function called "cc", and then you make an application that uses this library...?

If yes, please confirm that you have added your library file in the final application (like if it was a source file) and that it is placed _after_ the main.c that calls it. The GCC linker ld's behavior differs depending on the order in which you place the input files, especially when there are libraries. This is normal and documented. As a general rule, place all libraries after all .c, .s and .o files. And if you have several libraries, you'll have to be careful at the order between them.

I hope it helps. If not, please send us (support@raisonance.com) some example projects that show the problem.

Best Regards,

Vincent

+1
0
-1
May 5, 2009 - 5:37pm
Guest

Hi.

Yes, you have understood well.
I have added the libraries after the source files, but there are some symbols that are not found.

Later, I have modified an Systick example, and I have got the same error including the function in a source module.

I will send this project to support.
Thanks.

Best regards

+1
0
-1
May 6, 2009 - 11:58am
Guest

Hi.
Thank you very much for the information.

I have made the change and it works.

Best regards

+1
0
-1
May 6, 2009 - 12:59pm
Guest

Hi.
Is there any other factor that can produce the unresolved external.

I have solved some unresolved external errors, but there are other unresolved that doesn't disappear. I have included in the project the library that contains the function, but the linker error remains.

The program contains many modules and libraries, so it would be very interesting to know how can I search the error cause.

Best regards.

+1
0
-1
May 6, 2009 - 4:01pm
Raisonance Support Team

Hi,

Have you checked the order in which the object files are placed in the libraries? This is important, as the linker analyzes them in this order and takes a file only if it allows to resolve an undefined symbol at the time the file is analyzed. And of course the order of the libraries between them is important.

There is an option called 'GROUP' in the linker script format that tells the linker to analyse a set of libraries again and again until no new symbol is resolved by this set of libraries. This is useful when two or more libraries call each other both ways, but it can also be used if you don't know which library calls which library. Of course for using this option you have to use a custom linker script...

I hope it helps.

Best Regards,

Vincent

+1
0
-1
May 8, 2009 - 9:07am
Guest

Hi.
I have tried to use an alternative script for the linker. In the linker options I have selected "Use Default script file: NO" and "Script File: Proves.elf.ld".
This script file is a copy of the script file generated by Ride7.

When I try to link, I get the following error:
Running: LD
\"C:\Archivos de programa\Raisonance\Ride\arm-gcc\bin\arm-none-eabi-gcc.exe" -mcpu=cortex-m3 -mthumb -Wl,-T -Xlinker "C:\USERS\STM32\Unref\obj\SysTick.elf.ld" -u _start -Wl,-static -Wl,--gc-sections -nostartfiles -Wl,-Map -Xlinker "C:\USERS\STM32\Unref\lst\SysTick.map"
c:/archivos de programa/raisonance/ride/arm-gcc/bin/../lib/gcc/arm-none-eabi/4.3.2/../../../../arm-none-eabi/bin/ld.exe: multiple STARTUP files
collect2: ld returned 1 exit status

Build failed

It seems that RIDE 7 calls LD using the Ride 7 normal script.

Is there any other option that I have to change to use my own script?

NOTE: FOR LARGE PROJECTS, IT WOULD BE INTERESTING THAT, AFTER FINISHING THE BUILD PROCESS, RIDE7 SUMMARIZES THE NUMBER OF ERRORS AND WARNING.
Most of development environments show this information .

Best regards

+1
0
-1
May 11, 2009 - 9:58am
Raisonance Support Team

Hi,

You should not have taken this ld file, as this is the one that contains the input files, and this one is always re-generated by Ride, even when you use the custom linker script. Here is what you should do:

1. Select 'default linker script" back.
2. Launch the link process once. (doesn't matter if it fails) Ride will generate the "Proves.elf.ld" file.
3. Open the "Proves.elf.ld" in an editor and search it for the "include" directive.
4. The file referenced in this directive is the one that you should reference in the "custom linker script" option.

I hope it helps.

Best Regards,

Vincent

+1
0
-1
May 11, 2009 - 10:37am
Guest

Hi.
Thanks for the information.

Now I understand that the link script generated by Ride 7 is used always, and that if we select that the linker script is not the default one, we can include a second linker script.

I was prepared to use the GROUP option to link the libraries, but first I have build my application with an empty additional linker script.

The result is that, in a project that game me a lot of undefined symbols, I get 0 errors.

Is it normal?

Best regards.
Francesc

+1
0
-1
May 11, 2009 - 10:50am
Guest

Hi again.

If I use an specific linker script (not default), and I put this file empty, the linker generates an empty code.
It's seems that it doesn't use the linker script generated by Ride7.

Here you can see how the linker is called.

Building C:\USERS\STM32\STM32Eval Crison\STM32Eval crison\project\RIDE\STM32Eval Crison.rapp
Running: LD
\"C:\Archivos de programa\Raisonance\Ride\arm-gcc\bin\arm-none-eabi-gcc.exe" -mcpu=cortex-m3 -mthumb -Wl,-T -Xlinker "C:\USERS\STM32\STM32Eval Crison\STM32Eval crison\project\RIDE\obj\STM32Eval Crison.elf.ld" -u _start -Wl,-static -Wl,--gc-sections -nostartfiles -Wl,-Map -Xlinker "C:\USERS\STM32\STM32Eval Crison\STM32Eval crison\project\RIDE\lst\STM32Eval Crison.map"
\"C:\Archivos de programa\Raisonance\Ride\arm-gcc\bin\arm-none-eabi-objcopy.exe" "C:\USERS\STM32\STM32Eval Crison\STM32Eval crison\project\RIDE\obj\STM32Eval Crison.elf" --target=ihex "C:\USERS\STM32\STM32Eval Crison\STM32Eval crison\project\RIDE\obj\STM32Eval Crison.hex"
\"C:\Archivos de programa\Raisonance\Ride\Bin\rexrdr.exe" "C:\USERS\STM32\STM32Eval Crison\STM32Eval crison\project\RIDE\obj\STM32Eval Crison.elf.sizetmp" 0 "C:\Archivos de programa\Raisonance\Ride\arm-gcc\bin\arm-none-eabi-size.exe" "C:\USERS\STM32\STM32Eval Crison\STM32Eval crison\project\RIDE\obj\STM32Eval Crison.elf"
\"C:\Archivos de programa\Raisonance\Ride\Bin\dwf2xml.exe" "C:\USERS\STM32\STM32Eval Crison\STM32Eval crison\project\RIDE\STM32Eval Crison.dbi" "C:\USERS\STM32\STM32Eval Crison\STM32Eval crison\project\RIDE\STM32Eval Crison-globals.Standard.xml" "C:\USERS\STM32\STM32Eval Crison\STM32Eval crison\project\RIDE\STM32Eval Crison.Standard.xml" ARM
DWF2XML 2.00.01 - Raisonance Dwarf information extractor
Copyright (c) Raisonance S.A.S. 2007-2009. All rights reserved.

+1
0
-1
May 11, 2009 - 11:33am
Raisonance Support Team

Hi,

It's a little more complex than this. You cannot link using a custom linker script that is empty, nor with no linker script at all.

By default Ride uses one linker script and four sub-scripts.
The first one is always generated by Ride, even when the 'Use Default Linker Script' option is cleared, and it only contains the input files that are referenced in the Ride project. The other ones can be replaced by your own version, but they must contain some information like memory spaces definitions, sections mapping, special function registers addresses, etc. that you should keep. So you must tell Ride to use as custom linker script the file that is "INCLUDE"d in the "....elf.ld" file. And then you can modify this sub-script just by adding a GROUP command in it.

This kind of thing is easy to do when you know how, but quite hard to explain. It would probably be easier if you send me your project and I send it back to you with the modification.

Best Regards,

Vincent