简体   繁体   中英

How to include, build and debug shared libraries (.so) in vs code using cmake?

I am trying to debug catkin package node in vs code but I have encountered a problem. For some reason, in debug, mode program aborts when it needs to create object from a shared library. When the program fails to create an object on call stack there are my shared libraries (.so) but vscode says that libraries have unknown source from what I can conclude that cmake or vscode do not know where shared libraries are located. Shared libraries are included in CMakeLists.txt like this:

cmake_minimum_required(VERSION 3.0.2)

## Compile as C++11, supported in ROS Kinetic and newer
add_compile_options(-std=c++14)

project(1_OpenCV_detection)

message(${PROJECT_SOURCE_DIR})
# Aggregate the sources
#file(GLOB SOURCES "${PROJECT_SOURCE_DIR}/include/*.cpp")
set(SOURCES "${PROJECT_SOURCE_DIR}/include/Model.cpp"
            "${PROJECT_SOURCE_DIR}/include/Mesh.cpp"
            "${PROJECT_SOURCE_DIR}/include/CsvReader.cpp"
            "${PROJECT_SOURCE_DIR}/include/CsvWriter.cpp"
            "${PROJECT_SOURCE_DIR}/include/ModelRegistration.cpp"
            "${PROJECT_SOURCE_DIR}/include/PnPProblem.cpp"
            "${PROJECT_SOURCE_DIR}/include/RobustMatcher.cpp"
            "${PROJECT_SOURCE_DIR}/include/Utils.cpp")
message(${SOURCES})
#set(OpenCV_DIR "/usr/share/OpenCV/")
set(OpenCV_DIR "/usr/local/lib/cmake/opencv4/")
#message(${OpenCV_DIR})

set(CMAKE_CXX_STANDARD_REQUIRED ON)
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
  include
  ${opencv_INCLUDE_DIRS}
  ${catkin_INCLUDE_DIRS}
  ${OpenCV_DIR}
  /usr/local/include/opencv4/opencv2/core/utils/
  /usr/local/include/opencv4/opencv2/core/
  /usr/local/include/opencv4/opencv2/
  /opt/ros/melodic/include/
  /usr/include/boost/
  #/usr/include/opencv/opencv2/
  #/usr/share/OpenCV/
  #linux
  /usr/include/c++/7/
  /usr/include/x86_64-linux-gnu/c++/7/
  /usr/include/c++/7/backward/
  /usr/lib/gcc/x86_64-linux-gnu/7/include/
  #/usr/local/include/
  /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed/
  /usr/include/x86_64-linux-gnu/
  /usr/include/
  /usr/local/lib/
)
add_library(opencv_so SHARED IMPORTED GLOBAL)
set_target_properties(
  opencv_so 
  PROPERTIES 
    IMPORTED_LOCATION /usr/local/lib/libopencv_core.so.4.3
    IMPORTED_IMPLIB   /usr/local/lib/libopencv_core.so.4.3
) 
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
OpenCV REQUIRED
cv_bridge
image_transport
roscpp
sensor_msgs
std_msgs
)
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES 1_OpenCV_detection
  CATKIN_DEPENDS cv_bridge image_transport roscpp sensor_msgs std_msgs
#  DEPENDS system_lib
)
add_executable(OpenCV_registration src/OpenCV_registration.cpp ${SOURCES} ${OpenCV_DIR})
target_link_libraries(OpenCV_registration ${catkin_LIBRARIES} ${OpenCV_LIBS}  opencv_so)

add_executable(test_luka src/test.cpp ${SOURCES} ${OpenCV_DIR})
target_link_libraries(test_luka ${catkin_LIBRARIES} ${OpenCV_LIBS}  opencv_so)

I have searched google upside down but I couldn't find any solution how to include shared libraries in my cmake that works for me.

I am trying to debug this small program:

// C++
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>

// OpenCV
#include <opencv2/core.hpp>
#include <opencv2/core/utils/filesystem.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/video/tracking.hpp>
#include <opencv2/core/utility.hpp>

// PnP Tutorial
#include "Mesh.h"
#include "Model.h"
#include "PnPProblem.h"
#include "RobustMatcher.h"
#include "ModelRegistration.h"
#include "Utils.h"

//ROS-->openCV
//bridge between ROS and opencv; used for reading from camera topic in ROS and giving it to opencv
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>

/**  GLOBAL VARIABLES  **/

using namespace cv;
using namespace std;

/**  Functions headers  **/
void help();
void initKalmanFilter( KalmanFilter &KF, int nStates, int nMeasurements, int nInputs, double dt);
void predictKalmanFilter( KalmanFilter &KF, Mat &translation_predicted, Mat &rotation_predicted );
void updateKalmanFilter( KalmanFilter &KF, Mat &measurements,
                         Mat &translation_estimated, Mat &rotation_estimated );
void fillMeasurements( Mat &measurements,
                       const Mat &translation_measured, const Mat &rotation_measured);
string CurrentPath;
string getCurrentPath()
{
    size_t size;
        char *path=NULL;
    path=getcwd(path,size);
    CurrentPath=path;
    return path;
}
/**  Main program  **/
int main(int argc, char *argv[])
{
    //CommandLineParser parser(argc, argv, keys);
    cout << "Current directory is: " << getCurrentPath() << endl;

    string video_read_path = samples::findFile("src/1_OpenCV_detection/Data/box.mp4");                             // recorded video
    string yml_read_path = samples::findFile("src/1_OpenCV_detection/Data/cube_30mm/cube_30mm.yml");               // 3dpts + descriptors
    string ply_read_path = samples::findFile("src/1_OpenCV_detection/Data/cube_30mm/meshes/cube_30mm.ply");        // object mesh

    Model model;                // instantiate Model object
    cout<<"Before model.load()"<<endl;
    model.load(yml_read_path); // load a 3D textured object model
    cout<<"After model.load()"<<endl;
    Mesh mesh;                 // instantiate Mesh object
    mesh.load(ply_read_path);  // load an object mesh

    return 0;
}

Program always fails with on same place, in method model.load(yml_read_path) and vscode raises popup window in right bottom corner which says:

Unable to open 'strlen-avx2.S': Unable to read file '/build/glibc-OTsEL5/glibc-2.27/sysdeps/x86_64/multiarch/strlen-avx2.S' (Error: Unable to resolve non-existing file '/build/glibc-OTsEL5/glibc-2.27/sysdeps/x86_64/multiarch/strlen-avx2.S').

but my opinion is that there is no problem with strlen and that.so libraries are not included somehow.

Ignore all these include headers, I just copied them from another program but I am not using it in my test_luka.cpp

Any help would be appreciated.

EDIT:

I have tried @Boris suggestion ( https://github.com/microsoft/vscode-cpptools/issues/811 ) but without any success, shared libraries are still unknown only difference is that after exception I program goes to strlen-avx2.S.

$ sudo apt install glibc-source 
$ cd /usr/src/glibc 
$ sudo tar xvf glibc-2.27.tar.xz 

Then make link for folders using sourceFileMap in launch.json:

"sourceFileMap": {
    "/build/glibc-OTsEL5": "/usr/src/glibc"
},

When I run ldd in exe directory like this:

  ldd OpenCV_registration | grep libopencv_core

I get this output:

libopencv_core.so.3.2 => /usr/lib/x86_64-linux-gnu/libopencv_core.so.3.2 (0x00007f0f4d85e000) libopencv_core.so.4.3 => /usr/local/lib/libopencv_core.so.4.3 (0x00007f0f4bc62000) So it seems to recognizes which libraries are needed but looks like doesn't know where to find them

Try the fix mentioned in vs-code's github bug reports https://github.com/microsoft/vscode-cpptools/issues/811

I encountered same error when I tried to use cv_bridge with an incompatible version of OpenCV(I installed a higher version OpenCV using source install method), make sure that you are linking against OpenCV that is bundled with ROS version you use.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM