Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Language IDEs » C / C++ IDE (CDT) » Linker can't "recognize" function, defined in another source file
Linker can't "recognize" function, defined in another source file [message #1760026] Fri, 21 April 2017 10:16 Go to next message
Pavel Yermolenko is currently offline Pavel YermolenkoFriend
Messages: 26
Registered: June 2015
Junior Member
Hello,

Again, quite naughty behavior of "NIOS II Software Build Tools for Eclipse". On the screenshot below - the result of building of a quite simple project. Build fails because linker can't "recognize" timer_wr_prd function that is defined in chu_timer_drv.c source file. And yet the header chu_timer_drv.h is included in the source file. So, also sniffs as a bug ?

Here is the complete build error message:
C:\Users\Pavel\Documents\proj_Quartus\Embedded_SoPC_NIOS_Verilog\proj06_NIOS_Flashing-LED_system_ch11\software\led2_test/main_chasing_led.cpp:88: undefined reference to `timer_wr_prd(unsigned long, unsigned long)'
collect2.exe: error: ld returned 1 exit status
make: *** [led2_test.elf] Error 1


Thanks in advance for your feedback.
Pavel.
https://s27.postimg.org/5srcxvl6r/Linker_cant_recognize_function.jpg
Re: Linker can't "recognize" function, defined in another source file [message #1760041 is a reply to message #1760026] Fri, 21 April 2017 12:19 Go to previous messageGo to next message
Pavel Yermolenko is currently offline Pavel YermolenkoFriend
Messages: 26
Registered: June 2015
Junior Member
Once the timer_wr_prd function is moved in the main source file, the project is built without errors. Strange ...
void timer_wr_prd(alt_u32 timer_base, alt_u32 prd) {
	alt_u16 high, low;

	/* unpack 32-bit timeout period into two 16-bit half words */
	high = (alt_u16) (prd >> 16);
	low = (alt_u16) (prd & 0x0000ffff);
	/* write timeout period */
	IOWR(timer_base, TIMER_PRDH_REG_OFT, high);
	IOWR(timer_base, TIMER_PRDL_REG_OFT, low);
	/* configure timer to start, continuous mode; enable interrupt */
	IOWR(timer_base, TIMER_CTRL_REG_OFT, 0x0007);
}

void sys_init() {
	btn_clear(BTN_BASE);
	timer_wr_prd(USR_TIMER_BASE, 150000);
}

int main() {
	LED led(0);
	sys_init();
	while(1)
	{
		set_speed(led);
		led.flash();
		led.move();
	};
}
Re: Linker can't "recognize" function, defined in another source file [message #1760045 is a reply to message #1760041] Fri, 21 April 2017 13:07 Go to previous messageGo to next message
David VavraFriend
Messages: 1426
Registered: October 2012
Senior Member
Not strange.
Includes are used to define external functions to the compiler.
The error you were getting is a linker error.
For some reason, the object containing the function wasn't used in the link.
Why is hard to say.

Another possible reason for the error is perhaps it wasn't declared as a C function.
C++ function names are mangled to convey type information.

[Updated on: Fri, 21 April 2017 13:15]

Report message to a moderator

Re: Linker can't "recognize" function, defined in another source file [message #1760051 is a reply to message #1760045] Fri, 21 April 2017 13:49 Go to previous messageGo to next message
Pavel Yermolenko is currently offline Pavel YermolenkoFriend
Messages: 26
Registered: June 2015
Junior Member
Yes, there is an issue with mixing .cpp and .c sources. I've just tried the following experiment: I've created new source file that contains function timer_wr_prd ... with slightly other name and mostly with .cpp extension. Then I excluded old .c file from build and tried to build the project. This time it worked ... project is built. First, the idea of some kind of "incompatibility" of .c and .cpp sources comes in mind ... but then I see that for other functions (that are defined in other .c files) such "mixing" works.

Other issue that probably comes from the same problematic: as you can state from the screenshot below, the macro IOWR seems to be unrecognized (at least tooltip gets this impression), but nevertheless built process finishes without errors.

https://s3.postimg.org/agknt4rj7/timer_drv_cpp.jpg

[Updated on: Fri, 21 April 2017 13:50]

Report message to a moderator

Re: Linker can't "recognize" function, defined in another source file [message #1760066 is a reply to message #1760045] Fri, 21 April 2017 15:41 Go to previous messageGo to next message
Tauno Voipio is currently offline Tauno VoipioFriend
Messages: 743
Registered: August 2014
Senior Member
Did you remember to use extern "C" for plain C functions in C++?


--

Tauno Voipio
Re: Linker can't "recognize" function, defined in another source file [message #1760093 is a reply to message #1760066] Sat, 22 April 2017 09:50 Go to previous messageGo to next message
Pavel Yermolenko is currently offline Pavel YermolenkoFriend
Messages: 26
Registered: June 2015
Junior Member
Thanks Tauno,

Indeed, I forgot these linkage issues.
Nevertheless alternating linkage inside .h file (where function is declared) didn't work.
E.g., modifying
void timer_wr_prd(alt_u32 timer_base, alt_u32 prd);

to
extern "C" void timer_wr_prd(alt_u32 timer_base, alt_u32 prd);

generates error:

chu_timer_drv.h:30:8: error: expected identifier or '(' before string constant
extern "C" void timer_wr_prd(alt_u32 timer_base, alt_u32 prd);
^
make: *** [obj/default/chu_timer_drv.o] Error 1


But when I do it in the main source file, wrapping header, it works.
E.g.
#include "chu_timer_drv.h"

becomes
extern "C" {
#include "chu_timer_drv.h"
}


This last construction resolves the issue, i.e. "C" function is recognized while linking with "CPP" source.

[Updated on: Sat, 22 April 2017 09:51]

Report message to a moderator

Re: Linker can't "recognize" function, defined in another source file [message #1760100 is a reply to message #1760093] Sat, 22 April 2017 14:50 Go to previous message
David VavraFriend
Messages: 1426
Registered: October 2012
Senior Member
extern "C" is valid only in C++.
The error you are getting is when compiling chu_timer_drv.c
Either use extern "C" in when you need it in a C++ module or surround it in the header as follows

#ifdef __cplusplus
extern "C" {
#endif
:
// c linkage code here
:
#ifdef __cplusplus
}
#endif


NOTE: not all compilers define __cplusplus so you may need to define it yourself on the compile command line when using C++.
ANSI/ISO compilers should have it though.

[Updated on: Sun, 23 April 2017 03:11]

Report message to a moderator

Previous Topic:RadioHead library for Arduino CDT anyone?
Next Topic:Can I have a simple editor?
Goto Forum:
  


Current Time: Thu Dec 05 10:33:04 GMT 2024

Powered by FUDForum. Page generated in 0.03669 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top