ubuntu vscode c++生成so及调用调试so包

1 ubuntu vscode c++配置

建议参考https://blog.csdn.net/weixin_43374723/article/details/84064644,介绍的很详细。

参考vscode官方介绍https://code.visualstudio.com/docs/cpp/config-linux,补充说明下task.json和launch.json的区别:

  • task.json表示编译时的配置项,生成默认task.json的操作是在某个cpp页面上使用快捷键ctrl+shift+p,打开"任务:运行任务",选择"c/c++:g++ build active file"可以生成生成默认task.json,其主要内容包括:
    {
      "version": "2.0.0",
      "tasks": [
        {
          "type": "shell",
          "label": "g++ build active file",
          "command": "/usr/bin/g++",
          "args": ["-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}"],
          "options": {
            "cwd": "/usr/bin"
          },
          "problemMatcher": ["$gcc"],
          "group": {
            "kind": "build",
            "isDefault": true
          }
        }
      ]
    }
    
    label指定了任务的别名,在launch.json中还需要使用;
    command指定了使用g++进行编译;
    args指定了编译时的参数,各参数的含义可以参考https://code.visualstudio.com/docs/editor/variables-reference和https://www.runoob.com/w3cnote/gcc-parameter-detail.html;
  • launch.json指定了调试设置,生成默认launch.json可以通过“Run > Add Configuration>选择C++ (GDB/LLDB)”。默认内容为:
    {
      "version": "0.2.0",
      "configurations": [
        {
          "name": "g++ build and debug active file",
          "type": "cppdbg",
          "request": "launch",
          "program": "${fileDirname}/${fileBasenameNoExtension}",
          "args": [],
          "stopAtEntry": false,
          "cwd": "${workspaceFolder}",
          "environment": [],
          "externalConsole": false,
          "MIMode": "gdb",
          "setupCommands": [
            {
              "description": "Enable pretty-printing for gdb",
              "text": "-enable-pretty-printing",
              "ignoreFailures": true
            }
          ],
          "preLaunchTask": "g++ build active file",
          "miDebuggerPath": "/usr/bin/gdb"
        }
      ]
    }
    
    preLaunchTask指出了在调试之前预先执行的任务,注意这里和task.json中的label是一样的,表示在调试之前首先进行编译;
    program指定了要调试哪个程序;
    stopAtEntry设置为true表示在进入main函数时自动进入断点。

2 同一个文件夹下生成so包并且使用so包

代码结构:
ubuntu vscode c++生成so及调用调试so包_第1张图片
ubuntu vscode c++生成so及调用调试so包_第2张图片
ubuntu vscode c++生成so及调用调试so包_第3张图片

vscode使用文件夹来管理工程,配置项存储在.vscode文件下。工程开发时,往往涉及到一个工程中生成so包,另一个工程下调用so包,并单步调试代码,个人习惯把这两个工程放到同一个文件夹下进行管理,所以这里设置gen文件夹下生成so包,use/main.cpp调用so包,通过配置文件来实现不同的任务。

2.1 生成so包时的配置文件

task.json:

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "shell",
            "label": "build",
            "command": "/usr/bin/g++",
            "args": [
                "-g",								  //要设置该选项,否则无法单步调试so包中的代码
                "${workspaceFolder}/gen/hello.cpp",   //so包函数实现的文件
                "-o",
                "${workspaceFolder}/lib/libhello.so", //生成的包一定要是lib+包名+.so的形式
                "-fPIC",                              //生成和位置无关的so文件
                "-shared"							  //生成动态链接库,即so文件
            ],
            "options": {
                "cwd": "/usr/bin"
            },
            "problemMatcher": [
                "$gcc"
            ]
        }
    ]
}

fPIC的含义,请参考:https://www.cnblogs.com/fengliu-/p/10216878.html
shared的含义,请参考:https://www.cnblogs.com/ziyunlong/p/6023121.html,就是创建动态链接库,对应于windows下的dll,所以在运行程序的时候的时候要通过系统的环境变量能找到对应的so文件。
launch.json:

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "g++ - 生成和调试活动文件",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/lib/libhello.so",//"${fileDirname}/${fileBasenameNoExtension}",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "build",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

2.2 调用so包时的配置文件

tasks.json

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "shell",
            "label": "build",
            "command": "/usr/bin/g++",
            "args": [
                "-g",
                "${workspaceFolder}/use/main.cpp", //主函数
                "-o",
                "${workspaceFolder}/lib/main",	//生成的可执行文件路径及名称
                "-I${workspaceFolder}/gen",		//头文件路径,多个路径时逗号分割	
                "-L${workspaceFolder}/lib",		//库文件路径,多个路径时逗号分割
                "-lhello"                       //具体的库文件,这里是指libhello.so
            ],
            "options": {
                "cwd": "/usr/bin"
            },
            "problemMatcher": [
                "$gcc"
            ]
        }
    ]
}

如果main中需要使用opencv,可以在args中列出:

					"-I", "/usr/local/include",
			        "-I", "/usr/local/include/opencv",
			        "-I", "/usr/local/include/opencv2",
			        "-L", "/usr/local/lib",
			        "-l", "opencv_core",
			        "-l", "opencv_imgproc",
			        "-l", "opencv_imgcodecs",
			        "-l", "opencv_video",
			        "-l", "opencv_ml",
			        "-l", "opencv_highgui",
			        "-l", "opencv_objdetect",
			        "-l", "opencv_flann",
			        "-l", "opencv_imgcodecs",
			        "-l", "opencv_photo",
			        "-l", "opencv_videoio"

“-l”, “opencv_videoio"和”-lopencv_videoio"是等价的,都是去找/usr/local/lib/libopencv_videoio.so文件。

launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "g++ - 生成和调试活动文件",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/lib/main",//设置调试的程序名称
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "build",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

调用so包时需要能够让可执行程序能够找到这个so包,需要设置~/.bashrc中的LD_LIBRARY_PATH中包含要引用的so包的路径,然后执行source ~/.bashrc,也可以参考https://blog.csdn.net/arackethis/article/details/43342655获取更多配置方法。关于Linux共享库的搜索路径先后顺序可以参考https://blog.csdn.net/rryqszq4/article/details/51142468,这里摘抄下:
Linux共享库的搜索路径先后顺序:
1、编译目标代码时指定的动态库搜索路径:在编译的时候指定-Wl,-rpath=路径
2、环境变量LD_LIBRARY_PATH指定的动态库搜索路径
3、配置文件/etc/ld.so.conf中指定的动态库搜索路径
4、默认的动态库搜索路径/lib
5、默认的动态库搜索路径 /usr/lib

shell中执行:ldd main可以看看main依赖哪些路径下的哪些动态链接库;nm -D libhello.so可以查看so包中导出的所有函数。

初次在linux下进行c++的开发,本文记录简单的环境配置,以便查询,后续继续补充内容,欢迎批评指正。

你可能感兴趣的:(ubuntu)