Linker error.
Home › Forums › MultiConnect OCG › Linker error.
- This topic has 7 replies, 2 voices, and was last updated 13 years, 1 month ago by JM K.
-
AuthorPosts
-
October 4, 2011 at 9:48 pm #2639JM KParticipant
Hi,
I am not able to provide the relevant library to the linker. The library files, libmodbus.la, libmodbus.so are present in usr/lib directory. I am using the DEPENDS = “libmodbus” to link the library in my bitbake recipe however this doesn’t seem to work. I would appreciate it if someone can let me know how to link an external library in bitbake. This is the recipe I am working with:
DESCRIPTION = “modbuscomm”
SECTION = “examples”
LICENSE = “GPL”
PR = “r96”
DEPENDS = “libmodbus”
SRC_URI = “file://mymodbuscomm.c”
S = “${WORKDIR}”
do_compile() {
${CC} ${CFLAGS} ${LDFLAGS} mymodbuscomm.c -o mymodbuscomm
}
do_install() {
install -d ${D}${bindir}
install -m 0755 mymodbuscomm ${D}${bindir}
}
I always keep getting an ‘undefined reference’ error whenever I compile my source though the functions are present in the .h header file.
I am using a Ubuntu 10.0.4 platform and using C to code my application for the CDP.
I would very much appreciate any suggestions on this one.
Best Regards,
JM
October 4, 2011 at 9:58 pm #3406Jesse GillesBlockedHi JM,
A couple of things:
1. Adding “libmodbus” to DEPENDS doesn’t make your application link against it. It makes bitbake know that in order to build your recipe, it needs to build libmodbus first and put the needed files in the sysroot (so your recipe can find the headers and libs). You’ll need to tell GCC that you want to link against the libmodbus library, it doesn’t know about it automatically.
2. You can certainly compile your application right in the bitbake recipe, but it might be easier to manage if you were to write a Makefile to compile it. Then you can actively develop your application by just running make until you get it building. Once you have it building, then you can resume running the bitbake recipe to package it up.
You can open up a development shell with all of the environment variables set for cross-compiling (CC, CFLAGS, LDFLAGS, etc) by running:
bitbake modbuscomm -c devshell
Then you can run make or run $CC and you can fix your build and then go back to running the bitbake recipe again. Also, if you switch to using a Makefile, then your do_compile task goes away and the compiling happens in the make file. You can also do the same thing for do_install if you want.
Hope that helps,
Jesse
October 5, 2011 at 8:00 pm #3407JM KParticipantDear Jesse,
thanks for the response. I issued this command at the prompt while having navigated to the folder that had my application:
gcc mymodbuscomm.c -I/usr/include -L/usr/lib -lmodbus
Then I noticed that a a.out file got generated in the same folder.
Following your advice I opened up a development shell by running:
bitbake modbuscomm -c devshell then at the command prompt issued the same command again:
jm@jm-desktop:~/Desktop/corecdp-1.1.1/build/tmp/work/armv5te-corecdp-linux-gnueabi/modbuscomm-1.0.0-r100$ gcc mymodbuscomm.c -I/usr/include -L/usr/lib -lmodbus
I got these errors:
mymodbuscomm.c:4: error: expected identifier or ‘(‘ before string constant
mymodbuscomm.c:5:19: error: modbus.h: No such file or directory
mymodbuscomm.c: In function ‘main’:
mymodbuscomm.c:14: error: ‘modbus_t’ undeclared (first use in this function)
mymodbuscomm.c:14: error: (Each undeclared identifier is reported only once
mymodbuscomm.c:14: error: for each function it appears in.)
mymodbuscomm.c:14: error: ‘ctx’ undeclared (first use in this function)
I found that the problem I am facing has been faced by others however they were using the eclipse C/C++ IDE and I found both the problem and the solution:
http://cboard.cprogramming.com/c-programming/136664-undefined-reference.html (please check the link)
Solution is:
“Thanks to all who have helped. I think that I have found the solution to the issue. As Tater said, there seems to be a library file with a .la extension or maybe the file that has .pc extension. For a newbie I am not sure why this file is needed at all because you have functions and header files which all of the logic seems to be there for everything to work with just the header files and the functions defined within them. In eclipse I right clicked on the project file then expanded the “C/C++ Build” then went to “settings” then expanded the “GCC C Linker” then went to “Libraries” then went under “Libraries (-l)” and added “modbus” it seemed to work. I am guessing that the default location for this to search is /usr/local/lib/pkgconfig which contained the file modbus.pc . Although I also changed the file name in eclipse libmodbus to test because I also have a file in /usr/local/lib called libmodbus.la and I don’t get any errors with this either. Hope this helps someone in the future so they don’t waste the 3.5 hours I did. Anybody to further explain for myself and other newbies would be appreciated I am sure.” (Credit to the user who posted this one).
I am wondering how to replicate the same in this case. I apologize if my questions are too trivial as I am a beginner with not much experience in programming applications on a Linux platform.
Thank you and have a great day.
Best Regards,
JM
October 5, 2011 at 8:27 pm #3408Jesse GillesBlockedJM,
I think some of your difficulty is arising from the fact the application needs to be cross compiled, not built for your Linux workstation. This means you have to use a different compiler and that headers and libraries are installed in a non-standard location.
When you are cross-compiling, you can’t just call “gcc” since that will be the compiler for your workstation, not the embedded device. Also, for the same reason, you can’t use includes from /usr/include and libs from /usr/lib because those are also for your workstation.
When you open up the devshell, print out your env (just run “env”) and look at the environment variables defined and you’ll see where the cross-compiler located, etc.
When you run the cross-compiler, it will have the includes and libs for the target system already in its default search paths, so if the libmodbus recipe installed the headers and libs in the right spot, you shouldn’t need to add the -I and -L options to your compile command. But you will need to add ‘-lmodbus’ so it knows to link against.
The compiler is located at:
$OETREE/build/tmp/cross/armv5te/bin
The headers dir that is search by default is:
$OETREE/build/tmp/staging/armv5te-corecdp-linux-gnueabi/usr/include
And libs are in:
$OETREE/build/tmp/staging/armv5te-corecdp-linux-gnueabi/usr/lib
$OETREE is the top of your corecdp directory structure.
October 5, 2011 at 11:09 pm #3409JM KParticipantHi Jesse,
Thanks for the response. I opened up the devshell by issuing the command:
bitbake modbuscomm -c devshell
Then at the command prompt I isuued the command:
arm-corecdp-linux-gnueabi-gcc -lmodbus mymodbuscomm.c -o mymodbuscomm
It returned nothing neither did any compilation errors show up. Then I exited the devshell and wrote a simple makefile.
CC = $OETREE/build/tmp/cross/armv5te/bin/arm-corecdp-linux-gnueabi-gcc
mymodbuscomm: mymodbuscomm.c
arm-corecdp-linux-gnueabi-gcc -lmodbus mymodbuscomm.c -o mymodbuscomm
Then I changed my bitbake recipe in the way where under do_compile only makefile existed.
Then when I tried to package using bitbake modbuscomm at the prompt the following error showed up:
Log data follows:
| /home/jm/Desktop/corecdp-1.1.1/build/tmp/work/armv5te-corecdp-linux-gnueabi/modbuscomm-1.0.0-r104/temp/run.do_compile.15178: line 784: makefile: command not found
| ERROR: Function do_compile failed
When I tried just issuing make at the command prompt the following error showed up:
arm-corecdp-linux-gnueabi-gcc -lmodbus mymodbuscomm.c -o mymodbuscomm
make: arm-corecdp-linux-gnueabi-gcc: Command not found
make: *** [mymodbuscomm] Error 127
Why did the same command at the devshell return nothing? Does the PATH in the env-oe.sh have to be modified? I checked and made sure that the relevant headers (modbus.h) exited in the include folder. I would appreciate it if my questions are answered. Thanks a lot, Jesse.
Best Regards,
JM
October 6, 2011 at 3:43 pm #3410JM KParticipantHi Jesse,
I figured out how to set the path. I am trying to set the path in the makefile however and I have been unsuccessful in doing this so far. In case I issue a command as this:
$arm-corecdp-linux-gnueabi-gcc -lmodbus mymodbuscomm.c -o mymodbuscomm
I encounter no errors nor does the command return anything.
Neither is there a generation of a new .o file in the same folder does it mean the program compiled successfully? Thanks for your help.
Best Regards,
JM
October 6, 2011 at 4:57 pm #3411Jesse GillesBlockedI think it would be helpful for you to do some research on using gcc in general if you are not familiar with it. If the program compiles successfully, it doesnt print anything out. It only prints messages if there are errors. You specified the -o option to gcc, which told it to put the output as a file named “mymodbuscomm”. If you ran it successfully as you mentioned, then you should have a compiled program called “mymodbuscomm” and you should be able to run it on the MTCDP if the libmodbus library is installed.
You shouldn’t set the path in your Makefile. Bitbake will setup all the paths needed and you should only need to invoke the compiler using the right variables like you had in your recipe in the first place.
$(CC) $(CFLAGS) $(LDFLAGS) mymodbuscomm.c -o mymodbuscomm
If you building the recipe then the paths and variables will be set. They will also be set if you open a devshell. If you don’t do either of those, then you don’t have any special paths set and you have to set them yourself or specify the full path to the compiler when you run it.
October 6, 2011 at 6:34 pm #3412JM KParticipantDear Jesse,
Thank you very much. I could successfully bitbake my application.
Best Regards,
JM
-
AuthorPosts
- You must be logged in to reply to this topic.