Linux c++开发搭建 动态静态文件

450 阅读5分钟

参考教程: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"
            ]
        }
    ]
}

setting.json 文件参考:jingyan.baidu.com/article/4f7…

tasks.json 在terminal中configure task中