Linking error OpenCV 2.4+CUDA windows 7(x64) command line - visual-c++

I am trying to compile a program that uses both CUDA and OpenCV.
I am sure that the paths to OpenCV are right because compiling a simple OpenCV program with this:
cl /I"%OPENCV_DIR%\include" /LINK"%OPENCV_DIR%\x64\vc10\lib\opencv_core240.lib" "%OPENCV_DIR%\x64\vc10\lib\opencv_highgui240.lib" testCV.cpp
it successfully compiles the program. Now when I try to compile with NVCC like this:
nvcc testCuda.cu --cl-version 2010 --use-local-env -I"%OPENCV_DIR%\include" -L"%OPENCV_DIR%\x64\vc10\lib\opencv_core240.lib" "%OPENCV_DIR%\x64\vc10\lib\opencv_highgui240.lib"
I got an error when trying to link that says:
error LNK2019: unresolved external symbol cvLoadImage referenced in function main
a.exe : fatal error LNK1120: 1 unresolved externals
What am I missing or doing wrong when compiling with NVCC?

-L is used to specify library directories, not files.
You probably want to execute:
nvcc testCuda.cu --cl-version 2010 --use-local-env -I"%OPENCV_DIR%\include" -L"%OPENCV_DIR%\x64\vc10\lib" -lopencv_core240 -lopencv_highgui240
If that doens't work, drop the -l and add their extensions:
nvcc testCuda.cu --cl-version 2010 --use-local-env -I"%OPENCV_DIR%\include" -L"%OPENCV_DIR%\x64\vc10\lib" opencv_core240.lib opencv_highgui240.lib
Once upon a time, when we had CUDA 2.x and OpenCV 2.1, I wrote a Makefile to compile an application that used both frameworks:
CXX=g++
CUDA_INSTALL_PATH=/usr/local/cuda
CFLAGS= -I. -I$(CUDA_INSTALL_PATH)/include -I/usr/include/opencv
LDFLAGS= -L$(CUDA_INSTALL_PATH)/lib -lcudart -L/usr/lib -lcxcore -lcv -lhighgui -lcvaux -lml
ifdef EMU
CUDAFLAGS+=-deviceemu
endif
all:
$(CXX) $(CFLAGS) -c main.cpp -o main.o -m32 -arch i386
nvcc $(CUDAFLAGS) -c kernel_gpu.cu -o kernel_gpu.o
$(CXX) $(LDFLAGS) main.o kernel_gpu.o -o grayscale -arch i386
clean:
rm -f *.o grayscale

May be a missing -L before the second library file like the first one?

I was just able to link against cuBLAS on Windows by adding a pragma directive to my code:
#pragma comment(lib,"cublas.lib")
This might work with OpenCV as well. Be aware that this is non-portable, though.

Related

Unable to compile C program on Mac, but able to compile on Linux

I facing some trouble compiling my programming assignment on my local machine. The program is distribute to us with makefiles and compilation commands that are known to work on the school's Scientific Linux servers. My local machine is Mac OS X El Capitan.
When I compile my program running make on my Mac, I get the following error that prevents compilation from proceeding:
myid-MacBook-Pro:mp6 myid$ make
gcc -g -lm -std=c99 -Wall -Werror -c lodepng.c
clang: error: -lm: 'linker' input unused
make: *** [lodepng.o] Error 1
But when I push that very same code as work in progress to the Linux servers and compile there, everything works fine. The linux servers use gcc and not clang:
[netid#linux-a2 mp6]$ make
gcc -g -lm -std=c99 -Wall -Werror -c functions.c
gcc -g -lm -std=c99 -Wall -Werror main.o lodepng.o imageData.o functions.o -o mp6 -lm
gcc -g -lm -std=c99 -Wall -Werror -c test.c
gcc -g -lm -std=c99 -Wall -Werror test.o lodepng.o imageData.o functions.o solution.o -o test -lm
In the makefile, these are the variable definitions:
CC=gcc
CFLAGS=-g -lm -std=c99 -Wall -Werror
and the target definition for loadpng.o
lodepng.o: lodepng.c
$(CC) $(CFLAGS) -c lodepng.c
I would appreciate any help on understanding this error and overcoming it.
Thank you very much.
Also, on this note, I thought I would say that I've noticed a subtle difference between Clang and GCC. It seems to me that even warnings generated by Clang would prevent the compilation to proceed so the warnings behaves like errors. But for GCC, if it generates warnings, it still compiles the object file. Please correct me if I'm mistaken.
Right now you're getting a compilation error on your Mac because you're trying to pass linker commands (i.e. -lm) into a compilation(i.e. -c). Do not give link flags when you compile (-c flag) your source files.
In the other compilation snippet you provided, the unused linker command seems to pass by unnoticed which isn't a good thing.
For your last question, the flag -Werror should force all compilation warnings to become errors -- which is exactly what you are describing.

Linker error in Codelite with MinGW-w64

I'm trying to use MinGW-W64 instead of MinGW in Codelite. When I compile simple "hello, world" project it's all right. But when I try to link some libraries, I get a strange linker error. Project with exactly same settings compiles by MinGW with any problems. There are build output for both variants:
MinGW GCC 4.8.1
`C:\Windows\system32\cmd.exe /C D:/apps/mingw/bin/mingw32-make.exe -j8 SHELL=cmd.exe -e -f Makefile
"----------Building project:[ code - Debug ]----------"
mingw32-make.exe[1]: Entering directory 'D:/Projects/codelite/code'
codelite-cc D:/apps/mingw/bin/g++.exe -c "D:/Projects/codelite/code/src/main.cpp" -Wfatal-errors -g -O0 -pedantic -W -std=c++11 -Wall -o ./Debug/src_main.cpp.o -I./inc/
D:/apps/mingw/bin/g++.exe -o bin/code #"code.txt" -L./lib/ -lopengl32
mingw32-make.exe[1]: Leaving directory 'D:/Projects/codelite/code'
====0 errors, 0 warnings====`
MinGW-W64 GCC 5.2.0
`C:\Windows\system32\cmd.exe /C D:/apps/mingw-w64/mingw32/bin/mingw32-make.exe -j8 SHELL=cmd.exe -e -f Makefile
"----------Building project:[ code - Debug ]----------"
mingw32-make.exe[1]: Entering directory 'D:/Projects/codelite/code'
codelite-cc D:/apps/mingw-w64/mingw32/bin/g++.exe -c "D:/Projects/codelite/code/src/main.cpp" -Wfatal-errors -g -O0 -pedantic -W -std=c++11 -Wall -o ./Debug/src_main.cpp.o -I./inc/
D:/apps/mingw-w64/mingw32/bin/g++.exe -o bin/code #"code.txt" -L./lib/ -lopengl32
g++.exe: error: #code.txt -L./lib/: No such file or directory
mingw32-make.exe[1]: *** [bin/code] Error 1
code.mk:78: recipe for target 'bin/code' failed
mingw32-make.exe[1]: Leaving directory 'D:/Projects/codelite/code'
mingw32-make.exe: *** [All] Error 2
Makefile:4: recipe for target 'All' failed
====1 errors, 0 warnings====`
This looks like a bug in your toolchain and not in CodeLite.
There is a space between the "#code.text" and -L./lib and for some reason g++ does not see it...
I put my money on the mingw32-make tool. You can tell CodeLite to use the mingw32-make.exe from the 4.8.1 version (which worked): settings->build settings->compilers->[YOUR COMPILER NAME]->Make
Another option is to disable the option that tells CodeLite to generate Makefile that passes the object list via file to the compiler:
Settings->Build Settings->compilers->[YOUR COMPILER NAME]->Advanced tab and uncheck the option: pass object list to the linker via file
Lately i too have found the similar problem. Later i was able to figure out the issue. We just to need to go to the project settings under change makefile generator default to codelite makefile generator i think that will work.

undefined reference when cross-compiling for ARM with static OpenCV libraries

I'm trying to compile a simple test program using static OpenCV libraries that have been compiled using an ARM compiler. But when I try to compile it with the command
$arm-linux-gnueabihf-g++ `pkg-config --static opencv` -I/usr/local/include -L<path to static libary> -lopencv_imgproc -lopencv_core ARMtest2.cpp -o ARMtest2
This gives
/tmp/ccxNeUbK.o: In function main':
ARMtest2.cpp:(.text+0x8a): undefined reference tocv::Mat::ones(int, int, int)'
/tmp/ccxNeUbK.o: In function cv::Mat::~Mat()':
ARMtest2.cpp:(.text._ZN2cv3MatD2Ev[_ZN2cv3MatD5Ev]+0x20): undefined reference tocv::fastFree(void*)'
/tmp/ccxNeUbK.o: In function cv::Mat::release()':
ARMtest2.cpp:(.text._ZN2cv3Mat7releaseEv[_ZN2cv3Mat7releaseEv]+0x30): undefined reference tocv::Mat::deallocate()'
collect2: error: ld returned 1 exit status
The code itself is just some simple test code that prints a Mat type variable.
I compiled the static OpenCV library with cmake-gui. I selected UNIX Makefile and then selected 'specify options for cross-compiling' where I gave the path to the ARM (arm-linux-gnueabihf) gcc and g++ compiler. Then I unticked BUILD_SHARED_LIB so it compiled static libraries. It seemed to compile fine without errors. After that I did make & sudo make install.
I also tried it with shared libraries and that worked fine on the ARM board (once I copied the libraries to the board and exported the library path).
The static .a files landed nicely in the build folder. Apparently it can also find it when I -L link to it. I have tried reversing the order of the libraries, but to no avail.
So I'm a bit at a loss what is going wrong.
I solved it. Using the normal --static pkg-config command to compile with OpenCV libraries;
`pkg-config --libs --static opencv`
Of course I installed the static libraries also to the folder /usr/local/lib where libraries get installed first. But still i don't know what I missed in the command line I tried to use. I had a look in the config file /usr/local/lib/pkgconfig/opencv.pc
Here is whats in it:
# Package Information for pkg-config
prefix=/usr/local
exec_prefix=${prefix}
libdir=
includedir_old=${prefix}/include/opencv
includedir_new=${prefix}/include
Name: OpenCV
Description: Open Source Computer Vision Library
Version: 2.4.9
Libs: ${exec_prefix}/lib/libopencv_calib3d.so ${exec_prefix}/lib/libopencv_contrib.so ${exec_prefix}/lib/libopencv_core.so ${exec_prefix}/lib/libopencv_features2d.so ${exec_prefix}/lib/libopencv_flann.so ${exec_prefix}/lib/libopencv_gpu.so ${exec_prefix}/lib/libopencv_highgui.so ${exec_prefix}/lib/libopencv_imgproc.so ${exec_prefix}/lib/libopencv_legacy.so ${exec_prefix}/lib/libopencv_ml.so ${exec_prefix}/lib/libopencv_nonfree.so ${exec_prefix}/lib/libopencv_objdetect.so ${exec_prefix}/lib/libopencv_ocl.so ${exec_prefix}/lib/libopencv_photo.so ${exec_prefix}/lib/libopencv_stitching.so ${exec_prefix}/lib/libopencv_superres.so ${exec_prefix}/lib/libopencv_ts.a ${exec_prefix}/lib/libopencv_video.so ${exec_prefix}/lib/libopencv_videostab.so -lrt -lpthread -lm -ldl
Cflags: -I${includedir_old} -I${includedir_new}
I believe this is what is being called with the pkg-config <--something_or_other> opencv line.
And saw some other things that probably get linked when compiling -lrt -lpthread -lm -ldl Not really sure though as I tried it ina normal command line and I apparently still missed somethings.
But it worked, so didn't really bother too much with it much further :)
In your command:
*$arm-linux-gnueabihf-g++ `pkg-config --static opencv` -I/usr/local/include -L<path to static libary> -lopencv_imgproc -lopencv_core ARMtest2.cpp -o ARMtest2*
The cflags was missing.
Try with:
$arm-linux-gnueabihf-g++ `pkg-config --cflags --static opencv` -I/usr/local/include -L<path to static cross-compiled libary> -lopencv_imgproc -lopencv_core ARMtest2.cpp -o ARMtest2
Assuming here that your cross-compiled headers are saved in /usr/local/include (as you specified).

OMP Cross compilation with x86_64-w64-mingw32-g++

I have some trouble with crosscompiling C++ program which takes advantage of openMP library. I am using Linux Ubuntu 12.04 LTS. I want to obtain executable file runnable on Windows.
I have no problem with compiling my program with OMP with regular g++ command:
g++ a.cpp b.cpp -o OMPres -pg -O3 -I./CBLAS/include -L./ -lcblas
Also when I try crosscompilation without OMP, everything runs perfectly fine:
x86_64-w64-mingw32-g++ a.cpp b.cpp -O3 -I./CBLAS/include ./CBLAS/cblas_WIN64.a ./BLAS/blas_WIN64.a -o res.exe -l gfortran -static
But when I try to crosscompile it with OMP using following command:
x86_64-w64-mingw32-g++ a.cpp b.cpp -O3 -I./CBLAS/include ./CBLAS/cblas_WIN64.a ./BLAS/blas_WIN64.a -o OMPres.exe -l gfortran -static -fopenmp
I get this error:
a.cpp:41:17: fatal error: omp.h: No such file or directory
compilation terminated.
I found where omp.h file is located on my disk, and added the path to the command. After executing it:
x86_64-w64-mingw32-g++ a.cpp b.cpp -O3 -I./CBLAS/include -I/usr/lib/gcc/x86_64-linux-gnu/4.6/include ./CBLAS/cblas_WIN64.a ./BLAS/blas_WIN64.a -o OMPres.exe -l gfortran -static -fopenmp
I got another error: x86_64-w64-mingw32-g++: error: libgomp.spec: No such file or directory
As I also have this file on the disk I tried to copy it in various places and finaly it worked when I copied it directly into the directory where compilation takes place. Then it produced another error:
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lgomp
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lrt
collect2: ld returned 1 exit status
I don't have a good understanding of how compilers exactly work. I tried to update all mingw-w64 compilers that I could find with apt-cache search but nothing helped. I have no idea what more I can do :(.
First, #nmaier is completely correct in that the Ubuntu x86_64-w64-mingw32 toolchain is crippled, and that you can rebuild the toolchain yourself.
I, however, suggest that you use MXE, which saves you the time of manually compiling gcc and every dependency of it. The steps below should be enough for your purpose:
# Get MXE
git clone https://github.com/mxe/mxe.git && cd mxe
# Settings
cat <<EOF > settings.mk
MXE_TARGETS := x86_64-w64-mingw32.static
JOBS := 4
EOF
# Build gcc, libgomp, blas, and cblas. It will take a while
make -j2 libgomp cblas
# Add toolchain to PATH
# See http://htmlpreview.github.io/?https://github.com/mxe/mxe/blob/master/index.html#tutorial step 4
export PATH=`pwd`/usr/bin:$PATH
# You don't need -I./CBLAS/include ./CBLAS/cblas_WIN64.a ./BLAS/blas_WIN64.a
# because headers and libraries are installed to standard location and
# I already used `-lcblas -lblas`.
x86_64-w64-mingw32-g++ a.cpp b.cpp -fopenmp -O3 -o res.exe -lcblas -lblas -lgfortran -lquadmath
Your x86_64-w64-mingw32 toolchain appears to have been build without libgomp.
You could check your supplier/distribution if it there additional or variant packages that have libgomp.
Or switch to a different supplier/distribution.
Or you could rebuild (or build in the first place) a cross gcc with --enable-libgomp. This is kinda the hard way.
PS:
Adding paths that do not correspond with your platform, like -I/usr/lib/gcc/x86_64-linux-gnu/4.6/include, is a bad idea in general, and will most certainly fail... This kinda creates a Franken-compiler.

Creating shared objects with mpicc - does not seem to find pthread routines

I am learning to create shared libraries in Linux, subsequently to develop parallelised scientific computing programs. I took the toy example from here for shared library. I modified the Makefile from this question to suit the toy example. My Makefile now is
CC = mpicc
INCDIR = -I ./
CFLAGS = -Wall -rdynamic -g -fPIC $(INCDIR)
LIBADD = -L ./ -lcalc_mean
all: dyn_main.out
dyn_main.out: libcalc_mean.so
$(CC) -o $# main.c $(LIBADD)
libcalc_mean.so: calc_mean.o
$(CC) -shared --export-dynamic -o $# $<
calc_mean.o: calc_mean.c
$(CC) $(CFLAGS) -c $<
clean :
-rm *.o
-rm *.out
-rm *.so
.PHONY:
clean
When I make with CC = gcc in the Makefile, things run fine. I could run the binary even with mpirun.
When I have CC = mpicc in the Makefile, I get the following error.
mpicc -Wall -rdynamic -g -fPIC -I ./ -c calc_mean.c
mpicc -shared --export-dynamic -o libcalc_mean.so calc_mean.o
mpicc -o dyn_main.out main.c -L ./ -lcalc_mean
/home/elan/localinstalls/lib/libmpi.so: undefined reference to `pthread_key_create'
/home/elan/localinstalls/lib/libmpi.so: undefined reference to `pthread_getspecific'
/home/elan/localinstalls/lib/libmpi.so: undefined reference to `pthread_create'
/home/elan/localinstalls/lib/libmpi.so: undefined reference to `pthread_atfork'
/home/elan/localinstalls/lib/libmpi.so: undefined reference to `pthread_setspecific'
/home/elan/localinstalls/lib/libmpi.so: undefined reference to `pthread_join'
collect2: ld returned 1 exit status
make: *** [dyn_main.out] Error 1
I added the path to libpthread.so,.a to LD_LIBRARY_PATH, but no avail. I have a self compiled openmpi-1.5.4. If this were a openmpi dependency, shouldn't it have been resolved when I configured it?
Is this error familiar? I am using Ubuntu 11.04, with gcc 4.5.2. I already built and run some mpi parallel programs successfully. But they are large packages configured with autotools. One of the config.log s display the same error. But even that one runs fine.
References to / examples of creating static/shared libraries with mpi will also be appreciated (though Openmpi discourages fully static libraries.)
Thank you very much,
Elan.
You should be able to just add -lpthread.
Open MPI probably didn't add it because it found that adding -lpthread wasn't necessary (likely due to some other dependency implicitly pulling in the pthread library). But with the linker flags you're using, you might well have changed that implicit dependency, so the pthread library isn't being pulled in automatically anymore.
If adding -lpthread to the command line fixes the issue, then see this FAQ entry for how to update the wrapper compilers (E.g., add your own flags): http://www.open-mpi.org/faq/?category=mpi-apps#override-wrappers-after-v1.0
You can see what options the Open MPI compiler wrapper supplies to the underlying compiler and linker using the -showme option or one of its specific variants:
-showme:compile to just show the compiler flags
-showme:link to just show the linker flags
For example:
$ mpicc -showme
icc -I/opt/MPI/openmpi-1.5.3/linux/intel/include -I/opt/MPI/openmpi-1.5.3/linux/intel/include/openmpi -fexceptions -pthread -I/opt/MPI/openmpi-1.5.3/linux/intel/lib -Wl,-rpath,/opt/MPI/openmpi-1.5.3/linux/intel/lib -I/opt/MPI/openmpi-1.5.3/linux/intel/lib -L/opt/MPI/openmpi-1.5.3/linux/intel/lib -lmpi -ldl -Wl,--export-dynamic -lnsl -lutil

Resources