我在使用cmake链接fftw库时遇到问题。我使用findFFTW.cmake文件来查找库。我知道这是成功找到库,因为我将REQUIRED标志设置为true以查找库并且make过程正常。
尽管将其与我的可执行文件链接,但我仍然收到未定义的引用错误。一些相关的帖子,我试过的解决方案。
Undefined reference to "function name from external library"
http://answers.ros.org/question/171326/catkin-linking-order-undefined-reference-to-symbol/
更新
感谢ComicSansMS,下面的CMake现在应该正确建模依赖关系。
CMake项目文件(更新3/7)
cmake_minimum_required(VERSION 2.8.3)
project(gist_extractor)
## Find catkin macros and libraries
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
image_transport
cv_bridge
sensor_msgs
cmake_modules
)
find_package(OpenCV REQUIRED)
find_package(Eigen REQUIRED)
find_package(FFTW REQUIRED)
###########
## Build ##
###########
## Set GIST variables for building library
set(GIST_PATH /home/andy/Development/lear_gist-1.2)
## Specify additional locations of header files
include_directories(include ${catkin_INCLUDE_DIRS} ${GIST_PATH} ${FFTW_INCLUDES})
## Declare a gist library
add_library(gist SHARED ${GIST_PATH}/standalone_image.c ${GIST_PATH}/gist.c) # THIS IS NOT BEING BUILT
target_link_libraries(gist ${FFTW_LIBRARIES})
## Add cmake target dependencies of the library
#MESSAGE( STATUS "GIST_LIBRARY_PATH: " ${GIST_PATH})
## Declare a C++ executable
add_executable(gist_extractor src/gist_extractor.cpp)
target_link_libraries(gist_extractor ${catkin_LIBRARIES} gist)
编辑2
如果我们使用上面的CMake文件,我们现在有一个链接错误。特别是当我尝试运行
时,make过程失败了target_link_libraries(gist_extractor ${catkin_LIBRARIES} gist)
我有几点意见。首先,根据以下控制台消息正确构建我的gist库。
Linking C shared library /home/andy/Projects/ROS/robot_ws/devel/lib/libgist.so
[ 80%] Built target gist
Scanning dependencies of target gist_extractor
[100%] Building CXX object
`gist_extractor/CMakeFiles/gist_extractor.dir/src/gist_extractor.cpp.o
但是当我们尝试将可执行文件与gist库链接时,我们可以看到存在未定义的引用错误。
Linking CXX executable gist_extractor
: undefined reference to `color_gist_scaletab'
这就是为什么我不明白为什么会这样。在gist_extractor.cpp中,我已经包含了包含' color_gist_scaletab'功能。具体来说,这个" color_gist_scaletab是在' gist.h'中定义的。并在' gist.c'中实施。我认为构建我的库gist可以让我访问' color_gist_scaletab'。我已在下面发布了相关文件。
gist.h
#ifndef GIST_H_INCLUDED
#define GIST_H_INCLUDED
#include "standalone_image.h"
/*! Graylevel GIST for various scales. Based on Torralba's Matlab
* implementation. http://people.csail.mit.edu/torralba/code/spatialenvelope/
*
* Descriptor size is w*w*sum(n_orientations[i],i=0..n_scale-1)
*
* @param src Source image
* @param w Number of bins in x and y axis
*/
float *bw_gist_scaletab(image_t *src, int nblocks, int n_scale, const int *n_orientations);
/*! @brief implementation of grayscale GIST descriptor.
* Descriptor size is w*w*(a+b+c)
*
* @param src Source image
* @param w Number of bins in x and y axis
*/
float *bw_gist(image_t *scr, int nblocks, int a, int b, int c);
/*! @brief implementation of color GIST descriptor.
*
* @param src Source image
* @param w Number of bins in x and y axis
*/
float *color_gist(color_image_t *src, int nblocks, int a, int b, int c);
/*! Color GIST for various scales. Based on Torralba's Matlab
* implementation. http://people.csail.mit.edu/torralba/code/spatialenvelope/ */
float *color_gist_scaletab(color_image_t *src, int nblocks, int n_scale, const int *n_orientations);
#endif
gist_extractor.cpp
// color_gist_scaletab is defined in gist.h
// I'm including relevant header file
#include "/home/andy/Development/lear_gist-1.2/gist.h"
//SOME MORE STUFF
// This is where I call the function
float *gist_descriptor = color_gist_scaletab(im, nblocks, n_scale, orientations_per_scale);
答案 0 :(得分:0)
您似乎没有正确建模您的依赖项。
您使用gist.c
内部的fftw,gist
是gist_extractor
库目标的一部分。
但是,该目标不依赖于fftw,只有下游目标gist
具有依赖性。这是一个麻烦的方法,特别是在静态构建中,其中工具链经常挑剔库在链接器命令行上出现的顺序。
将fftw作为依赖项添加到target_link_libraries(gist ${FFTW_LIBRARIES})
:
add_dependencies(gist_extractor gist)
target_link_libraries(gist_extractor ${GIST_PATH}/libleargist.a)
此外,没有必要这样做:
target_link_libraries(gist_extractor gist)
如果两个目标都是作为同一项目的一部分构建的,那么只需执行以下操作:
Map<String, String> urlVariables = new HashMap<>();
urlVariables.put("ip_address", IP);
urlVariables.put("port", PORT);
ResponseObject state =
restTemplate.getForObject("http://{ip_address}:{port}/state/", ResponseObject.class, urlVariables);
通过使用目标名称而不是硬编码输出文件,您不仅可以使构建脚本更具可移植性,还可以让CMake更好地跟踪目标之间的依赖关系。