Hi
I ran into a odd problem yesterday when I add a code file to control the GPIO for a Cortex M3. All of the routines that were being called from the main code (4 of them) were called out by the linker to be undefined symbols. ??? The .c file compiled with no errors.
I did some experiments to see what the issue might be. I thought maybe the calling signature was wrong and it could not match it up so I cut and pasted just the subroutine definition of one of the subroutines and put it into the top of the only file that called that particular one and just made it a do nothing loop and the linker did resolve the subroutines name/symbol!!
So it is has nothing to do with how the subroutines are called or defined. I did another experiment to see if it had anything to do with the physical number of files being linked. I combined the new GPIO.c file with a existing file and removed the GPIO.c from the link list. I relinked and all of the subroutines names/symbols were resolved BUT a another assembly language name showed up as unresolved. Gees. Its definitely there in a totally different .s file so I don't know why started it will not resolve all of the sudden.
I tried combining more and more files to reduce the number of physical files but nothing seemed to help make this new unresolved system that did not show up before, go away.
So now I don't know what to do. The only thing that makes sense (cause and effect) is a limit on the number of files that the linker can accept. Maybe beyond that there is a internal limit on the number of routines or something that is causing this .s routine to be declared undefined.
Has anyone ever had a problem like this before?
Thanks
Too long command line when linking? Depending on OS version and how the linker is started, it's likely that the limit is 2k, 8k or 32k characters.
By the way - what changes did you do to this project initially to get it to fail to link? Or have you ported some code from some other environment?
"Too long command line when linking? Depending on OS version and how the linker is started, it's likely that the limit is 2k, 8k or 32k characters."
I am using the latest version, v5 with legacy support. I am using uVision 5.11a
"By the way - what changes did you do to this project initially to get it to fail to link? Or have you ported some code from some other environment?"
All I did was add another file to the source files group in uVision. Then this happened. All of this is new original code, nothing ported.
I have been playing around with it some more and if I #include "gpio.c" at the bottom of a existing file in the linker list, the undefined symbol error for all of the gpio functions goes away but a new one which I mentioned early appears because gpio.c calls a assembly routine called HW_get_8bit_reg. Grr.
So obviously the functions in gpio.c are being included now and being resolved which is why this other undefined symbol error appeared. I included the .s file hw_reg_access.s where this routine is defined but I still get the error. The .s is getting assembled without error.
But again the linker will not resolve the subroutine name. Just like with the gpio.c file.
I have tried reduce the number of files in the link list (group) with the #include trick but that has not helped in this case.
Is There anything special I need to do to link a .s with my .c and .cpp files?
Well if you're mixing in C++ (.cpp) files then you're going to need to be acutely aware of the name mangling done for type checking purposes, and ensure that when you call C routines you make the compiler explicitly aware of this. Otherwise, yes you'll see the linker failing.
extern "C" void foo(int); // of whatever
I'm not aware the linker has a file limit issue, although I haven't validated such, most would take a response file where command line constraints exist, it's not like we're using DOS tools in 1984.
View all questions in Keil forum