Build Error with CalcOpticalFlowFarneback Function -> OpenCV -> C Language - Eclipse -> MacOSX - c

i have to do a program using C Language and OpenCV Libreries for a project,
I followed the guide for the installation for MACOSX on this site:
OpenCV Installation
I used Mac Port for the Istallation.
I use Eclipse to program,
Now when i try to compile this program, i get a Build Error and i think that it depends to CalcOpticalFlowFarneback() Function.
This is the code:
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#include <math.h>
#include <time.h>
int main(){
CvCapture* webcam = cvCreateCameraCapture(0);
IplImage*prev=NULL;
IplImage*next=NULL;
char scelta;
/*INIZIALIZZAZIONE FUNZIONE RAND*/
srand(time(NULL));
double pyr_scale=0.5;
int levels=1;
int winsize=3;
int iterations=10;
int poly_n=5;
double poly_sigma=1.1;
int flags=0;
sleep(2);
if (!webcam){
/* Exit with an error */
puts("Attenzione! si è verificato un Errore in Fase di Attivazione della WebCam. Preghiamo di Riprovare!");
return -1;
}
while (1) {
prev = cvQueryFrame(webcam);//primi 8-bit single-channel immagine in ingresso
next = cvQueryFrame(webcam);// immagine secondo ingresso della stessa dimensione e lo stesso tipo prev.
CvSize isize = cvSize(80,80);
IplImage *flow = cvCreateImage(isize, IPL_DEPTH_32F, 1); //immagine computerizzata che ha le stesse dimensioni e tipo CV_32FC2 prev
if ((prev) && (next)) {
cvCalcOpticalFlowFarneback(prev,next,flow,pyr_scale,levels,winsize,iterations,poly_n,poly_sigma,flags);
scelta=cvWaitKey(20);
if((char)scelta == 27){
break;
}
}
}
cvDestroyWindow("VIDEO SORVEGLIANZA");
cvReleaseCapture(&webcam);
return 0;
}
and this is the error Log:
Undefined symbols for architecture x86_64: "_cvCalcOpticalFlowFarneback", referenced from:_main in main.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [cattura_foto] Error 1
And I want to specify that if i remove the cvCalcOpticalFlowFarneback Function i do not have any problems.
Thank you,
manu.web

"undefined symbol" means that you have not linked against the proper library, or you have, but the library is for the wrong architecture (e.g. a 32-bit library while your machine is 64-bit).
You need to check the linking flags and paths, and the library installation path.
If you can get the linker log in Eclipse, and/or the command line that got passed to the linker, you can repeat the linking command from a terminal and see if you get a more helpful message (such as "library not found"). Or you can try running the make command from the terminal and do the same.
Editing the Makefile, you might find that some commands are prepended with the "#" symbol, which prevents them from being output (their output is visible, the command itself is not). You can usually safely remove the #'s and get a more verbose output.
Another possibility is that there is a name mangling error, and the "_" prefix to the function should not be there. I am not too familiar with Eclipse though, so I can't follow you there. But see e.g. http://www.eclipse.org/forums/index.php/m/783606/ ; you might have built OpenCV with the wrong options, so that now it is not compatible with your code. Which is strange, seeing as how you call other OpenCV functions without problems; but maybe you built OpenCV in two steps?
In general (this is not limited to OpenCV!) you will have a build command such as
gcc -I/usr/local/include/opencv -L/usr/local/lib main.c -o Cattura_foto2 \
-lopencv_core.2.4.3 \
-lopencv_imgproc.2.4.3 \
-lopencv_highgui.2.4.3 \
-lopencv_gpu.2.4.3
and an error complaining of an undefined symbol:
Undefined symbols for architecture x86_64: "_cvCalcOpticalFlowFarneback"
This means that you are linking with the libraries openvc_core.2.4.3 etc. and the linker cannot find the symbol "_cvCalcOpticalFlowFarneback".
Locate those libraries on your computer, and run (from Terminal) the following command against all the libraries you found. Note: your path will probably be different. I have /usr/lib64.
for lib in /usr/lib64/libopencv_*; do
echo "Examining $lib..."
strings $lib | grep -i cvCalcOpticalFlowFarneback
done
You ought to see something like:
Examining /usr/lib/libopencv_pippo_pluto...
Examining /usr/lib/libopencv_blah_blah...
...
Examining /usr/lib64/libopencv_video.so...
cvCalcOpticalFlowFarneback
cvCalcOpticalFlowFarneback
Examining /usr/lib64/libopencv_video.so.2.4...
cvCalcOpticalFlowFarneback
cvCalcOpticalFlowFarneback
Examining /usr/lib64/libopencv_video.so.2.4.3...
cvCalcOpticalFlowFarneback
cvCalcOpticalFlowFarneback
The reason for the multiple matches is that libraries exist in multiple symbolic copies.
To be sure, let's inspect the library:
nm -D /usr/lib64/libopencv_video.so.2.4 | grep Farneback
0000000000027e50 T cvCalcOpticalFlowFarneback
Now we know two important things:
The symbol is really called cvCalcOpticalFlowFarneback. Your GCC is complaining it doesn't find the symbol _cvCalcOpticalFlowFarneback, with an underscore. You either built the library incorrectly or you are missing a -fno-leading-underscore option to GCC.
But if that were the case, no OpenCV2 symbols at all would be recognized. So, I'm betting on #2:
The symbol is in libopencv_video.so.2.4.3, and there is no reference to that library in your build command! You ought to have -lopencv_video.2.4.3 or something like that. Verify your makefile and options.
Let me know how it goes - and in bocca al lupo.

Related

GNU Linker map: trace origin of symbol from dynamic library

I am trying to list all real file dependencies of an ELF executable in order to improve granularity of incremental building/testing.
When I link an executable against a set of libraries, the symbols from the STATIC ones appear on top of the linker map, which is good. I would like to also know when the linker include a symbol from a shared library and the path to the defining file.
For exemple if I have an executable looking like:
#include "ext_src.h"
#include "ext_lib.h"
#include "int_src.h"
int main(){
ext_src();
ext_lib();
int_src();
}
Where each of the 3 functions comes from a different library, the compiler command being:
/usr/bin/cc -O3 -DNDEBUG -Wl,-Map=exec2.map exec2.c.o -o exec2 -Wl,-rpath,backend_libs: backend_libs/libsub.so backend_libs/libEXT_dependence1.so extern/lib/an_extern_lib/libext_lib_normal.a
I can only have the information I seek (which is that ext_lib() comes from ext_lib.c.o) for the static library on top of the linker map:
Membre d'archive inclu pour satisfaire la référence par fichier (symbole)
extern/lib/an_extern_lib/libext_lib_normal.a(ext_lib.c.o)
CMakeFiles/exec2.dir/entry/exec2.c.o (ext_lib)
/usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS)
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/Scrt1.o (__libc_csu_init)
The information does not seem to be anywhere in the linker map. Indeed I cant find the module I know where ext_src() is defined in it.
Does someone have an idea how to get the file from which ext_src is defined? It need to be in a way that it would list only the symbols that my executable actually uses
Edit: I also forgot to mention that I control the compilation of the libraries I link to. Thus I am open to a solution involving compiling theses libraries with weird flags, debug sections...

Why do I get a linker error while I try to compile a C file?

I've had this error for weeks I already made a post about it but it wasn't very clear.
So I am calling a function from a a header file myBmpGris.h and the functions are implemented on the file myBmpGris.c . Here is my main file:
#include<stdio.h>
#include<stdlib.h>
#include "myBmpGris.h"
int main(){
char * image_name = "image_carre.bmp";
BmpImg image = readBmpImage(image_name);
return 0;
I compile by using ggc main.c and I get this error message :
Undefined symbols for architecture x86_64:
"_readBmpImage", referenced from:
_main in main-1c453a.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I read a lot of posts about the same error message but none of the answers seem to apply to my case. I'm kind of desperate because a lot of my programs give me the same error. What should I do ?
You need to tell the compiler about all the code files which contain any of the needed functions.
So if you have until now compiled like gcc main.c, then the simplest way of also getting the other file compiled is gcc main.c myBmpGris.c.
You might want to read up on the other things you can helpfully tell the compiler (and other parts of the building), i.e. the possible commandline parameters. Or use one of the available free programming environments. (I am not going to name any. Just use your favorite search engine on "C IDE free" or similar. The first few hits discuss several, try a few, then use the one your friends use, or the one you really like much, much better.)
There are two thing.
Compilation you have included. h file. It means comilper will make entry in symbol table for all used function from included library.
Linking here linker try to get address from library to fill in symbol table created in first step. This cannot be performed in your case. So give full path of library.

MicroFocus cobol commands cobinit,cobcall and cobtidy are throwing errors in my C program

As per the documentation in Micro-focus support site, to call a cobol program from a C program we just need to follow the given below steps.
main(int argv, char *argv)
{
cobinit(); /* Initialize COBOL environment */
cobcall("cobep", 0, NULL); /* Call a COBOL program */
cobtidy(); /* Close down COBOL environment */
return(0);
}
Based on this I have come up with a simple C program to call an already working Cobol program, but guess I am getting linking error.
C Program
cat call.c
#include<stdio.h>
#include "cobcall.h"
#include "cobmain.h"
int main()
{
int ret=0;
cobinit();
ret=cobcall("cobolprogram.gnt",1,NULL);
cobtidy();
return 0;
}
Error message receiving
gcc -Wall call.c -o call
call.c: In function 'main':
call.c:10: warning: pointer targets in passing argument 1 of 'cobcall' differ in signedness
/usr/ccs/bin/ld: Unsatisfied symbols:
cobtidy (first referenced in /tmp/ccQBPw6r.o) (code)
cobcall (first referenced in /tmp/ccQBPw6r.o) (code)
cobinit (first referenced in /tmp/ccQBPw6r.o) (code)
collect2: ld returned 1 exit status
If you use MF then you likely have access to a paid support. In any case here's what I can tell you from knowing something about gcc and libraries.
The C compiler compiles fine. It only complains about signedness of a char * or const char *, but this shouldn't matter.
To solve this check in the header for the actual defintion of cobcall, I assume changing it to one of these should fix the compiler warning:
ret=cobcall((char *)"cobolprogram.gnt",1,NULL);
ret=cobcall((const char *)"cobolprogram.gnt",1,NULL);
ret=cobcall((unsigned char *)"cobolprogram.gnt",1,NULL);
ret=cobcall((const unsigned char *)"cobolprogram.gnt",1,NULL);
Side note: as far as I know you don't pass the file extension to cobcall, therefore to make it work later you may need to remove the .gnt part.
The errors you get are from the linker as it has no possibility to resolve these mf specific functions. I've skimmed over different MF docs but did not found the library name you need. Maybe it is libcob or libcobmf or libmfcob or ...
Edit: I've found a reference in an old MF manual naming the library libcobol.
As soon as you know the library name use -lname (for example -lcobol/ -lcob/ -lcobmf/-lmfcob) to let the linker know that it can resolve them in this library. Add -L/path/to/library to let the linker know where it can find the library.
If compilation worked any your main program complains about "cannot find libcob.so" (or libcobmf.so or whatever it is named) set LD_LIBRARY_PATH to point to the library name.

Undefined reference and bad reloc address when linking to libsndfile

In a project project I am working on, I need to be able to open and read content from audio files (at least WAV files). I installed libsndfile using the Win64 installer from mega-nerd.com, and created a simple C program that opens and closes an audio file to test out the library.
#include <stdio.h>
#include <sndfile.h>
int main()
{
SNDFILE *sndfPtr;
SF_INFO soundfileInfo;
char path[] = "C:\\Users\\jayb\\Documents\\MusicClips\\violin.wav";
printf( "Path: %s\n", path );
/* Open soundfile for reading */
soundfileInfo.format = 0; /* Must be set to zero before opening */
sndfPtr = sf_open( path, SFM_READ, &soundfileInfo );
if( sndfPtr == NULL )
{
fprintf( stderr, "Error: %s\n", sf_strerror(NULL) );
return -1;
}
/* Close soundfile and check for error */
if( sf_close( sndfPtr ) )
{
fprintf( stderr, "There was an error closing the soundfile\n" );
return -1;
}
return 0;
}
However, I keep getting undefined reference errors to the libsndfile functions, plus a bad reloc address error when I try compiling/linking:
C:\Users\jbiernat\AppData\Local\Temp\ccSmO0dw.o:sndfile_test.c:(.text+0xbb): undefined reference to `sf_open'
C:\Users\jbiernat\AppData\Local\Temp\ccSmO0dw.o:sndfile_test.c:(.text+0xd8): undefined reference to `sf_strerror'
C:\Users\jbiernat\AppData\Local\Temp\ccSmO0dw.o:sndfile_test.c:(.text+0x10a): undefined reference to `sf_close'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: C:\Users\jbiernat\AppData\Local\Temp\ccSmO0dw.o: bad reloc address 0x20 in section `.eh_frame'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
I'm compiling with this command:
gcc -Wall -o sndfile_test.exe sndfile_test.c -llibsndfile-1
The install of libsndfile comes with header files sndfile.h and sndfile.hh, and .lib, .def, and .dll files: libsndfile-1.lib libsndfile-1.def libsndfile-1.dll
The header and library directories are included in the compiler's search path, and it doesn't seem to be a problem of finding the library? I'm linking the .lib file with -llibsndfile-1 as per instructions on the minGW wiki
I also copied and renamed the .lib file with the .a extension and tried linking with -lsndfile-1 (this worked for someone else having a similar problem), but I get the exact same errors when I do so.
Any help would be appreciated! If I cannot link successfully to libsndfile, are there are any other simple libraries out there I could use for reading from audio files?
Edit: Of course I spend two days trying to find the solution, finally post to stackoverflow, and then solve the problem two hours later. I will post my solution as an answer to the question.
Following the information on this page of the MinGW wiki, use MinGW's dlltool with the libsndfile-1.def file to re-create the the dll's import library.
Use this command to do so:
dlltool -d libsndfile-1.def -l libsndfile-1.dll.a
This will create the .dll.a file that you can use instead of the .lib file. Note that when I did this, the .dll.a file did not appear in the directory I was in when I executed the above command. It ended up hidden in my \AppData directory, so you might have to search your OS for it.
Replace the libsndfile-1.lib in your lib directory with libsndfile-1.dll.a and then compile using:
gcc -Wall -o sndfile_test.exe sndfile_test.c -lsndfile-1

Tcl interpreter undefined reference error while compiling with gcc

I am new to Tcl scripting and would like to use C to embed Tcl codes.
This is the code that I have copied from a website to test the Tcl-C working.
test.c
#include <stdio.h>
#include <tcl.h>
void main ()
{
Tcl_Interp *myinterp;
char *action = "set a [expr 5 * 8]; puts $a";
int status;
printf ("Your Program will run ... \n");
myinterp = Tcl_CreateInterp();
status = Tcl_Eval(myinterp,action);
printf ("Your Program has completed\n");
getch();
}
I am using MinGW to compile this file.
I have copied the contents of the C:\Tcl\include folder into the C:\MinGW\include folder as well.
My gcc command for compiling :
gcc -o test.exe test.c
The error message shown :
C:\Users\user\AppData\Local\Temp\ccEHJKCb.o:tcl_connection_test.c:(.text+0x23): undefined reference to `_imp__Tcl_CreateInterp'
C:\Users\user\AppData\Local\Temp\ccEHJKCb.o:tcl_connection_test.c:(.text+0x3d): undefined reference to `_imp__Tcl_Eval'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: C:\Users\user\AppData\Local\Temp\ccEHJKCb.o: bad reloc address 0x20 in section `.eh_frame'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
I don't seem to have any libtcl file in the Tcl folder.
The Tcl version is ActiveTcl 8.5.15.0.297577.
Any help would be really appreciated.
Your example how to embed Tcl is outdated, and you are missing certain things in your link line (-ltcl85 for example). If you simply add -ltcl85 to your link line it should start to work.
It does not work in your case, because you installed the x64 (64-Bit version) of ActiveTcl, which provides x64 dlls, not 32-Bit ones. But the standard mingw gcc only works with 32-Bit libraries.
So to get this to work:
Download the 32-Bit ActiveTcl distribution
Compile your code with gcc -o test.exe test.c -Lc:/tcl/lib -Ic:/tcl/include -ltcl86
Adjust your path so the c:\tcl\bin\tcl86.dll is found in PATH, make also sure Tcl finds its libdir (set TCL_LIBRARY=c:\tcl\lib\tcl8.6)
run your program
But for more complex examples, you still need to initialise the library and a do some boilerplate code, so please call Tcl_FindExecutable(argv[0]); before the call to Tcl_CreateInterp() otherwise a few commands (e.g. clock might just not work as expected).
Have a look at http://www.tcl.tk/cgi-bin/tct/tip/66.html for some more details. Also have a look at the Tcl source distribution and the source for the tclsh shell.
You're very close to getting it right.
The Tcler's Wiki has a few examples, some of which are very confusing to be frank, but this one from this page is the best I've spotted recently. (The comments are mine.)
#include <stdlib.h>
#include <tcl.h>
int main (int argc, char *argv[]) {
Tcl_Interp *interp;
const char *script = "proc p1 a { puts $a }";
// Initialize the Tcl library; ***STRONGLY RECOMMENDED***
Tcl_FindExecutable(argv[0]);
// Create the interpreter, the execution context
interp = Tcl_CreateInterp();
// Initialise the interpreter
if (TCL_OK != Tcl_Init(interp)) {
fprintf(stderr, "Tcl_Init error: %s\n", Tcl_GetStringResult(interp));
exit(EXIT_FAILURE);
}
// Define a procedure
Tcl_Eval(interp, script);
fprintf(stderr, "res 1: %s\n", Tcl_GetStringResult(interp));
// Check if the procedure exists
Tcl_Eval(interp, "puts [info commands p*]");
fprintf(stderr, "res 2: %s\n", Tcl_GetStringResult(interp));
// Call the procedure
Tcl_Eval(interp, "p1 abc");
fprintf(stderr, "res 3: %s\n", Tcl_GetStringResult(interp));
// We could use Tcl_DeleteInterpreter to clean up here, but why bother?
return EXIT_SUCCESS;
}
What else were you missing? Simple. You forgot to tell the C compiler to use the Tcl library when building the executable; the compiler (or, more strictly, the linker) is in places a stupid piece of code. The exact option to use to get the linker to add the library in will depend on your system configuration, but is probably going to be -ltcl, -ltcl8.5 or -ltcl8.6; which it is depends on the filename and all sorts of things that we can't check exactly without being on your system. The names do fit a simple pattern though.
It's also possible that you might need to pass the -L option in to tell the linker about additional library locations. (There's an equivalent -I for telling the compiler where to find include files, so you don't have to copy everything into one gigantic unmanageable directory.)
The order of arguments can matter. Libraries should be listed after the source file:
gcc -o test.exe test.c -L/mingw/path/to/library/directory -ltcl86
(If you're using old, unsupported versions of Tcl — why would you do that?! — then the code above won't work because Tcl_Eval then took a writable string. But that was fixed many years ago and upgrading to a current version is the fix.)

Resources