精华内容
下载资源
问答
  • vscode编译静态库
    2022-07-05 14:12:03

    1.动态链接库的生成

    /****tasks.json*********/
    {
        "tasks": [
            {
                "type": "cppbuild",
                "label": "C/C++: g++ 生成活动文件",
                "command": "/usr/bin/g++",
                "args": [
                    "-fdiagnostics-color=always",
                    "-g",
                    "${file}",
                    "-o",
                    "${fileDirname}/lib/libcommon.so",
                    "-std=c++11",
                    "-fPIC",
                    "-shared"
                ],
                "options": {
                    "cwd": "${fileDirname}"
                },
                "problemMatcher": [
                    "$gcc"
                ],
                "group": "build",
                "detail": "调试器生成的任务。"
            }
        ],
        "version": "2.0.0"
    }

    在tasks.json中,动态链接库名称必须加lib,如libcommon.so,参数加-fPIC(可选),-shared(必选)。编译即可生成libcommon.so。

    2.动态链接库的引用

    {
        "tasks": [
            {
                "type": "cppbuild",
                "label": "C/C++: g++ 生成活动文件",
                "command": "/usr/bin/g++",
                "args": [
                    "-fdiagnostics-color=always",
                    "-g",               
                    "${file}",
                    "SocketHelper.cpp",
                    "-o",               
                    "${fileDirname}/${fileBasenameNoExtension}",
                    "-I","${fileDirname}/CommonFunc",
                    "-L","${fileDirname}/CommonFunc/lib",
                    "-l","common",
                    "-Wl,-rpath=${fileDirname}/CommonFunc/lib",
                    "-std=c++11",
                    "-pthread"
                ],
                "options": {
                    "cwd": "${fileDirname}"
                },
                "problemMatcher": [
                    "$gcc"
                ],
                "group": "build",
                "detail": "调试器生成的任务。"
            }
        ],
        "version": "2.0.0"
    }

    "-I":动态链接库的头文件所在目录;(大写i)

    "-L":动态链接库文件所在目录;

    "-l":动态链接库名(小写l);

    "rpath":程序运行时,优先到rpath指定的目录去寻找依赖库; 程序链接时,在指定的目录中,隐式的链接那些动态库所需要的链接库。

    特别注意"-Wl,rpath=xx",在运行调试时程序不会找"-L"参数目录下的链接库,会报错error while loading shared libraries: lib*.so: cannot open shared object file: No such file or directory。

    更多相关内容
  • libvscode VSCode静态内部版本,可用于将其包含在其他项目中。 该项目是一个分支,它打包结果并提供用于运行时配置的其他机制。用法安装libvscode: $ npm install @casual-simulation/libvscode将libvscode dist...
  • 静态库和动态库基于Windows和VScode

    千次阅读 2022-02-12 22:01:06
    基于Windows和VScode关于C/C++的静态库和动态库创建和使用。

    VScode配置C/C++环境

    • 静态库和动态库的基本概念
    • 静态库和动态库的创建
    • 静态库和动态库的使用
    • Makefile写法

    一、静态库和动态库的基本概念

    静态库和动态库简单理解就是对目标文件的打包操作

    1.1 静态库

    一般情况下的静态库命名规则:

    • lib开头
    • .lib结尾 —>Windows
    • .a结尾 —>Linux

    例如:

    1. libxxx.lib 的名字就是xxx
    2. libyyy.a 的名字就是yyy

    在Windows下.lib和.a都可以表示静态库,但是使用的时候

    • .lib的静态库需要用lib加名字
    • .a的静态库只需要用名字

    静态库的特点:

    1. 编译阶段完成
    2. 在链接的时候把静态库的**“内容”**放到最终的可执行文件中
    3. 静态库一旦嵌到可执行文件中就可以直接运行程序,静态库和程序本身再无关系
    4. 把静态库嵌入到可执行文件中会使可执行文件的体积变大

    lib: library 库

    a : archive 档案

    1.2 动态库

    动态库:有**“动态链接库”“共享对象”**的叫法。

    一般情况下的动态库命名规则:

    • lib开头
    • .dll结尾 —>Windows
    • .so结尾 ---->Linux

    例如:

    1. libxxx.dll 是名为xxx的动态库
    2. libyyy.so 是名为yyy的动态库

    DLL: Dynamic Link Library 动态链接库

    SO: Shared Object 共享对象

    动态库的特点:

    1. 程序运行的时候才会使用到动态库中的内容
    2. 在链接的时候把动态库的**“访问方式”**放到可执行文件中
    3. 使用动态库而生成的可执行文件必须依赖到动态库才能成功的运行程序
    4. 使用动态库的可执行文件体积相对于使用静态库的小

    1.3 静态库和动态库的简单区别

    从静态库和动态库的特点就可以看得的是,静态库的优点就是动态库的缺点,动态库的优点就是静态库的缺点

    二、静态库和动态库的创建

    • 使用命令行创建静态库和动态库

    关于静态库和动态库的创建要注意的事项:

    1. 操作系统不同,静态库和动态库的内部格式不同
    2. 同操作系统,不同编译器,静态库和动态库的生成方式也不同
    3. 同操作系统,不同编译器,静态库和动态库的使用方式也不同
    4. 静态库和动态库的创建和使用一定是基于指定的操作系统和编译器才可以

    2.1 基于Widows,MinGW的静态库的创建

    头文件:myMath.h

    #ifndef _myMath_H_
    #define _myMath_H_
    
    typedef struct MyMath
    {
        int a;
        int b;
    }myMath;
    
    MyMath* creatMathObject(int a,int b);
    int add(MyMath* mobj);
    int sub(MyMath* mobj);
    void delMathObject(MyMath* mobj);
    
    #endif
    

    源文件:myMath.c

    #include "myMath.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    
    MyMath* creatMathObject(int a,int b)
    {
        MyMath* mobj=(MyMath*)malloc(sizeof(MyMath));
        assert(mobj);
        mobj->a=a;
        mobj->b=b;
        return mobj;
    }
    int add(MyMath* mobj)
    {
        return mobj->a+mobj->b;
    }
    int sub(MyMath* mobj)
    {
        return mobj->a-mobj->b;
    }
    void delMathObject(MyMath* mobj)
    {
        if(mobj==NULL)
            return ;
        free(mobj);
        mobj=NULL;
    }
    

    进入终端

    gcc -c myMath.c -o myMath.o -static	
    # 生成静态库要加-static选项,位置在不脱离现实的情况下随便放
    ar -crus libmymath1.lib myMath.o
    # 生成静态库文件,方式一
    ar -crus libmymath2.a myMath.o
    # 生成静态库文件,方式二
    # c create
    # r replace
    # u update
    # s search
    

    2.2 基于Widows,MinGW的动态库的创建

    头文件和源文件还是上面的

    进入终端:

    gcc -c myMath.c -o myMath.o -fpic
    # 先生成.o文件,-fpic选加
    gcc myMath.o -o libmymath3.dll -shared
    # 生成动态库文件
    
    #也可以将两个命令结合在一起
    gcc -c myMath.c -o libmymath3.dll -fpic -shared
    
    # -shared是生成动态库的关键选项,在不脱离现实的情况下位置无关
    # -fpic是选加的
    # f file
    # p position
    # i independent
    # c code
    

    三、静态库和动态库的使用

    3.1 静态库的使用

    使用之前的条件:

    • 拿到.h文件
    • 拿到静态库文件

    3.1.1 单目录

    和本地的项目源文件放在以下,操作起来很简单。

    直接把头文件包含过来

    //main.c
    #include <stdio.h>
    #include "myMath.h"	//没有源文件,源文件已经被编译成静态库文件了
    
    int main()
    {
        MyMath* mobj=creatMathObject(7,5);
        int result=add(mobj);
        printf("%d\n",result);
        result=sub(mobj);
        printf("%d\n",result);
        delMathObject(mobj);
        printf("over\n");
        return 0;
    }
    

    进入终端:

    # 正常编译操作生成main.o
    gcc -c main.c -o main.o
    # 链接的时候需要把静态库也链接过来
    gcc main.o -L. -llibmymath1 -o main.exe	# .lib
    # gcc main.o -L. -lmymath1 -o main.exe	# 会报错
    gcc main.o -L. -lmymath2 -o main2.exe 	# .a
    

    3.1.2 多目录

    目录结构

    .
    |--bin
    |--include
    	|--myMath.h
    |--lib
    	|--libmymath1.lib
    	|--libmymath2.a
    |--obj
    |--src
    	|--main.c	# main.c文件还是上面的
    

    进入终端:

    # 正常编译操作生成main.o
    gcc -c src/main.c -o obj/main.o -I include
    # 链接的时候需要把静态库也链接过来
    gcc main.o -L./lib -llibmymath1 -o bin/main.exe	# .lib
    gcc main.o -L./lib -lmymath2 -o bin/main2.exe 	# .a
    

    3.2 动态库的使用

    基于Windows下使用动态库

    使用条件:

    • 拿到.h文件
    • 拿到动态库文件

    3.2.1 单目录

    还是上面的main.c文件

    进入终端:

    # 正常编译操作生成main.o
    gcc -c main.c -o main.o
    # 链接的时候需要把动态库也链接过来
    gcc main.o -L. -llibmymath3 -o main.exe	# .lib
    ./main.exe # 成功运行
    

    3.2.2 多目录

    目录结构:

    .
    |--bin
    	|--libmymath3.dll
    |--include
    	|--myMath.h
    |--obj
    |--src
    	|--main.c	# main.c文件还是上面的
    

    进入终端:

    # 正常编译操作生成main.o
    gcc -c src/main.c -o obj/main.o -I include
    # 链接的时候需要把动态库也链接过来
    gcc main.o -L./bin -llibmymath3 -o bin/main.exe	# .lib
    cd bin
    ./main.exe #正常运行
    

    四、Makefile写法

    单文件就不写Makefile了,太简单了直接使用gcc命令比较简单也比快捷

    4.1 使用静态库时Makefile写法

    BIN=./bin
    OBJ=./obj
    INC=./include
    SRC=./src
    LIB=./lib
    
    SRCS=$(wildcard $(SRC)/*.c)
    OBJS=$(patsubst %.c,$(OBJ)/%.o,$(notdir $(SRCS)))
    
    TARGET=main
    TARGET_PATH=$(BIN)/$(TARGET)
    
    CC=gcc
    CFLAGS=-g -Wall -I$(INC)
    
    LIB_PATH=-L $(LIB)
    LIB_FLAGS=-l libzzz
    
    $(TARGET_PATH):$(OBJS)
    	$(CC) $^ $(LIB_PATH) $(LIB_FLAGS) -o $@
    
    $(OBJ)/%.o:$(SRC)/%.c
    	$(CC) -c $(CFLAGS) $^ -o $@
    
    .PHONY: clean
    
    clean:
    	del /Q /F obj
    

    4.2 使用动态库时Makefile写法

    BIN=./bin
    OBJ=./obj
    INC=./include
    SRC=./src
    
    SRCS=$(wildcard $(SRC)/*.c)
    OBJS=$(patsubst %.c,$(OBJ)/%.o,$(notdir $(SRCS)))
    
    TARGET=main
    TARGET_PATH=$(BIN)/$(TARGET)
    
    CC=gcc
    CFLAGS=-g -Wall -I$(INC)
    
    LIB_PATH=-L$(BIN)
    LIB_FLAGS=-lmymath
    
    $(TARGET_PATH):$(OBJS)
    	$(CC) $^ $(LIB_PATH) $(LIB_FLAGS) -o $@
    
    $(OBJ)/%.o:$(SRC)/%.c
    	$(CC) -c $(CFLAGS) $^ -o $@
    
    .PHONY: clean
    
    clean:
    	del /Q /F obj
    

    4.3 使用静态库和动态库时Makefile写法

    BIN=./bin
    OBJ=./obj
    INC=./include
    SRC=./src
    LIB=./lib
    
    SRCS=$(wildcard $(SRC)/*.c)
    OBJS=$(patsubst %.c,$(OBJ)/%.o,$(notdir $(SRCS)))
    
    TARGET=main
    TARGET_PATH=$(BIN)/$(TARGET)
    
    CC=gcc
    CFLAGS=-g -Wall -I$(INC)
    
    LIB_PATH=-L$(BIN) -L$(LIB)
    LIB_FLAGS=-lmathdm -llibmathas 
    
    $(TARGET_PATH):$(OBJS)
    	$(CC) $^ $(LIB_PATH) $(LIB_FLAGS) -o $@
    
    $(OBJ)/%.o:$(SRC)/%.c
    	$(CC) -c $(CFLAGS) $^ -o $@
    
    .PHONY: clean
    clean:
    	del /Q /F obj
    

    搭配视频看会更好哟!!!

    C/C++静态库和动态库基于Windows和VScode

    展开全文
  • vscode C++编译调试教程

    关于本帖的各个模块组成先解释一下

     vscode本质上是个编辑器,只能用于编辑文本,本体功能类似于notpad++,它并不是个像 vs那样的集成开发环境,MinGW是将g++等一系列用于在linux上编译c/c++的编译器适配到windows平台的编译器,windows平台有自己的编译器叫msvc不过用vscode的人一般不用msvc

    cmake是用于生成makelist文件的构建器,makelist的作用是简化makefile的书写.

    编译程序最终调用的是make指令,这个对应的是makefile,makefile可以人为书写,不过语法相对难懂,可以通过cmake生成的makelist来自动生成makefile,makelist的语法就简单多了

    这里附上一篇个人感觉很全的cmake教程(虽然我本人也并没有全部看完)

    cmake 教程

    好了知道上面的模块了,就可以进入主题了(关于如何安装vscode跟配置minGW的环境变量这个我就不写了,网上太多了),这里说几个vscode插件

    C/C++  Cmake Tools必须安装,其余的随意,有些插件就是改变了目录的颜色,这些可以自己去找找,跟本文主旨无关

    首先声明,本人使用vscode编译C++时间甚短,关于vscode的很多配置不是很明白,不过以下的示例都经过验证,可帮助小白快速入手

    vscode在调试程序这块关于工作区的问题

    一简易使用篇: 直接使用g++指令编译程序

    如图:

     将如下代码拷贝到新建的cpp文件内

    #include<iostream>
    using namespace std;
    int main(){
        cout << "hello echo" << endl;
        system("pause");
    }

    此时你的工作区应该是这样的(除了.vscode文件夹)

     关于这个.vscode文件夹其实不必太过关心,用多了自然就知道是干嘛的,主要就是存放launch.json,tasks.json等启动,调试,任务文件的.

    下面手动创建.vscode目录

     然后将如下文件复制到.vscode目录下(文件名不要出错)

     c_cpp_properties.json (修改compilerPath)

    {
        "configurations": [
            {
                "name": "MinGW64",
                "intelliSenseMode": "gcc-x64",
                "compilerPath": "D:/C++IDE17_19_22/vscode/mingw64/bin/gdb.exe",
                "includePath": [
                    "${workspaceFolder}"
                ],
                "cppStandard": "c++17"
            }
        ],
        "version": 4
     } 

    launch.json (注意program,cwd,miDebuggerPath)

    {  
        "version": "0.2.0",  
        "configurations":
        [  
            {  
                "name": "(gdb) Launch", // 配置名称,将会在启动配置的下拉菜单中显示  
                "type": "cppdbg",       // 配置类型,这里只能为cppdbg  
                "request": "launch",    // 请求配置类型,可以为launch(启动)或attach(附加)  
                "program": "${workspaceFolder}/${fileBasenameNoExtension}.exe",// 将要进行调试的程序的路径  
                "args": [],             // 程序调试时传递给程序的命令行参数,一般设为空即可  
                "stopAtEntry": false,   // 设为true时程序将暂停在程序入口处,一般设置为false  
                "cwd": "${workspaceFolder}", // 调试程序时的工作目录,一般为${workspaceFolder}即代码所在目录  
                "environment": [],  
                "externalConsole": true, // 调试时是否显示控制台窗口,一般设置为true显示控制台  
                "MIMode": "gdb",  
                "miDebuggerPath": "D:/C++IDE17_19_22/vscode/mingw64/bin/gdb.exe", // miDebugger的路径,注意这里要与MinGw的路径对应  
                "preLaunchTask": "g++", // 调试会话开始前执行的任务,一般为编译程序,c++为g++, c为gcc  
                "setupCommands":
                [  
                    {   
                    "description": "Enable pretty-printing for gdb",  
                    "text": "-enable-pretty-printing",  
                    "ignoreFailures": true  
                    }  
                ]  
            }  
        ]  
    }

    tasks.json(注意command, options)

    {
        // See https://go.microsoft.com/fwlink/?LinkId=733558 
        // for the documentation about the tasks.json format
        "version": "2.0.0",
        "tasks": [
            {
                "type": "shell",
                "label": "g++", //这里注意一下,见下文
                "command": "D:/C++IDE17_19_22/vscode/mingw64/bin/g++.exe",
                "args": [
                    "-g",
                    "${file}",
                    "-o",
                    "${fileDirname}\\${fileBasenameNoExtension}.exe",
                    "-ggdb3",   // 生成和调试有关的信息
                    "-Wall",    // 开启额外警告
                    "-static-libgcc",   // 静态链接
                    "-std=c++17",       // 使用c++17标准
                    "-finput-charset=UTF-8",    //输入编译器文本编码 默认为UTF-8
                    "-fexec-charset=GB18030",   //输出exe文件的编码
                    "-D _USE_MATH_DEFINES"
                ],
                "options": {
                    "cwd": "D:/C++IDE17_19_22/vscode/mingw64/bin/"
                },
                "problemMatcher": [
                    "$gcc"
                ],
                "presentation": {
                    "echo": true,
                    "reveal": "always", // 在“终端”中显示编译信息的策略,可以为always,silent,never
                     "focus": false,
                     "panel": "shared" // 不同的文件的编译信息共享一个终端面板
                },
            }
        ]
    }
    

    这几个文件大概的功能这里说明一下

    C_Cpp_Properties.json是用于配置编译器环境的,包括启动器代号、位数(这些是自定义的)、编译选项、启动设置、编译模式等。includePath指向C/C++标准库、用户头文件所在位置。
    不需要CMake也可以直接编写C/C++

    launch.json是vscode用于调试的配置文件,比如指定调试语言环境,指定调试类型等等,这个文件在首次运行F5(跟vs相同的调试指令)时会让你创建该文件

    tasks.json 这个配置文件是用来执行你预定的任务的,比如说你修改了你的代码,调试之前,肯定要重新生成新的程序后再调试,那么你就可以配置它告诉vscode怎么重新生成这个新的程序

    vscode就是先跑 tasks.json 任务,再跑 launch.json。

    下面就运行tasks.json, (组合键 ctrl + shift + p  或者直接F1键)

     这里的g++就是tasks.json的lable的名字

     可以看到生成了test.exe文件

    下面进行调试,直接F5进入调试(记得打断点)

    以上

    二项目篇 cmake构建项目

    这里准备做的是创建一个dll项目,一个demo项目,使用demo调用dll的导出函数,当然了,不想看dll的可以略过部分内容

    好了跟上面一样先创建一个目录用于存放demo跟dll文件夹,我这里创建的是wook6,参照上面的方法,先给wook6文件夹添加工作区,然后在wook6文件夹里面创建bin目录,demo目录,dll目录,此时的工作区如下(除了.vscode目录)

    这时候在wook6目录下,也就是在wook6工作区中存在bin,demo,dll三个文件夹,由于vscode的命令面板执行的各种任务仅能在当前工作区生效,因此为了让demo项目在demo文件夹下生成,dll项目在dll文件夹下生成,需要为demo,dll文件夹分别添加工作区,添加工作区的方法如下

     上面的步骤执行结束后,vscode的目录如下

     那么现在发生什么事了呢,可以通过 ctrl + r 切换工作区,现在把工作区切换回wook6

     此时的目录如下

     这样一来就可以通过切换工作区的方式来指定vscode当前的工作目录

    好了,按照这个方法,把demo文件夹也添加工作区

    下面开始通过cmake构建demo项目

    ctrl+ r 进入 demo工作区,F1或者 ctrl + shift + p 打开命令面板 ,选择cmake入门

    选择你配置的mingw GCC编译版本

     输入项目名字,这里是demo

     选择下面Executable ,创建exe程序,上面这个library是用于创建链接库程序,如lib库跟dll库

     执行完上面的步骤后目录应该如下

     这个目录下面的文件由cmake构建创建,CmakeLists.txt就是cmake的语法文件,用于生成makefile文件的(此时没有.vscode目录没关系),现在cmake已经为我们构建出项目了,接下来要做的就是执行cmake指令,编译出我们的程序

    main.cpp就是本项目唯一的源文件,里面就是默认的 打印hello world,没什么可多说的

    如何执行cmake指令呢

    通过F1或者组合键打开命令面板,选择配置任务

     在列表最下面找到使用模板创建tasks.json文件

     选择maven

     此时在demo目录下面会生成.vscode目录,且在该目录下有tasks.json文件

    看看此时的tasks.json文件内容是什么

     这内容并没什么用,不过这个文件有用,vscode通过检索.vscode目录下的tasks.json文件来执行指令,label就是指令的名字,下面将如下语句替换到 label : test 的 command下

    cd ${workspaceFolder}/build ; Remove-Item -r CMakeFiles ; cmake .; make

     此时应为

     可以看到tasks.json中使用的类型是shell,准确的说是windows下的powershell,所以command后面加的就是powershell的指令,这条指令什么意思呢,就是进入当前工作区的build目录,删除CMakeFiles文件夹,然后执行cmake根据当前目录配置生成makefile,再调用make指令执行makefile文件构建项目,关于这条指令可能会出现错误的地方是 删除文件夹部分,这个自己根据shell还是cmd自行修改

    可以看到我上面把任务的名字改成了test-demo-build,下面就执行这个任务

    还是通过命令面板

     

     这两个任务就是在tasks.json中配置的,不过因为我们只配置了一个任务,另一个任务目前是无意义的,选择执行test-demo-build

     下面验证下生成的demo.exe是否可以运行,当然了有两种方法

    一是直接在命令行执行,如下,右击build目录,将其在集成终端打开

    可以看到vscode为我们新起了一个powershell终端,且运行目录也在build下

     输入 ./de 之后可通过tab键补全名称,回车键确认,执行完是这样

     注意,ps是powershell的简称

    可以看到生成的demo.exe文件可以执行,当然了最粗暴的方式是直接在文件夹下双击运行,不过默认的main.cpp没有加暂停功能,运行程序会一闪而过,想要通过此方式查看运行效果可以在main.cpp中添加 system("pause")代码,不过添加该代码后在命令行运行会出现无法关闭demo.exe的bug,如果出现该bug可在任务管理器里强制关闭demo.exe进程,当然了这些都是题外话,是我遇到的一些坑,你不一定会遇到,不知道也没关系

    二调试执行demo.exe程序

     通过该步骤可以生成launch.json文件,将如下复制粘贴,需注意miDebuggerPath

    {
        // 使用 IntelliSense 了解相关属性。 
        // 悬停以查看现有属性的描述。
        // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
        "version": "0.2.0",
        "configurations": [
            {  
                "name": "(gdb-demo) Launch", // 配置名称,将会在启动配置的下拉菜单中显示  
                "type": "cppdbg",       // 配置类型,这里只能为cppdbg  
                "request": "launch",    // 请求配置类型,可以为launch(启动)或attach(附加)  
                "program": "${workspaceFolder}/build/demo.exe",// 将要进行调试的程序的路径  
                "args": [],             // 程序调试时传递给程序的命令行参数,一般设为空即可  
                "stopAtEntry": false,   // 设为true时程序将暂停在程序入口处,一般设置为false  
                "cwd": "${workspaceFolder}", // 调试程序时的工作目录,一般为${workspaceFolder}即代码所在目录  
                "environment": [],  
                "externalConsole": true, // 调试时是否显示控制台窗口,一般设置为true显示控制台  
                "MIMode": "gdb",  
                "miDebuggerPath": "D:/C++IDE17_19_22/vscode/mingw64/bin/gdb.exe", // miDebugger的路径,注意这里要与MinGw的路径对应  
                "preLaunchTask": "test-demo-build", // 调试会话开始前执行的任务,一般为编译程序,c++为g++, c为gcc  
                "setupCommands": [  
                    {   
                        "description": "Enable pretty-printing for gdb",  
                        "text": "-enable-pretty-printing",  
                        "ignoreFailures": true  
                    }  
                ]  
            }  
        ]
    }

    好了现在可以调试程序了,vscode跟vs的调试命令完全一样,通过F5调试

     可以看到调试成功,vscode进入断点

    好了以上关于demo项目的配置就全部结束了,注意,目前的编译,调试都是在demo的工作区内完成的,下面要切换工作区到dll

    通过ctrl + r切换工作区

    通过cmake构建dll项目

    构建dll跟构建demo项目基本一样,这里只用文字说明进行了那些步骤,具体执行后的结果可参照demo的构建

    首先确认当前的工作区已经切换到dll目录,F1(ctrl + shift + p)打开命令面板,选择CMake:快速入门,

    输入项目名字,dll,选择创建library项目

     此时项目应该如上

    如果你知道C++的链接库知识应该会产生疑惑,C++的链接库分为两种,一种是lib(a)库,也就是静态库,采用的是编译时链接,仅能在C/C++语言内部使用, 一种是dll(so)库,也就是动态库,采用的是运行时链接,支持其他多种语言调用,我们这里创建的是dll,为什么没有什么设置之类的,如何确定生成的是动态库呢,好带着这个疑问接下去慢慢看

    如果熟悉C++链接库的知识,应该知道,C++链接库有两种链接方式,其中一种隐式调用链接库的方式就需要有库的头文件,目前的项目里面仅有一个cpp源文件,因此还需手动创建一个头文件(如果用显示调用方式则不需要头文件,但是需要用到loadlibaray,getaddress之类的函数获取接口的地址)

    下面创建dll.h头文件,内容如下

    #ifndef DLL_H
    #define DLL_H
    
    void say_hello();
    
    #endif

    接下来通过命令面板,给dll项目添加tasks.json,步骤跟创建demo项目时一样  : F1 -> 任务:配置任务 ->使用模板创建tasks.json文件 -> maven

    将cd ${workspaceFolder}/build ; Remove-Item -r CMakeFiles ; cmake .; make 替换进去,如下

     运行这个test  task(在命令面板 -> 任务:运行任务->test),然后去build目录下找生成的文件,如下图

      

     可以看到此时生成了一个后缀式.a的文件,说明这是生成了静态库文件,既然生成了,那就调用一下看看这个文件能不能使用吧

    将工作区切换到wook6,即最开始的目录下,如图

     如何让demo调用dll生成的库文件呢,下面需要修改demo项目的cmakelists,内容如下

    #当前工作目录
    MESSAGE(STATUS "Current path : ${CMAKE_CURRENT_SOURCE_DIR}")
    cmake_minimum_required(VERSION 3.0.0)
    project(demo VERSION 0.1.0)
    
    
    #链接库的目录,可用相对路径
    link_directories(../dll/build)
    #配置头文件目录
    include_directories(../dll)
    
    add_executable(demo main.cpp)
    
    #链接使用的库
    target_link_libraries(${PROJECT_NAME} libdll.a)
    
    set(CPACK_PROJECT_NAME ${PROJECT_NAME})
    set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
    
    

    上述设置了demo项目将要使用的库目录,库文件目录以及链接库命令

    在demo项目的main.cpp文件中修改如下

    #include <iostream>
    #include "dll.h"
    
    
    int main(int, char**) 
    {
        using namespace std;
        
        std::cout << "Hello, world!\n";
        say_hello();
        system("pause");
    }

    下面将工作区切换到demo,F1运行编译任务,在F5运行调试任务,具体运行结果如下

    上面表明demo调用dll生成的静态库文件成功

    那么问题来了,我需要生成的是动态库,这里为什么生成的是静态库呢,下面通过修改cmake指令编译生成动态库

    指定dll项目为动态库项目

    好了现在将工作区切换到dll

    修改dll的cmakelist如下

    cmake_minimum_required(VERSION 3.0.0)
    project(dll VERSION 0.1.0)
    
    include(CTest)
    enable_testing()
    
    #[[命令:add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)
    libname:生成的库文件的名字
    ​[SHARED|STATIC|MODULE]:生成库文件的类型(动态库|静态库|模块)
    [EXCLUDE_FROM_ALL]:有这个参数表示该库不会被默认构建​
    source2 ... sourceN:生成库依赖的源文件,如果源文件比较多,可以使用​aux_sourcr_directory命令获取路径下所有源文件.]]
    add_library(dll SHARED dll.cpp)
    
    set(CPACK_PROJECT_NAME ${PROJECT_NAME})
    set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
    include(CPack)
    

    注意cmake默认生成静态库项目,动态库需显式指定

    下面执行dll的编译task,结果如下

     好了现在问题来了,为什么出现了两个.a文件,一个.dll文件 ,还有为什么是.a

    先说为什么是.a 

    .a .so是linux系统下的库后缀名,分别对应windows下的.lib,.dll ,因为这里使用minGW进行编译的原因,该平台移植自linux,所以中间文件沿用的.a后缀,可以看到最终文件动态库使用的是.dll,因为.a文件在编译时被链接进程序,成为程序的代码,可以不明确区分操作系统版本,只要你的编译器认识就行,而在运行过程中,需要操作系统去加载动态库,所以这里还是以windows认识的.dll后缀作为动态库文件名

    这涉及到链接库的知识,这里简单说明一下: 动态库在被链接时有两种方式,具体的调用方法参考如下链接  动态库库的两种链接调用方式

    可以看到,动态库也有一个相应的.lib库,这个库准确的讲不能叫静态库,叫动态库导入库,里面仅有动态库的符号表及函数地址,跟真正的静态库完全不同

    好了上面生成了动态库,下面还是把工作区切换到demo,仅需修改makelist中链接库的名字即可

    执行编译指令,生成成功

    注意,动态库的使用需要将dll文件放置到demo.exe同一目录层级,将libdll.dll拷贝到demo.exe目录

     F5执行launch任务,如下

     上述表示demo调用动态库文件成功,并对demo进行了调试

    好了现在本教程已经完成了绝大部分了,还有最最重要的一步,调试动态库

    最后一步,调试动态库

    调试动态库需要稍微修改demo代码以便于让调试器可以附加进入demo程序,修改后如下

    #include <iostream>
    #include "dll.h"
    
    int main(int, char**) 
    {
         using namespace std;
        cout << "请选择输入数字执行指令" << endl;
        cout << "0 -------------- 退出程序" << endl;
        cout << "1 -------------- 调用动态库接口say_hello()" << endl;
        int in = 10086;
        while (in != 0)
        {
            cout << "输入数字:" ;
            cin >> in;
            if(in == 1)
            {
                say_hello();
            }
            else if (in == 0)
            {
                break;
            }    
        }
        return 0;
    }
    

    好了修改完后进行编译任务,并F5运行一下,可以看到如下问题

    中文出现乱码,这是编码问题,vscode默认使用UTF-8编码,而windows的cmd窗口默认使用本地编码,因为我切换了windeos语言为中文系统,所以默认的是ANIS码,也就是GBK,虽然从主流上讲,使用UTF编码更适合跨平台项目(多数平台默认宽字符编码UTF-8),不过国内的软件开发多数使用的编码仍然是GBK,关于GBK,GB2312 ,GB18030,只要知道是后者兼容前者

    下面给makelist添加如下设置

    #设置以本地GBK编码编译程序,解决中文乱码问题
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -finput-charset=GBK")
    #设置输出文件编码为GBK,解决中文乱码问题
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexec-charset=GBK")

    为什么这样设置,选择打开任何带有代码的文件,可以看到如下

     说明vscode默认使用UTF编码来保存文件,上述第一条就是告诉编译器,编译文件编码全部是GBK      设置编码参考

    下面那条命令告诉编译器将生成文件的所有输出改成GBK编码

    将main.cpp编码改成GBK

    如此设置后如下图

    接下来运行编译任务和调试任务

     好了,现在demo已经改好了,下面要对动态库进行调试

    将工作区切换到dll

    在.vscode中创建launch.json文件,内容如下

    {
        // 使用 IntelliSense 了解相关属性。 
        // 悬停以查看现有属性的描述。
        // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
        "version": "0.2.0",
        "configurations": [
            {  
                "name": "dll_attach", // 配置名称,将会在启动配置的下拉菜单中显示  
                "type": "cppdbg",       // 配置类型,这里只能为cppdbg  
                "request": "attach",    // 请求配置类型,可以为launch(启动)或attach(附加)  
                "program": "D:/vscode-workspace/wook6/demo/build/demo.exe",// 将要进行调试的程序的路径  
                "processId": "${command:pickProcess}",
                "MIMode": "gdb",  
                "miDebuggerPath": "D:/C++IDE17_19_22/vscode/mingw64/bin/gdb.exe", // miDebugger的路径,注意这里要与MinGw的路径对应  
                //"preLaunchTask": "test-demo-build", // 调试会话开始前执行的任务,一般为编译程序,c++为g++, c为gcc  
                "setupCommands": [
                    {
                        "description": "为 gdb 启用整齐打印",
                        "text": "-enable-pretty-printing",
                        "ignoreFailures": true
                    },
                    {
                        "description":  "将反汇编风格设置为 Intel",
                        "text": "-gdb-set disassembly-flavor intel",
                        "ignoreFailures": true
                    }
                ]
            }  
        ]
    }

    dll调试实在难以搞定,暂无教程

    附录: 常用的cmake指令

    #设置c++编译器
    set(CMAKE_CXX_COMPILER "g++")

    #CMAKE_ARCHIVE_OUTPUT_DIRECTORY:默认存放静态库的文件夹位置;
    #CMAKE_LIBRARY_OUTPUT_DIRECTORY:默认存放动态库的文件夹位置;
    #LIBRARY_OUTPUT_PATH:默认存放库文件的位置,如果产生的是静态库并且没有指定 CMAKE_ARCHIVE_OUTPUT_DIRECTORY 则存放在该目录下,动态库也类似;
    #CMAKE_RUNTIME_OUTPUT_DIRECTORY:存放可执行软件的目录
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ../../test)
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../../test)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../../test)

    #设置可执行文件的版本为debug还是release
    set(CMAKE_BUILD_TYPE "Debug")
    #set(CMAKE_BUILD_TYPE "Release")
    set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
    set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
    add_definitions(-std=c++11)


    #定义变量,存储当前目录下的所有源文件
    aux_source_directory(. ALL)
    #当源文件较多时,通过设置变量来指定需要编译的源文件
    set(GIVEN_LIST dll.cpp)

    #[[命令:add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)
    libname:生成的库文件的名字
    ​[SHARED|STATIC|MODULE]:生成库文件的类型(动态库|静态库|模块)
    [EXCLUDE_FROM_ALL]:有这个参数表示该库不会被默认构建​
    source2 ... sourceN:生成库依赖的源文件,如果源文件比较多,可以使用​aux_sourcr_directory命令获取路径下所有源文件.]]
    #add_library(dll SHARED dll.cpp)
    #add_library(dll SHARED ${GIVEN_LIST})
    add_library(dll SHARED dll.cpp)


    #重定义输出dll的名字
    set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "dll")   #重命名后的文件名前面依旧会加上lib三个字符

    #2、设置cmake编译语言
    set(CMAKE_CXX_STADARD 11)
    #启用语法检查
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    project(dllTest VERSION 0.1.0)

    #设置c++编译器
    set(CMAKE_CXX_COMPILER "g++")

    #6、WIN特有的bug,windows.h会定义下面两个宏,导致std::min和std::max用不了,所以要添加
    if(WIN32)
        add_definitions(-DNOMINMAX -D_USE_MATH_DEFINES)
    endif()


    #设置以本地GBK编码编译程序,解决中文乱码问题
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -finput-charset=GBK")
    #设置输出文件编码为GBK,解决中文乱码问题
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexec-charset=GBK")

    #链接库的目录,可用相对路径
    #link_directories(./)
    #配置头文件目录
    #include_directories(../dll)
    #设置可执行文件的版本为debug还是release
    set(CMAKE_BUILD_TYPE "Debug")
    #set(CMAKE_BUILD_TYPE "Release")
    #生成调试文件
    #set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
    #set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
    #add_definitions(-std=c++11)

    #CMAKE_ARCHIVE_OUTPUT_DIRECTORY:默认存放静态库的文件夹位置;
    #CMAKE_LIBRARY_OUTPUT_DIRECTORY:默认存放动态库的文件夹位置;
    #LIBRARY_OUTPUT_PATH:默认存放库文件的位置,如果产生的是静态库并且没有指定 CMAKE_ARCHIVE_OUTPUT_DIRECTORY 则存放在该目录下,动态库也类似;
    #CMAKE_RUNTIME_OUTPUT_DIRECTORY:存放可执行软件的目录
    #set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ../../bin)
    #set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ../../bin)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ../)


    add_executable(dllTest main.cpp)

    #链接使用的dll库
    #target_link_libraries(${PROJECT_NAME} libdll.dll.a)

     

     

     

    展开全文
  • linux下基于VScode cmake调试动态库和静态库

    1 创建工程目录结构

    首先创建工程文件(文件名mymath),VScode打开,进行目录结构创建。工程目录结构如下:

     .vscode是存放task.json和launch.json编译调试的文件夹。task.json和launch.json是自动生成的,但是需要根据自己的工程进行修改,后面会具体介绍。

    bin是存放最终可执行文件的文件夹;

    build是工程编译时生成的一些文件,有点类似于VS中的Debug;

    include是工程头文件;

    lib是存放生成的动态库和静态库(.a/.so)文件夹;

    myadd是动态库库工程;

    mymain是主工程;

    mysub是静态库库工程;

    根目录下的CMakeLists.txt是起到加载子目录,然后编译调试的功能。

    2 代码和文件的具体实现

    2.1 动态库myadd

    头文件myadd.h

     源文件myadd.cpp

     CMakeLists.txt文件

    2.2 静态库mysub

    头文件mysub.h

     源文件mysub.cpp

     CMakeLists.txt文件

    2.3 主工程mymain

    头文件mymain.cpp

     CMakeLists.txt文件

     2.4 根目录下的CMakeLists.txt

    3 编译和调试

    3.1 编译

    1、按住ctrl+shift+p,打开命令命令面板,输入CMake: Configure,配置CMake。

    2、选择GCC7.5.0 xxxxx选项

     3、配置完成后,在最下方会出现一条状态栏。先后执行Build和 run,输出结果。

    3.2 调试

    工程调试需要配置json文件,task.json 编译,launch.json调试。 

    1. 配置c_cpp_properties.json文件

    按住ctrl+shift+p,打开命令命令面板,输入CMake: Configure,配置CMake。

          2.配置任务tasks.json文件

    按住ctrl+shift+p,打开命令命令面板,输入Tasks: Configure Default Build Task,进行配置。

      3. 配置launch.json文件

    按下F5进行launch.json文件配置。

     

           4. 最后按下ctrl+F5即可打断点进行调试。

    单步运行就可以进入到库工程中,进行调用库的调试。

    3.3 结果

    当调试完成后,在lib文件夹下会生成动态库和静态库文件(.so/.a),在bin下生成可执行文件exe。

    展开全文
  • linux下vscode编译和调试时链接

    千次阅读 2020-11-25 19:34:51
    linux下vscode编译和调试时链接 我们可以在命令行里使用-l指定 gcc filename -lxxx #xxx是库名 但是每次都在命令行里输入太麻烦了 我们可以设置tasks.json文件里的args属性 "args": [ "-g", "${file}...
  • 以连接Mysql所需的依赖为例 1. 为插件添加头文件目录,不然语法检查提示错误 2. 项目根文件夹命名有空格,在根文件夹下有bin、include、lib、src三个文件夹 3. include下创建头文件a.cpp,内含 #ifndef DAtA...
  • RECORD: 文件结构: src bin ... DIRE_LIBS) #生成静态链接 add_library( SRC ${DIRE_LIBS}) 通过更改 SRC 来让外面的主链接链接 add_libray( SRC ${DIRE_LIBS}) 然后终端运行 cd build cmake … make … ./run
  • 一、前置知识——gcc/g++的编译链接过程 在Windows下,如果你用Visual Studio进行开发,C/C++的编译器一般采用微软提供的MSBuild;在Linux下C/C++的编译器大多采用gcc/g++。既然要在Linux下进行C++开发,很有必要...
  • vscode makefile编译方法实例

    千次阅读 2021-09-14 11:53:47
    载入内存时机,静态随程序链接时拷贝过来,库都是二进制版本 c语言中文网动态库静态库概念 静态链接库和动态链接库的作用时机不同,静态链接库会在程序载入内存之前完成所有的链接操作,而动态链接库是在程序载入内存...
  • SLAM 14讲 ch3 使用vscode编译 基于ubuntu20.04简述关于eigen3和pangolin头文件变红的问题关于eigen3和pangolin头文件变红修复VScode需要用到的插件VScode编译和调试部分思考 简述 之前一直在琢磨如何使用vscode来...
  • vscode+cmake编译cpp工程

    2021-06-18 21:13:33
    文章目录vscode+cmake编译cpp工程1. 环境配置1.1 安装 Mingw1.2 安装 cmake1.3 vscode 安装 CMake 和 CMake Tools 插件1.4 配置 MinGw 和 cmake 的环境变量1.5 注意2. 编译工程2.1 总体流程2.2 新建工程2.3 编译工程...
  • gcc,g++编译/制作并调用静态库,动态库/makefile
  • vscode 的task,lanch的配置。前提各个程序正确安装,即使用QtCreator可以正常编译调试。使用QtCreator生成工程。这里演示的是使用MSVC + CDB,因此VS和windows调试工具要装好。当然也是可以使用GCC + GDB的。脚本我...
  • VSCode配置编译MSVC程序示例 ...有时候还需要生成静态库或动态库(lib.exe)。如果我们使用VC,这些过程是在背后运作的,如果使用VSC,则不得不了解这些命令行背后运作的机理。 本文的示例代码 fi...
  • 1.项目目录 . ├── bin ├── build ├── CMakeLists.txt ├── include │ ├── array_2d.h │ ├── common.h ...build:存放编译文件 include:存放头文件 src:存放源文件 lib:存放 CMakeLists.txt:
  • vscode配置C/C++编译环境

    千次阅读 2021-07-03 14:45:46
    这边记录一下配置vscodeC/C++编译环境的过程,以便...回想我们之前用命令行或者IED编译项目,我们一般需要明确编译器的路径(包括了标准库的头文件和静态库),项目的编译规则,配置调试。 而上面这三部分就和vscode
  • cmake 编译链接静态动态文件

    千次阅读 2020-05-18 18:06:51
    但又不想在visual studio下练,整个工程文件太大了,所以用vscode连接WSL,在Linux环境下编程练习,难受的是之前都是在有图形界面的条件下用CLion编程的,整个流程就是使用IDE自动解决了,对c++的编译链接使用过程...
  • export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/yexinming/testlib2/lib(链接的位置)
  • VSCode 编译运行C++

    千次阅读 2019-04-28 18:37:10
    VSCode 编译运行C++ 简介 VSCode使用clang 编译C++ 下载LLVM 下载MinGW vscode 配置文件 使用CMake编写project 单文件单目录 多文件多目录 拓展(Makefile) 参考 简介 因为不想使用IDE,所以选择了vscode...
  • 1.4 静态库的制作

    2022-04-01 18:51:18
    库文件有两种,静态库和动态库(共享库),二者的区别是:静态库在程序的链接阶段被复制到了程序中;(根据GCC编译的原理,预处理—编译—汇编—链接(链接成可执行程序);其实静态库和动态库都是在链接阶段做的...
  • 它是JavaScript的超集,最终会被编译为JavaScript代码。 2012年10月,微软发布了首个公开版本的TypeScript,2013年6月19日,在经历了一个预览版之后微软正式发布了正式版TypeScript TypeScript的作者是安德斯·...
  • 在slam中最重要的就是Eigen,在高博的书上使用的是KDdevelop,我对vscode情有独钟想要在上面学习——死磕就完事了。如果遇到vscode对eigen报错这个问题请直接拉到下面看。 一、现在终端mkdir (文件夹名字),...
  • 1.安装CMake ps.本案例使用的是CentOS7(Red Hat 4.8) #1移除旧版本CMake yum remove cmake -y ...默认你有编译环境,若你还没有gcc、g++编译环境也不要怕,请执行如下命令配置编译环境及内核文件,你的网络传输速度
  • android生成静态库的方法有两种,一种是编辑android.mk文件,一种是编辑cmakelist文件。前一种没做研究,因为用的ide是android studio,所以直接利用gradle调用cmakelist文件完成静态库的生成,就是第二种方式。现...
  • 这是我使用VScode进行课程实验时,配置了MinGW的gcc编译器,兴冲冲地对项目使用CMake时报的错 2.解决方案 2.1 检查当前根目录下(即你通过VSCode的打开文件夹功能打开的文件夹)是否存在以“.code-workspace”文件,...
  • 我们可以将Go的非main包编译静态库提供给用户使用。下面以Windows为例,介绍一下如何将Go的非main包编译静态库,用户又将如何使用。 一、环境 笔者使用的VSCode,在终端中查看Go的环境变量,主要看GOROOT以及...
  • 下载cmake-3.23.0-rc2-windows-x86_64,下载完成打开我的电脑–》属性–》环境变量–》path中增加bin路径 不确定第一步是不是无用功,后来放弃了vscode编译 3.第2步下载好后bin里面有个gui,双击直接使用 对了,使用...
  • 静态库编译时会直接整合到目标程序中,编译成功的可执行文件可独立运行 动态库在编译时不会放到连接的目标程序中,即可执行文件无法单独运行 1.构建工程目录实例 2.工程文件编写与安装 3.使用.so和.a 1....
  • 编写 CMakeLists.txt 最常用的功能就是调用其他的 .h头文件 和 .so/.a文件,将 .cpp/.c/.cc 文件编译成可执行文件或者新的文件。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,666
精华内容 1,466
关键字:

vscode编译静态库