参考教程:www.bilibili.com/video/BV1fy…
工具
vscode and ubuntu c++ cmake
linux系统
linux一切皆文件
指令:
ls
pwd
开发环境搭建
安装编译器 调试器
sudo apt udpate
sudo apt install build-essential gdb
gcc --version
g++ --version
gdb --version
camke安装
sudo apt install cmake
cmake --version
gcc编译器
使用gcc指令编译c代码
g++来编译c++代码
编译过程
1.预处理 pre-preocessing //.i文件
g++ -E test.cpp -o test.i //.s文件
2.编译-compiling
g++ -S test.i -o test.s
3.汇编 //.o文件
g++ -c test.s -o test.o
4.链接 //bin文件
g++ test.o -o test
以上四部经常:g++ test.cpp -o test一部搞定
./test
g++需要编译
g++重要编译参数
1.-g 编译带调试信息的可执行的文件 g++ -g test.cpp -o test
2.-O[n] 优化代码源 g++ -O2 test.cpp 一般选择O2 速度很快
time ./test :就可以看到执行速度
ls -lh :可以看到文件大小
3.-I指定库文件 -L指定库文件路径
g++ -lglog test.cpp
g++ -L/home/bing/mystest -lmytest test.cpp //L库文件路,l库文件名
4.-I 指定文件搜索目录
g++ -I/myinclude test.cpp
5.-Wall 答应警告信息
6.-w 关闭警告信息
7.std=c++11 设置编译标准
g++ -std=c++11 test.cpp
8.-o 指定输出文件名
9.-D 定义宏
代码:
#include<stdio.h>
int main(){
#ifdef DEBUG
print("DEBUG LOG\n");
sendif
print("in\n");
}
//编译使用:
g++ -DDEBUG main.cpp //就可以被执行了
10.man:可以查看相关文档
编译实战:
tree:
include
:swap.h
src
:swap.cpp
main.cpp
main.cpp:
#include<iostream>
using namespace std;
#include<string>
#include"swap.h"
int main(){
int a=10;
int b=20;
cout<<a<<" "<<b<<endl;
swap(a,b);
cout<<a<<" "<<b<<enl;
return 0;
}
swap.h
#include<iostream>
using namespace std;
void swap(int &a,int &b);
swap.cpp
#include"swap.h"
void swap(int &a,int &b){
int temp;
temp=a;
a=b;
b=temp;
}
g++ main.cpp src/swap.cpp -Iinclude //这样就不报错了,把所有链接
g++ main.cpp src/swap.cpp -Iinclude -Wall -std=c++11 -o a.out
c++
include"swap.h"
include"src/swap.h" //这是错误的不能这样用
g++ swap.cpp -I../include
# 生成静态库libSwap.a
ar r s libSwap.a Swap.o
静态库和动态库
静态库:
linux:.a
windows:.lib
动态库:
linux:.so
windows:.dll
生成静态库
把需要的其它文件生成一个库
把swap.cpp生成一个静态库 生成静态库之前,我们生成.o文件
g++ swap.cpp swap.cpp -c -I../include -o swap.o
然后生成静态库libSwap.a
ar rs libSwap.a swap.o //静态库是以a为结尾的,把swap.o变成静态库libSwap.a
链接,生成只执行文件:staticmain
g++ mian.cpp -lswap -Lsrc -Iinclude -o static_main //-l是swap静态名 -L是路径 生成可执行文件
生成动态库
g++ swap.cpp -I../inlcude -fPIC -shared -o libswap.so //生成动态库
等价于:
g++ swap.cpp -I../include -c -fPIC
g++ -shared -o libswap.so swap.o
动态库文件生成以后链接:
g++ main.cpp -Iinclude -lswap -Lsrc -o dyna_main
注意:./dyan_main //执行会报错
参考:https://www.cnblogs.com/skynet/p/3372855.html
发现还是报错!!!那么,在执行的时候是如何定位共享库文件的呢?
当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统动态载入器(dynamic linker/loader)。
对于elf格式的可执行程序,是由ld-linux.so*来完成的,它先后搜索elf文件的 DT_RPATH段—环境变量LD_LIBRARY_PATH—/etc/ld.so.cache文件列表—/lib/,/usr/lib 目录找到库文件后将其载入内存。
如何让系统能够找到它:
如果安装在/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作。
如果安装在其他目录,需要将其添加到/etc/ld.so.cache文件中,步骤如下:
编辑/etc/ld.so.conf文件,加入库文件所在目录的路径
运行ldconfig ,该命令会重建/etc/ld.so.cache文件
我们将创建的动态库复制到/usr/lib下面,然后运行测试程序。
在动态链接和静态链接一起存在的时候,动态链接优先
LD_LIBRARY_PATH=src ./dyna_main //也可以指定路径执行
GDB调试器
GDB(GUN debugger)是一个调试c/c++程序的功能强大的调试器,是linux系统开发最常用的调试器
vscode是通过gdb调试器来实现c/c++的调试工作的
GDB
调试开始:gdb [exefilename] 进入调试器 其中exefilename委要调试的可执行文件名
gcc -g main.c -o main //编译时候加上-g,之后才能用gdb进行调试
回车键:重复上一命令
ctrl +l 清屏
按enter键就是上一次命令执行
f2可以修改全部的名字
格式调整 format document
list
undisplay 行号 //取消代码
IDE -VSCode
插件安装:
c/c++
cmake
cmake tools
code runner 代码快速编写
tabout
界面参考链接:https://www.bilibili.com/video/BV1fy4y1b7TC?p=12
cmake
Make是一个跨平台的安装编译工具,可以用简单的语句来描述所有平台的安装(编译过程)
比如一个项目
visual studio msbuild Windows 变成binaries
xcode macos binaries
makefile make linux binaries
cmake 通过写一个CMakeLists.txt 就可以自动变成各个平台
cmake语法特性介绍
基本语法格式:指令(参数1 参数2 ..)
参数使用括弧括起
参数之间使用空格或分号分开
指令是大小写无关,参数和变量是大小写有关
变量使用${}方式取值,但是在IF控制语句中是直接使用变量名 ,比如:${Hello}
外部构建:
mkdir build
cd build
cmake .. //编译上一级目录
make //执行make命令生成target
cmake实战:
#注释必须要写在上面,不能写在下面
实战vscode项目完整版开发
案例:士兵突击
需求:
1.士兵 许三多 有一把枪 叫做AK47
2.士兵可以开火
3.士兵可以给枪装填子弹
4.枪能够发射子弹
5.枪能够装填子弹 --增加子弹数量
开发:
开发枪类
开发士兵类
士兵类
string _name;
Gun* _ptr_gun;
Solider(string name);
addBulletToGun(int num);
fire();
枪类
string _type;
int _bullent_count;
Gun(string type);
addBullent(int num);
shoot();
步骤
1.合理设置项目目录
ptr是pointer的缩写 指针
空指针:nullptr
g++ main.cpp src/gun.cpp src/solider.cpp -Iinclude -Wall -g -O2 -o myexe
然后代码修改了直接make make是只编译修改的部分对于大项目速度很快
cmake编写:
# cmake版本
cmake_minimum_required(VERSION 3.0)
# 项目名称
project(SOLIDERFIRE)
# 设置其它要求
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O2 -Wall")
# 头文件路径
include_directories(include)
# 可执行文件
add_executable(my_cmake_exe main.cpp src/solider.cpp src/gun.cpp)
调试配置:
launch.json中program和preLaunchTask很重要
program代码可以调试的绝对路径
preLaunchTask:在launch之前进行之前
${workspaceFolder}代表项目中的底层文件夹目录
"program": "${workspaceFolder}/build/my_cmake_exe",
F5是代码调试
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
set(CMAKE_BUILD_TYPE Debug)
如果使用-g -O2会优化代码容易出问题
加个task.json就可以自动编译 而就是preLaunchTasK:"Build",
launch.json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/my_cmake_exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"console": "externalTerminal",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "Build",
"miDebuggerPath": "/usr/bin/gdb"
}
]
}
tasts.json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"options": {
"cwd": "${workspaceFolder}/build"
},
"tasks": [
{
"label": "cmake",
"type": "shell",
"command": "cmake",
"args": [
".."
]
},
{
"label": "make",
"group": {
"kind": "build",
"isDefault": true
},
"command":"make",
"args": [
]
},
{
"label": "Build",
"dependsOrder": "sequence",//按列出的顺序执行任务依赖项
"dependsOn":[
"cmake",
"make"
]
}
]
}