I'm writing a library that contains a custom _sdcc_external_startup() function (It also contains a main() - the user of this library will only implement a few handlers).
This works fine as long as no other library references _sdcc_external_startup() somehow, otherwise I get the following warning:
?ASlink-Warning-Definition of public symbol '__sdcc_external_startup' found more than once
For example, let's suppose we have the following code:
main.c:
extern void bar();
void somefunc() {
bar();
}
lib1.c:
char _sdcc_external_startup() {
return 42;
}
lib2.c:
void bar() {
__asm
ljmp __sdcc_external_startup
__endasm;
}
Compiling lib1.c into lib1.lib and lib2.c into lib2.lib, then linking them both with main.c results in the warning:
$> sdcc -o lib1.rel -c lib1.c
$> sdcc -o lib2.rel -c lib2.c
$> sdcclib -a lib1.lib lib1.rel
$> sdcclib -a lib2.lib lib2.rel
$> sdcc -o main.rel -c main.c
$> sdcc -o main.out -llib1.lib -llib2.lib main.rel
?ASlink-Warning-Definition of public symbol '__sdcc_external_startup' found more than once:
Library: 'lib1.lib', Module: 'lib1'
Library: '/usr/share/sdcc/lib/small/libsdcc.lib', Module: '_startup.rel'
If I add a reference from main.c to something in the relfile where _sdcc_external_startup() is it works (e.g. if somefunc() would call another function from lib1.c). It must be the same relfile, using a function from another relfile added to lib1 doesn't work.
I'm not sure if this is really a bug or if I'm simply misunderstood something.
Thanks and cheers,
Sam
SDCC version:
SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.6.0 #9615 (Linux)
sdcc_external_startup is meant for time-critical tasks that must be executed immediately upon startup, even before global variables are initialized. Such tasks will typically be found only in an very low-level library, of which you typically don't want to use more than one.
Normal libraries might need some initialization, but that is usually done by some libname_init() function that the programmer calls before the first use of other library functions.
Philipp
But the problem for Sam is that he provides only one and SDCC provides another default one. When the function is found directly in an object file (.rel) there is no problem as that gets priority.
I think the solution if you want to provide this in a library is to replace the whole libsdcc.lib. Use --nodefaultlibs, use your own libsdcc.lib and manually link the other sdcc default libs.
Yes, exactly. I've run into this issue while working on a low-level library implementing a protocol using existing vendor libraries.
Building my own libsddc.lib seems a bit excessive. For now we will provide the implementation of sdcc_external_startup as source code the user of our library.
While there is nothing wrong with providing it as source code, you can also provide it as an object file (.rel).
Ah, that's good to know!
I don't think it would make much of a difference in my use case however as there isn't much special code in sdcc_external_startup anyways.
I think we've covered every possibility, so I don't mind if you close this.