linux运行c++代码

代码示例

为了方便就直接展示在VScode中,就不在终端中使用操作,终端操作跟VScode中操作是类似。

首先创建一个多目录下的文件夹,如下面图片

在这里插入图片描述
上面图片中的代码
main.cpp

#include <iostream>
#include "../s1/support1.h"
#include "../s2/support2.h"

int main()
{
    std::cout <<  "Hello from my project!" << std::endl;
    Support1 mys1;
    mys1.s1();
    Support2 mys2;
    mys2.s2();
    std::cin.get();
}

support1.h

class Support1
{
public:
    void s1();
};

support1.cpp

#include <iostream>
#include "support1.h"

void Support1::s1()
{
    std::cout << "hello support1" << std::endl;
}

support2.h

class Support2
{
public:
    void s2();
};

support2.cpp

#include <iostream>
#include "support2.h"

void Support2::s2()
{
    std::cout<<"hello support2"<<std::endl;
}

g++运行代码,不使用VScode(多目录)

不使用makefile

首先在终端中使用下面命令,下面命令主要是将support1.cpp生成一个编译单元,输出为support1.o

g++ -g -c -o ./s1/support1.o ./s1/support1.cpp

结果如下图所示,在s1文件下多出了一个support1.o文件
其中-c表示生成编译单元,也就是输出.o格式的文件
-o后面跟的是输出的文件保存地址

在这里插入图片描述
同理,可以使用下面代码生成support2.o文件,然后使用下面代码将所有的编译单元link起来,并编译main.cpp文件

# genenrate support2.o
g++ -g -c -o ./s2/support2.o ./s2/support2.cpp

# compile main.cpp, link support1.o support2.o
g++ -g -o mainProject/main.out mainProject/main.cpp s1/support1.o s2/support2.o

结果如下图所示

在这里插入图片描述
可以从上图看到已经有main.outexe程序生成,只需要用终端打开文件目录,并输入下面代码,注意这个./千万不能丢失,否则就会保错

./main.out

在这里插入图片描述

使用makefile

首先在mainProject目录下创建一个makefile文件,文件的内容,如下图所示

在这里插入图片描述
makefile文件的内容如下,makefile的格式内容可以参考这个链接

project : ../s1/support1.o ../s2/support2.o
	g++ main.cpp ../s1/support1.o ../s2/support2.o -g -o main.out
support1.o : ../s1/support1.cpp ../s1/support.h
	g++ -g -c ../s1/support1.cpp
support2.o : ../s2/support2.cpp ../s2/support2.h
	g++ -g -c ../s2/support2.cpp

然后在终端中使用make,对makefile进行编译

在这里插入图片描述
编译的结果如下图所示,可以看到s1文件下有support1.o文件,s2文件下有support2.o文件,mainProject文件下有main.out二进制程序,main.out执行结果如下图所示

在这里插入图片描述

使用VScode和g++运行c++代码(多目录)

VScode环境配置,安装下面图片中的扩展库

在这里插入图片描述

不使用makefile

在按F5运行main.cpp,第一次进行调试的时候会出现选择g++编译的情况,直接选择第一个g++编译器即可,

在这里插入图片描述

然后会运行失败,会出现下面图片中提示的错误,选择仍要调试选项
在这里插入图片描述
然后会出现下面图片中的提示,选择打开"launch.json"选项

在这里插入图片描述
然后会出现.vscode/tasks.json文件和.vscode/launch.json文件

在这里插入图片描述
tasks.json进行修改

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++ 生成活动文件",
            "command": "/usr/bin/g++",
            "args": [
                "-fdiagnostics-color=always",
                "-g", // 这个是编译程序的
                "${file}",
                "${fileDirname}/../s1/support1.cpp",  // s1/support1.cpp文件
                "${fileDirname}/../s2/support2.cpp",  // 直接在这里添加需要g++的文件 
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。"
        }
    ],
    "version": "2.0.0"
}

修改完成后,直接再次按F5,如果想要调试的话,可以直接和python一样打断点,如果不使用快捷键的话,可以使用VScode右上角的运行按钮选择是直接运行还是进行调试
在这里插入图片描述

选择调试后,结果会如下图所示
在这里插入图片描述

使用makefile

按照g++运行代码,不使用VScode(多目录)/使用makefile章节的方法将makefile文件添加好
在这里插入图片描述
然后根据使用VScode和g++运行c++代码(多目录)/不使用makefile中的方法生成launch.jsontasks.json文件

在这里插入图片描述
此时的tasks.json内容为

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++ 生成活动文件",
            "command": "/usr/bin/g++",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。"
        }
    ],
    "version": "2.0.0"
}

launch.json内容为

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": []
}

然后将tasks.json修改为下面的内容,label后面的名称可以是任意的字符串,如“myProject”,command后面的是要执行的命令,需要cd mainProject是因为项目在Hello Copy这个文件目录下,而makefile文件在mainProject这个子文件夹下

{
    "tasks": [
        {
            "label": "makeMyProject",
            "type": "shell",
            "command": "cd mainProject && make"
        }
    ],
    "version": "2.0.0"
}

在修改launch.json之前,首先点击VScode右下角的添加配置

在这里插入图片描述
然后会出现下面的选项,选择第二个选项C/C++: (gdb) 启动

在这里插入图片描述

然后launch.json的文件内容就变为下面的json

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) 启动",
            "type": "cppdbg",
            "request": "launch",
            "program": "输入程序名称,例如 ${workspaceFolder}/a.out",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "将反汇编风格设置为 Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

在上面的launch.json的基础上进行修改,生成的可执行文件main.out也在mainProject文件夹下,所以launch.json中还有一个program需要更新下:"program": "${workspaceFolder}/mainProject/main.out",也就是指定.out的输出路径;还需要添加 "preLaunchTask": "makeMyProject",注意这个 "preLaunchTask"冒号后的内容一定要跟tasks.json中的label相同,至于"miDebuggerPath": "/usr/bin/gdb"可能是可添加可不添加(也有可能是添加了这个才能对C++代码进行调试),我添加了,我看其他博客是没有添加这个,修改后的launch.json如下

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) 启动",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/mainProject/main.out",  // 修改
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "将反汇编风格设置为 Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "makeMyProject",  // 添加
            "miDebuggerPath": "/usr/bin/gdb"  //  添加 
        }
    ]
}

然后使用F5键进行运行,或者直接点击main.cpp,然后选择运行——>启动调试,会得到如下图,可以看到可以运行成功

在这里插入图片描述

makefile文件优化

现在有个问题,由于只有3个文件夹,3个cpp文件,所以在生成.out文件时候,使用了三个文件(一个.cpp,两个.o)来完成g++ myProject.cpp ../s1/support1.o ../s2/support2.o -g -o mainProject.out。如果有很多文件?需要一个一个先把调用的文件编译了,然后一起link然后生成.out?并且添加一个文件就需要改变makefile文件?所以需要对makefile进行优化,不管.cpp文件在哪里,都拉过来链接成为.o文件,不管.o文件在哪里,都统统拉过来编译为.out文件

CC := g++
CFLAGS 	:= -g
TARGET 	:= main.out
SOURCE 	:= $(wildcard *.cpp ../s1/*.cpp ../s2/*.cpp)
OBJS 	:= $(patsubst %.cpp,%.o,$(SOURCE))

Tar : $(OBJS)
	$(CC) $(CFLAGS) $(OBJS) -o $(TARGET)  

%.o : %.cpp
	$(CC) $(CFLAGS) -c $< -o $@

.PHONY : clean
clean : 
	rm -rf $(TARGET) *.o ../s1/*.o ../s2/*.o

使用了CC作为变量名,变量内容为g++CFLAGS同理,可以使用$(CC)$(CFLAGS)的方式使用两个变量。使用SOURCE表示源码的所有位置,由于makefile在mainProject文件夹下,所以文件路径就是当前文件夹下的所有.cpp文件,使用*通配所有后缀为.cpp的文件,以及同级的s1文件夹和s2文件夹的所有.cpp文件,如果只有文件发生变化,那么使用通配的方式还是能找到新增的文件,如果文件夹的位置发生变化或者新增,就需要更改这个SOURCE变量。OBJS是将通配出来的所有SOURCE的后缀.cpp换成.o(通过函数patsubst实现)。所以Tar这个命令就是利用所有的.o文件生成main.out,而.o文件需要%.o这步生成。这里有$<$@等符号介绍一下:

符号含义
$^代表所有的依赖文件
$@代表所有的目标文件
$<代表第一个依赖文件
$?所有比目标新的依赖文件名称的集合,以空格分隔
$+很像$^,也是所有依赖文件的集合,但是它不去除重复的依赖
$*匹配目标模式中“%”之前的部分

$(CC) $(CFLAGS) -c $< -o $@就是将所有的依赖cpp文件,生成所有的目标.o。

说一下.PHONY的作用,.PHONY后面写的是伪目标,也就是说这种目标只是占用一个符号一个名字而已,无论当前目录下是否有clean文件,不会对比是否最新,只要执行make clean,clean目标下面定义的命令永远都会执行!在包含makefile的文件夹下执行make clean就可以清除所有的.o以及.out文件。
在这里插入图片描述
可以看到,上面的makefile优化成功了,但是并没有执行make clean命令清除掉main.out、main.o、support1.o、support2.o。如果要将执行make之后生成的.o以及.out文件都删除了,必须在执行make后,接着执行make clean
如下面终端中的,在执行make后,生成了main.out、main.o,然后执行make clean后,又清除了main.out、main.o文件。
在这里插入图片描述
在这里插入图片描述
其实也可以在VScode中清除main.o、support1.o、support2.o,但是不能清除main.out,否则会出现报错(open launch.json错误)。
具体可以在tasks.json中的command"cd mainProject && make"修改为"cd mainProject && make && make clean",如下所示

{
    "tasks": [
        {
            "label": "makeMyProject",
            "type": "shell",
            "command": "cd mainProject && make && make clean"
        }
    ],
    "version": "2.0.0"
}

为了防止出现报错,修改makefile文件,将最后一行rm -rf $(TARGET) *.o ../s1/*.o ../s2/*.o修改为rm -rf *.o ../s1/*.o ../s2/*.o,这个$(TARGET)其实就是main.out
tasks.jsonmakefile修改好后,直接F5键运行,由下图可以看到只有main.out保存下来了
在这里插入图片描述
生成库文件的Makefile万能模板:

CC      := g++ 
LD      := ld 
CFLAGS  = -shared -fPIC -Wall -O -g
LDFLAGS := -shared -fPIC
SOURCE  := $(wildcard *.cpp ./subpath1/*.cpp ./subpath2/*.cpp) 
OBJS    := $(patsubst %.cpp,%.o,$(SOURCE)) 
TARGET_LIB := main 

makeso:
	g++ $(SOURCE) -fPIC -shared -o $(TARGET_LIB)  

all:$(OBJS)
	echo $(OBJS)
	$(CC) $(LDFLAGS) -o $(TARGET_LIB) $(OBJS)  
  
%.o:%.cpp
	@echo Compiling $< ... 
	$(CC) $(CFLAGS) -c   $< -o $@
  
.PHONY: clean 
clean:
	rm *.so *.o ./subpath1/*.o ./subpath2/*.o $(TARGET_LIB) -rf

使用VScode引入依赖库(opencv、cuda库)等,以opencv为例

不使用makefile

方法一

创建tasks.jsonlaunch.json文件这个就不做介绍了,前面已经做过介绍了,生成原始文件就可以,不需要进行任何改变,会在下文进行改变。
创建之后还需按照以下步骤生成c_cpp_properties.json
首先点击查看——>命令面板
在这里插入图片描述
然后会出现下面的界面,选择C/C++:编辑配置(JSON)
在这里插入图片描述
然后就会出现c_cpp_properties.jsonc_cpp_properties.json的内容也如下:
在这里插入图片描述
需要对c_cpp_properties.json的内容进行修改

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "/usr/include/opencv4"  // jetson中opencv的头文件在这个路径中
 							// /usr/include/opencv4/opencv2
            ],
            "defines": [],
            "compilerPath": "/usr/bin/clang-8",
            "cStandard": "c17",
            "cppStandard": "c++14",
            "intelliSenseMode": "linux-clang-arm64"
        }
    ],
    "version": 4
}

然后,需要对tasks.json进行修改

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++ 生成活动文件",
            "command": "/usr/bin/g++",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "${fileDirname}/../s1/support1.cpp",
                "${fileDirname}/../s2/support2.cpp",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}",
                // "`pkg-config", "--cflags", "--libs", "opencv4`",
                
                // 方法一中需要添加以下内容
                "-I",
                "/usr/include",
                "-I",
                "/usr/include/opencv4",
                "-I",
                "/usr/include/opencv4/opencv2",
                
                /* 项目所需的库文件路径 */
                "-L", 
                "/usr/lib",
 
                /* OpenCV的lib库 在windows中可以直接使用opencv_world480.dll*/
                "-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"
            ],

            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。"
        }
    ],
    "version": "2.0.0"
}

在进行修改之后,可以直接使用F5进行运行
下面这张图片就是类似于g++编译代码
在这里插入图片描述
然后结果图是下面这张图
在这里插入图片描述

方法二

c_cpp_properties.json跟方法一的一样
就只有tasks.json的内容有所改变

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++ 生成活动文件",
            "command": "/usr/bin/g++",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "${fileDirname}/../s1/support1.cpp",
                "${fileDirname}/../s2/support2.cpp",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}",
                "`pkg-config", "--cflags", "--libs", "opencv4`"  // 这里需要是添加的代码
            ],

            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。"
        }
    ],
    "version": "2.0.0"
}

pkg-config --cflags --libs opencv4就是链接库,可以直接在终端使用该命令行,可以参考一下
Linux 下编译 OpenCV4

在这里插入图片描述
然后直接F5键进行调试
下面这张图片就是类似于g++编译代码
在这里插入图片描述然后结果图是下面这张图在这里插入图片描述

使用makefile

基础的makefile文件创建可以参考使用VScode和g++运行c++代码(多目录)/makefile文件优化,然后对makefile文件进行修改,

CC := g++
CFLAGS 	:= -g
LDLIBS = `pkg-config --cflags --libs opencv4`  # 添加了这个,这个就是链接到opencv库和头文件
TARGET 	:= main.out
SOURCE 	:= $(wildcard *.cpp ../s1/*.cpp ../s2/*.cpp)
OBJS 	:= $(patsubst %.cpp,%.o,$(SOURCE))

Tar : $(OBJS)
	$(CC) $(CFLAGS) $(OBJS) -o $(TARGET) $(LDLIBS)  # 这里添加 $(LDLIBS)

%.o : %.cpp
	$(CC) $(CFLAGS) -c $< -o $@ $(LDLIBS)  # 这里添加了$(LDIIBS)

.PHONY : clean
clean : 
	rm -rf  *.o ../s1/*.o ../s2/*.o

然后直接F5键进行调试
下面这张图片就是类似于g++编译代码
在这里插入图片描述
然后结果图是下面这张图在这里插入图片描述也可以进行断点调试
在这里插入图片描述

参考文献

  1. 在Linux上调试C++项目
  2. makefile编写规则
  3. vs code 配置C/C++多文件编译调试(linux&windows)
  4. vscode 调试使用 make 编译的项目
  5. linux环境下VScode如何调试C/C++代码
  6. Linux安装OpenCV并配置VSCode环境
  7. Linux使用VScode配置C++和opencv
  8. Linux 下编译 OpenCV4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值