Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't Find CMAKE library. #76

Open
itspalomo opened this issue Nov 18, 2022 · 4 comments
Open

Can't Find CMAKE library. #76

itspalomo opened this issue Nov 18, 2022 · 4 comments

Comments

@itspalomo
Copy link

System Information

OpenCV python version: 4.2.0 && 4.6.0
Operating System: Ubuntu Server 20.04
Platform: Raspberry Pi 4b
Firmware: Nov 18 2021 16:17:39
version: d9b293558b4cef6aabedcc53c178e7604de90788 (clean) (release) (start_x)
Python version: 3.8.10

Detailed description

Hello, I am using ROS to configure the libseek-thermal compact pro on a drone to publish the feed so it's usable by multiple programs. This is for my university capstone project, please forgive me if it is a silly error I am not catching. I am running into an issue where I continue to get undefined reference errors in the following code:

// Image Processing libraries
#include <opencv2/opencv.hpp> // Processing and VL
#include "seek/seek.h" // Thermal Imaging

// ROS2 Specific Libraries
#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/image.hpp"
#include "std_msgs/msg/header.hpp"
#include "cv_bridge/cv_bridge.h"

// for Size
#include <opencv2/core/types.hpp>
// for CV_8UC3
#include <opencv2/core/hal/interface.h>
// for thermal image cap
#include <opencv2/highgui/highgui.hpp>
// for compressing the image
#include <image_transport/image_transport.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <chrono>
#include <memory>
#include <stdio.h>

using namespace std::chrono_literals;

class ImagePub : public rclcpp::Node {
  public:
    ImagePub() : Node("imagepub"), count_(0) {
        visible_pub =
            this->create_publisher<sensor_msgs::msg::Image>("imagepub/visible_light", 10);
            //this->create_publisher<sensor_msgs::msg::Image>("imagepub/seek_thermal", 10);

        timer_ = this->create_wall_timer(
            100ms, std::bind(&ImagePub::timer_callback, this));
    }

  private:
    void timer_callback() {
        //Check if the cameras are working properly
        if (!vl_cam->open(0)) 
            std::cerr << "ERROR: Could not open visible light camera." << std::endl;

        cv::Mat visible_light_sensor;
        //get the frame and put it into a cv matrix
        *vl_cam >> visible_light_sensor;
        if(visible_light_sensor.empty())
            std::cerr << "Something is wrong with the webcam, could not get frame." << std::endl;


        sensor_msgs::msg::Image::SharedPtr msg = cv_bridge::CvImage(std_msgs::msg::Header(), "bgr8", visible_light_sensor).toImageMsg();

        visible_pub->publish(*msg.get());
        std::cout << "Published visible light!" << std::endl;
    }

    rclcpp::TimerBase::SharedPtr timer_;

    rclcpp::Publisher<sensor_msgs::msg::Image>::SharedPtr visible_pub;
    //rclcpp::Publisher<sensor_msgs::msg::Image>::SharedPtr thermal_pub;

    size_t count_;

    cv::VideoCapture *vl_cam = new cv::VideoCapture();
    
};

int main(int argc, char *argv[]) {

    LibSeek::SeekThermal seek;
    LibSeek::SeekCam* cam;

    printf("Starting...");
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<ImagePub>());
    rclcpp::shutdown();
    return 0;
}

More specifically, I get the following issues:

/usr/bin/ld: CMakeFiles/image_pub.dir/src/image_pub.cpp.o: in function `main':
image_pub.cpp:(.text+0x1c8): undefined reference to `LibSeek::SeekThermal::SeekThermal()'
/usr/bin/ld: CMakeFiles/image_pub.dir/src/image_pub.cpp.o: in function `LibSeek::SeekThermal::~SeekThermal()':
image_pub.cpp:(.text._ZN7LibSeek11SeekThermalD2Ev[_ZN7LibSeek11SeekThermalD5Ev]+0xc): undefined reference to `vtable for LibSeek::SeekThermal'
/usr/bin/ld: image_pub.cpp:(.text._ZN7LibSeek11SeekThermalD2Ev[_ZN7LibSeek11SeekThermalD5Ev]+0x10): undefined reference to `vtable for LibSeek::SeekThermal'
/usr/bin/ld: image_pub.cpp:(.text._ZN7LibSeek11SeekThermalD2Ev[_ZN7LibSeek11SeekThermalD5Ev]+0x24): undefined reference to `LibSeek::SeekCam::~SeekCam()'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/image_pub.dir/build.make:226: image_pub] Error 1
make[1]: *** [CMakeFiles/Makefile2:78: CMakeFiles/image_pub.dir/all] Error 2
make: *** [Makefile:141: all] Error 2

I suspect this to be a CMAKE issue but am unsure what I am doing wrong... ROS uses amentcmake, and here is the CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
project(imaging)

# Default to C99
if(NOT CMAKE_C_STANDARD)
  set(CMAKE_C_STANDARD 99)
endif()

# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 17)
endif()

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(OpenCV REQUIRED)
find_package(cv_bridge REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(std_msgs REQUIRED)
find_package(image_transport REQUIRED)
find_package(libseek REQUIRED)

add_executable(image_pub src/image_pub.cpp)


target_include_directories(image_pub PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
  $<INSTALL_INTERFACE:include>)
ament_target_dependencies(
  image_pub
  "rclcpp"
  "image_transport"
  "cv_bridge"
  "sensor_msgs"
  "std_msgs"
  "OpenCV"
  "libseek"
)

install(TARGETS image_pub
  DESTINATION lib/${PROJECT_NAME})

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # uncomment the line when a copyright and license is not present in all source files
  #set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # uncomment the line when this package is not in a git repo
  #set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()

Running sudo make install again reinstalls the library as expected in the /usr/local/... directory. Is there a way to tell CMAKE to include them?

Install the project...
-- Install configuration: "Release"
-- Up-to-date: /usr/local/lib/libseek.so
-- Up-to-date: /usr/local/include/seek/SeekCam.h
-- Up-to-date: /usr/local/include/seek/SeekDevice.h
-- Up-to-date: /usr/local/include/seek/seek.h
-- Up-to-date: /usr/local/include/seek/SeekLogging.h
-- Up-to-date: /usr/local/include/seek/SeekThermal.h
-- Up-to-date: /usr/local/include/seek/SeekThermalPro.h

Note: testing commands via CLI as described in the readme work as expected.

@Bostwickenator
Copy link
Contributor

Oof linker errors, never fun to debug. First thing I would sanity check here is if this is really the shared library not being found. Just delete it and see if the error changes. I think the library is being found otherwise you'd see find_package complaining not the linker.

@Bostwickenator
Copy link
Contributor

Also if you go to the directory containing libseek.so and run objdump -T libseek.so | grep _ZN7LibSeek11SeekThermalD5Ev should show you if that function exists in the library. I'm pretty sure it doesn't.
The example programs are statically linking. So I suggest to get you moving again trying that while I figure out the virtual function issues which seem to be happening here ( haven't touched c++ in a couple of years and need to reimport some knowledge ).

@itspalomo
Copy link
Author

So I tried using find_library with accompanying target_linked_libraries instead of find_package and that worked. The issue seems to be that once the library is installed, it doesn't generate the CMAKE_MODULE_PATH variables which should be in the /usr/local/lib/cmake/[libname].cmake directory. Though, I am unsure as to how to do that, is there a way to just export it so find_package is able to find it? Here is the CMAKE working file:

cmake_minimum_required(VERSION 3.5)
project(imaging)

# Default to C99
if(NOT CMAKE_C_STANDARD)
  set(CMAKE_C_STANDARD 99)
endif()

# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 17)
endif()

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

find_library(seeklib seek NAME libseek libseek-thermal lseek DOC "seek library" REQUIRED )

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(OpenCV 4.2.0 REQUIRED)
find_package(cv_bridge REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(std_msgs REQUIRED)
find_package(image_transport REQUIRED)

add_executable(image_pub src/image_pub.cpp)

target_link_libraries(image_pub ${seeklib})

target_include_directories(image_pub PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
  $<INSTALL_INTERFACE:include>
  )

ament_target_dependencies(
  image_pub
  "rclcpp"
  "image_transport"
  "cv_bridge"
  "sensor_msgs"
  "std_msgs"
  "OpenCV"
)

install(TARGETS image_pub
  DESTINATION lib/${PROJECT_NAME})

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # uncomment the line when a copyright and license is not present in all source files
  #set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # uncomment the line when this package is not in a git repo
  #set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()

Though I find it interesting that it didn't need the path for the include directories but linked directories it did.

@itspalomo
Copy link
Author

itspalomo commented Nov 19, 2022

Also if you go to the directory containing libseek.so and run objdump -T libseek.so | grep _ZN7LibSeek11SeekThermalD5Ev should show you if that function exists in the library. I'm pretty sure it doesn't. The example programs are statically linking. So I suggest to get you moving again trying that while I figure out the virtual function issues which seem to be happening here ( haven't touched c++ in a couple of years and need to reimport some knowledge ).

also, running this command did not produce an output.

ubuntu@ubuntu:/usr/local/lib$ ls
cmake                       libopencv_features2d.so        libopencv_highgui.so.406      libopencv_ml.so.4.6.0         libopencv_videoio.so
libopencv_calib3d.so        libopencv_features2d.so.406    libopencv_highgui.so.4.6.0    libopencv_objdetect.so        libopencv_videoio.so.406
libopencv_calib3d.so.406    libopencv_features2d.so.4.6.0  libopencv_imgcodecs.so        libopencv_objdetect.so.406    libopencv_videoio.so.4.6.0
libopencv_calib3d.so.4.6.0  libopencv_flann.so             libopencv_imgcodecs.so.406    libopencv_objdetect.so.4.6.0  libopencv_video.so
libopencv_core.so           libopencv_flann.so.406         libopencv_imgcodecs.so.4.6.0  libopencv_photo.so            libopencv_video.so.406
libopencv_core.so.406       libopencv_flann.so.4.6.0       libopencv_imgproc.so          libopencv_photo.so.406        libopencv_video.so.4.6.0
libopencv_core.so.4.6.0     libopencv_gapi.so              libopencv_imgproc.so.406      libopencv_photo.so.4.6.0      libseek.so
libopencv_dnn.so            libopencv_gapi.so.406          libopencv_imgproc.so.4.6.0    libopencv_stitching.so        libuvc.so
libopencv_dnn.so.406        libopencv_gapi.so.4.6.0        libopencv_ml.so               libopencv_stitching.so.406    python2.7
libopencv_dnn.so.4.6.0      libopencv_highgui.so           libopencv_ml.so.406           libopencv_stitching.so.4.6.0  python3.8
ubuntu@ubuntu:/usr/local/lib$ objdump -T libseek.so | grep _ZN7LibSeek11SeekThermalD5Ev
ubuntu@ubuntu:/usr/local/lib$ 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants