ПроблемыCMake - увязка ошибка и неопределенная ссылка
Я написал ROS исполняемого, который зависит от некоторого кода 3-участник C.
// ROS NODE - gist_extractor.cpp
extern "C"{
#include "gist/gist.h"
#include "gist/standalone_image.h"
}
/* Some Code */
float *gist_descriptor = color_gist_scaletab(im, nblocks, n_scale, orientations_per_scale);
Мой CMake файл для моего ROS исполняемого
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
image_transport
cv_bridge
sensor_msgs
cmake_modules
)
find_package(OpenCV REQUIRED)
find_package(FFTW REQUIRED)
###########
## Build ##
###########
## Specify additional locations of header files
include_directories(${CMAKE_CURRENT_SOURCE_DIR} include ${catkin_INCLUDE_DIRS}
${FFTW_INCLUDES}
)
## Add subdirectory for gist library
add_subdirectory(gist)
## Declare a C++ executable
add_executable(gist_extractor src/gist_extractor.cpp)
## Specify libraries to link a library or executable target against
target_link_libraries(gist_extractor ${catkin_LIBRARIES} gist)
Функция color_gist_scaletab() объявлен в gist.h. Несмотря на включение необходимого файла .h, когда я делаю, у меня есть следующая ошибка.
gist_extractor.cpp:+0x35e):... undefined reference to `color_gist_scaletab'
Решение Шаги
В этом разделе я проследить по шагам, как найти ошибку и как ее исправить.
1. Проверьте, если библиотека строится
После запуска MAKE в моем хранилище сборки, мы смотрели библиотеки строящиеся. Поскольку libgist.so появляется, он строится правильно.
-lboost_date_time /opt/ros/indigo/lib/libcpp_common.so -lboost_system -lboost_thread -lpthread -lconsole_bridge **/home/andy/Projects/ROS/robot_ws/devel/lib/libgist.so**
2. Проверьте, если искомая функция компилируется.
В нашем случае мы хотим color_gist_scaletab(). Мы выполнили команду «strings» в unix. Команда ниже выполняет регулярное выражение для «color_gist_scaletab()» в файле .so библиотеки. Если функция связана правильно, она должна появиться в файле .so. Мы ничего не поняли для color_gist_scaletab(), что означает, что функция не компилируется.
strings /home/andy/Projects/ROS/robot_ws/devel/lib/libgist.so | grep color_gist_scaletab
3. Определите, почему функция не компилируется.
Первое, что мы сделали, - это вернуться к объявлению функции и добавить инструкцию об ошибке (см. Ниже).
float *color_gist_scaletab(color_image_t *src, int w, int n_scale, const int *n_orientation)
{
int i;
#error COMPILER STEP SHOULD FAIL HERE
if(src->width < 8 || src->height < 8)
{
fprintf(stderr, "Error: color_gist_scaletab() - Image not big enough !\n");
return NULL;
}
Если функция скомпилирована должным образом, макрос ошибки будет выброшен. Но когда мы запускали make, мы получили ошибку связи, а это означало, что функция даже не выглядела. Weird !!
4. Обнаружение ошибки В исходном файле gist.c был указатель ifdef, который был источником нашей ошибки.
#ifdef USE_GIST
/*--------------------------------------------------------------------------*/
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <fftw3.h>
#include <pthread.h>
#ifdef STANDALONE_GIST
#include "gist.h"
#else
#include <image.h>
#include <descriptors.h>
#endif
Переменная USE_GIST никогда не определялась всем ниже, чем ifdef игнорируется. Следовательно, мы решили посмотреть исходный файл make.
gist.o: gist.c gist.h standalone_image.h
gcc -c -Wall -g $< $(WFFTINC) -DUSE_GIST -DSTANDALONE_GIST
AHA! -DUSE_GIST определялся в исходном файле make. Другими словами, нам нужно было обновить наш оригинальный файл CMAKE, чтобы также определить переменную USE_GIST. Поэтому мы вернулись в наш файл CMAKE для создания библиотеки gist и добавили add_definitions().
project(gist)
find_package(FFTW REQUIRED)
add_library(gist gist.c standalone_image.c)
add_definitions(-DUSE_GIST -DSTANDALONE_GIST)
target_link_libraries(gist ${FFTW_LIBRARIES})
После создания этого нового файла CMAKE мы успешно скомпилировали.
[email protected]:~/Projects/ROS/robot_ws/build$ make
Scanning dependencies of target gist
[ 20%] Building C object gist_extractor/gist/CMakeFiles/gist.dir/gist.c.o
[ 40%] Building C object gist_extractor/gist/CMakeFiles/gist.dir/standalone_image.c.o
Linking C shared library /home/andy/Projects/ROS/robot_ws/devel/lib/libgist.so
[ 40%] Built target gist
Linking CXX executable gist_extractor
[ 60%] Built target gist_extractor
[ 80%] Building CXX object simple_talker/CMakeFiles/listener.dir/src/listener.cpp.o
Linking CXX executable /home/andy/Projects/ROS/robot_ws/devel/lib/simple_talker/listener
[ 80%] Built target listener
[100%] Building CXX object simple_talker/CMakeFiles/talker.dir/src/talker.cpp.o
Linking CXX executable /home/andy/Projects/ROS/robot_ws/devel/lib/simple_talker/talker
[100%] Built target talker
Не можете ли вы представить пример кода, как изменить мой файл CMake? Я добавил библиотеку, а также связал библиотеку с target_link_libraries. Но это еще не проблема. Благодаря! –
Итак, в файле CMake вы буквально просто вводите путь к библиотеке, содержащей предварительно скомпилированное определение color_gist_scaletab() после «$ catkin_LIBRARIES» в записи target_link_libraries. Итак, финальная часть этой строки будет выглядеть как target_link_libraries (... $ {catkin_LIBRARIES} /usr/local/lib/library.so ...) и т. Д. Если это не сработает, то ваша версия предварительно скомпилированной библиотеки не будет Включить определение этой функции. Загрузите архив из библиотеки gist, который имеет правильную версию функции, которую вы хотите, и перекомпилируйте новый объект библиотеки для компоновщика. –
Спасибо. Это сработало! Я отправлю обновленный код через несколько дней. –