why can't it find sprintf? can't believe this! Mike@l2200 ~/Example $ make test ..linking arm-elf-ld -v -Map main.map -nostartfiles -T simple.cmd -L /gnude/arm-elf/lib -l c -lg -L /gnude/lib/gcc-lib/arm-elf/3.3.1 -lgcc -o main.out start.o ivt.o libc .a main.o Init22.o LCD.o RTC.o Serial.o Timer.o PWM.o Keypad.o Chars.o Delay.o GNU ld version 2.14 20030612 main.o(.text+0x16c): In function `__main': : undefined reference to `sprintf' main.o(.text+0x198): In function `__main': : undefined reference to `sprintf' main.o(.text+0x1d8): In function `__main': : undefined reference to `sprintf' main.o(.text+0x1f8): In function `__main': : undefined reference to `strcat' main.o(.text+0x238): In function `__main': : undefined reference to `sprintf' C:\cygwin\gnude\arm-elf\lib C:\cygwin\gnude\lib\gcc-lib\arm-elf\3.3.1 #include <stdlib.h> #include <stdio.h> #include <string.h> static void ShowIt(void) { char* s; char sOutBuffer[100]; s = (char*) &sOutBuffer; sprintf(s, "%d:%.2d:%.2d", 1, 2, 3); } thank you for your help!
dear mike
i haven't an answer, but why so complicated:
>> s = (char*) &sOutBuffer;
much more easy.
s = sOutBuffer ;
kind regards
hans
--
> why can't it find sprintf?
Because you pass libc to the linker before the file that uses it. It
should come after all your object files in the linker command line.
That, and you should be using gcc for linking instead of ld directly. This will solve a lot of environment issues such as library paths and linking of libc. Your linking of main.out repeats all the dependencies on the command line of the linker, use make variable $^ instead. Also, the standard variable name for linker flags is LDDFLAGS. Likewise the standard for C compiler flags is CFLAGS, not CAFLAGS, and -c shouldn't be in it because it is not a flag, it belongs on the command line. That is relevant because these names are used in default rules, which you might want to mix in. Then you should also explicitly name the output (conveniently available in $@) on the command line. Here is a pattern rule I use for example:
1 | %.o: %.c |
2 | @echo "CC $@" |
3 | @$(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $< |
It is basically the default pattern rule modified to hide the command line so that warnings and errors are easier to read in the make output. In your simple.cmd linker script I see that you are putting the initialized data sections into the uninitialized data section of the output. This is definitely wrong. All your initialized static and global variables will start with zero instead of the given value. Even if you can handle that it will also break any linked library that makes use of initialized data. Your Makefile is missing all dependency information. All source files depend at least on the headers they include and they need to be recompiled if any of those changes. You can still use the pattern rules to compile and use the initial line of a rule for the dependency information. Example:
1 | main.o: main.c someheader.h |
2 | other.o: other.c another.h someheader.h |
The advanced make user can script some automatic dependency generation (that's what gcc's -M flag is for).
thank you--that addressed this problem! now i can see something new (see new posting i'll be writing next).
>That, and you should be using gcc for linking instead of ld directly. This will solve a lot of environment issues such as library paths and linking of libc. don't know how to change that. am nervous to make that change since the example used something else. even as a professional developer (delphi), i find myself very unprepared for this. >Your linking of main.out repeats all the dependencies on the command line of the linker, use make variable $^ instead. Also, the standard variable name for linker flags is LDDFLAGS. Likewise the standard for C compiler flags is CFLAGS, not CAFLAGS, and -c shouldn't be in it because it is not a flag, it belongs on the command line. That is relevant because these names are used in default rules, which you might want to mix in. Then you should also explicitly name the output (conveniently available in $@) on the command line. > >Here is a pattern rule I use for example: > >%.o: %.c > @echo "CC $@" > @$(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $< > >It is basically the default pattern rule modified to hide the command line so that warnings and errors are easier to read in the make output. i'm nervous to change too much because i lack the experience to fix the problems that may arise. have made some of the changes. once i get things compiling, i will be more brave... >In your simple.cmd linker script I see that you are putting the initialized data sections into the uninitialized data section of the output. This is definitely wrong. All your initialized static and global variables will start with zero instead of the given value. Even if you can handle that it will also break any linked library that makes use of initialized data. i moved "*(.data)" into ".text". is that the correct solution? >Your Makefile is missing all dependency information. All source files depend at least on the headers they include and they need to be recompiled if any of those changes. You can still use the pattern rules to compile and use the initial line of a rule for the dependency information. Example: > >main.o: main.c someheader.h >other.o: other.c another.h someheader.h i think i have fixed this problem. can you have another look? >The advanced make user can script some automatic dependency generation (that's what gcc's -M flag is for). i do not fit in that category. i've attached revised copies. thank you for all your help!!!
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.