2011-09-14 21 views
9

Estoy escribiendo un programa que usa OpenCV (instalado en un directorio local, ya que no tengo permisos de raíz en esa máquina) y he escrito el archivo CMakeLists.txt correspondiente. Mi problema es que la compilación falla en la etapa de vinculación de diferentes maneras (he pasado tres horas probando todas las diferentes soluciones propuestas en la web, así que he visto muchos resultados). Aquí tiene las configuraciones/resultados que tienen más sentido para mí, a pesar de que llevan a un fracaso: [en project_root/CMakeLists.txt]:Problema de vinculación con OpenCV y CMake

cmake_minimum_required(VERSION 2.8) 
project(CUDA_learning) 

set(OpenCV_INCLUDE_DIR "path/to/opencv_CUDA/include") 
include_directories(${OpenCV_INCLUDE_DIR}) 
set(OpenCV_LIBS_DIR "path/to/opencv_CUDA/lib") 
link_directories(${OpenCV_LIBS_DIR}) 
set(OpenCV_LIBS "opencv_core opencv_imgproc opencv_calib3d opencv_video opencv_features2d opencv_ml opencv_highgui opencv_objdetect opencv_contrib opencv_legacy opencv_gpu") 

find_package(Boost COMPONENTS system filesystem program_options regex REQUIRED) 
if(Boost_FOUND) 
    include_directories(${Boost_INCLUDE_DIR}) 
else(Boost_FOUND) 
    message(FATAL_ERROR "Cannot build application without Boost. Please set Boost_INCLUDE_DIR.") 
endif(Boost_FOUND) 

set(CMAKE_BUILD_TYPE debug) 

add_definitions("-Wall") 

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/../bin) 

subdirs (
    ../src 
) 

[en project_root/src/CMakeLists.txt] :

FILE(GLOB dir_source *.cc 2D/*.cc) 
FILE(GLOB dir_header *.hh 2D/*.hh) 

add_executable(${PROJECT_NAME} ${dir_source} ${dir_header}) 
target_link_libraries(${PROJECT_NAME} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${OpenCV_LIBS}) 

Resultado:

Linking CXX executable ../../bin/CUDA_learning 
c++: opencv_imgproc: No such file or directory 
c++: opencv_calib3d: No such file or directory 
c++: opencv_video: No such file or directory 
c++: opencv_features2d: No such file or directory 
c++: opencv_ml: No such file or directory 
c++: opencv_highgui: No such file or directory 
c++: opencv_objdetect: No such file or directory 
c++: opencv_contrib: No such file or directory 
c++: opencv_legacy: No such file or directory 
c++: opencv_gpu: No such file or directory 

Si, contrariamente a las recomendaciones dadas en la red, me puso una "l" antes de la biblioteca OpenCV nombre I consiga:

Linking CXX executable ../../bin/CUDA_learning 
/usr/bin/ld: cannot find -lopencv_core 
collect2: ld returned 1 exit status 
make[2]: *** [../bin/CUDA_learning] Error 1 
make[1]: *** [src/CMakeFiles/CUDA_learning.dir/all] Error 2 
make: *** [all] Error 2 

¿Alguien sabe cómo resolver esto? Estoy literalmente enloqueciendo por esto ... ¡Muchas gracias de antemano! Cheers, Rob

Respuesta

5

Esta línea:

set(OpenCV_LIBS "opencv_core opencv_imgproc opencv_calib3d opencv_video opencv_features2d opencv_ml opencv_highgui opencv_objdetect opencv_contrib opencv_legacy opencv_gpu") 

... dice que usted tiene una biblioteca en la variable OpenCV_LIBS con un nombre gigantesca con una gran cantidad de espacios en él. Si quita las comillas, así:

set(OpenCV_LIBS opencv_core opencv_imgproc opencv_calib3d opencv_video opencv_features2d opencv_ml opencv_highgui opencv_objdetect opencv_contrib opencv_legacy opencv_gpu) 

... entonces será una lista de nombres de biblioteca, y debería funcionar bien.

CMake usa el carácter de espacio para separar los argumentos de sus comandos. Por eso, para incluir un espacio en un valor en el comando set, debe doblarlo. En este caso, no desea hacer eso porque quiere que el comando set vea los múltiples valores que está pasando, no un gran valor que contenga espacios.

EDIT: (más información sobre la base de la discusión en los comentarios):

Si esto no funciona, compruebe que los nombres que está utilizando son correctos. Con los nombres de biblioteca que está utilizando aquí, debe haber archivos llamados libopencv_core.so, libopencv_imgproc.so, y así sucesivamente, en el directorio nombrado por la variable OpenCV_LIBS_DIR. Si esos nombres de biblioteca exactos no existen como archivos, entonces eso explica el error del vinculador. (En este caso, como se discutió en los comentarios, los archivos reales se nombraron con números de versión en los nombres de archivo y no había ningún enlace simbólico "sin versión" apuntando hacia ellos).

+0

Hola, gracias por su respuesta, lo he intentado pero sigo teniendo el error "no puedo encontrar -lopencv_core" ... – Rob

+0

Hmmmm ... ¿y si cambia "subdirs" por "add_subdirectory" ? – DLRdave

+0

he cambiado como add_subdirectory ( $ {} CMAKE_BINARY_DIR /../ src ) pero todavía no hay cambio en el resultado :( – Rob

5

Aquí está la forma correcta de incluir OpenCV en su proyecto:

set(OpenCV_DIR "path/to/opencv_CUDA/share/OpenCV" 
    CACHE PATH "The path where OpenCVConfig.cmake is placed") 
find_package(OpenCV REQUIRED) 

# and for each executable/library dependent on OpenCV 
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OpenCV_LIBS}) 
+1

Tampoco funciona ... :(En una semana, los administradores de sistemas van a hacer una actualización del servidor en el que estoy trabajando, y espero que las cosas mejoren en ese momento. ¡Muchas gracias! – Rob

+0

De tus comentarios veo que está utilizando la versión anterior de la troncal de OpenCV. Le recomiendo que use una de las versiones oficiales o actualice a la última revisión. Hay más de 200 errores corregidos desde 2.2.9 (incluidos varios errores de instalación). –

+0

Lo sé, pero gracias por señalando eso. Estoy usando una versión anterior de OpenCV porque no tengo acceso de root en los servidores, y mientras espero que los administradores instalen CUDA4.0, quería probar algún código ... – Rob

0

el problema podría ser que el enlazador está buscando un archivo llamado libopencv_core.so pero hay un archivo con un nombre similar libopencv_core.so.1 en ese caso es necesario utilizar enlaces simbólicos. por ejemplo, haga esto ln -sf /opt/lib/libopencv_core.so.1 /opt/lib/libopencv_core.so