首页 > 系统相关 >1 Linux系统编程入门

1 Linux系统编程入门

时间:2023-07-13 17:45:43浏览次数:45  
标签:文件 gcc 入门 ++ 编程 编译 Linux main sub

1 Linux系统编程入门

1.1Linux开发环境搭建

我使用的是阿里云2核2G的服务器1年108元

  1. 设置服务器root密码,重启服务器
  2. root用户登录,进行添加新用户
  3. 注册自己使用的用户
sudo useradd -r -m -s /bin/bash tset #tset是用户名

其中参数的意义如下:

  • -r:建立系统账号
  • -m:自动建立用户的登入目录
  • -s:指定用户登入后所使用的shell
  1. 设置密码
sudo passwd tset
  1. 输入ls /home可以看到以及创建成功
    设置用户相关教程链接:ubuntu添加用户
  2. 修改用户权限
sudo chmod +w /etc/sudoers #添加写入的权限
sudo vim /etc/sudoers #修改文件
#修改vim中的权限,保存退出:wq
sudo chmod -w /etc/sudoers #移除写入的权限
  1. 创建组并且添加用户
groupadd learngroup
usermod -g learngroup mobbu
id mobbu #查看是否添加成功
  1. 使用vscode远程连接扩展,搜索remote安装,连接到服务器。

  2. 在本机创建密钥ssh-keygen -t rsa,默认回车即可,在用户账户可以查找到.ssh文件,找到id_rsa.pub文件(公钥文件),然后在服务器端使用同样命令创建密钥,cd .ssh,再修改文件vim authorized_keys,将本机的公钥打开复制粘贴到此文件中保存退出即可。此时环境配置完成。

1.2 GCC

1.2.1 什么是GCC

  • GCC 原名为 GNU C语言编译器(GNU C Compiler)
  • GCC(GNU Compiler Collection,GNU编译器套件)是由 GNU 开发的编程语言译器。GNU 编译器套件包括 C、C++、Objective-C、Java、Ada 和 Go 语言前端,也包括了这些语言的库(如 libstdc++,libgcj等)
  • GCC 不仅支持 C 的许多“方言”,也可以区别不同的 C 语言标准;可以使用命令行选项来控制编译器在翻译源代码时应该遵循哪个 C 标准。例如,当使用命令行参数-std=c99 启动 GCC 时,编译器支持 C99 标准。
  • 安装命令 sudo apt install gcc g++ (版本 > 4.8.5)
  • 查看版本 gcc/g++ -v/--version
  • CTRL + L 清空命令行

1.2.2 编程语言发展

  • 高级语言->汇编语言->机器语言->计算机

1.2.3 GCC工作流程

  • 预处理:头文件展开、宏替换、删除注释

1.2.4 gcc 和 g++ 的区别

  • gcc 和 g++都是GNU(组织)的一个编译器。
  • 误区一:gcc 只能编译 c 代码,g++ 只能编译 c++ 代码。两者都可以,请注意:
    • 后缀为 .c 的,gcc 把它当作是 C 程序,而 g++ 当作是 c++ 程序
    • 后缀为 .cpp 的,两者都会认为是 C++ 程序,C++ 的语法规则更加严谨一些
    • 编译阶段,g++ 会调用 gcc,对于 C++ 代码,两者是等价的,但是因为 gcc命令不能自动和 C++ 程序使用的库联接,所以通常用 g++ 来完成链接,为了统一起见,干脆编译/链接统统用 g++ 了,这就给人一种错觉,好像 cpp 程序只能用 g++ 似的
  • 误区二:gcc 不会定义 __cplusplus 宏,而 g++ 会
    • 实际上,这个宏只是标志着编译器将会把代码按 C 还是 C++ 语法来解释
    • 如上所述,如果后缀为 .c,并且采用 gcc 编译器,则该宏就是未定义的,否则, 就是已定义
  • 误区三:编译只能用 gcc,链接只能用 g++
    • 严格来说,这句话不算错误,但是它混淆了概念,应该这样说:编译可以用gcc/g++,而链接可以用 g++ 或者 gcc -lstdc++。
    • gcc 命令不能自动和C++程序使用的库联接,所以通常使用 g++ 来完成联接。但在编译阶段,g++ 会自动调用 gcc,二者等价

1.2.5 GCC常用参数选项

gcc编译选项 说明
-E 预处理指定的源文件,不进行编译
-S 编译指定的源文件,但是不进行汇编
-c 编译、汇编指定的源文件,但是不进行链接
-o [file1] [file2] 将文件 file2 编译成可执行文件 file1
-I directory 指定 include 包含文件的搜索目录
-g 在编译的时候,生成调试信息,该程序可以被调试器调试
-D 在程序编译的时候,指定一个宏
-w 不生成任何警告信息
-Wall 生成所有警告信息
-On n的取值范围:0~3。编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
-l 在程序编译的时候,指定使用的库
-L 指定编译的时候,搜索的库的路径
-fpic 生成与位置无关的代码
-shared 生成共享目标文件,通常用在建立共享库时
-std 指定C方言,如:-std=c99,gcc默认的方言是GNU C

例子:

gcc test.c -o app #当前目录下生成test.c的可执行文件app
./app #运行app
gcc test.c -E -o test.i # 预处理,进行头文件展开、宏替换、删除注释
gcc test.i -S -o test.s # 编译,生产test.s汇编代码
gcc test.s -c -o test.o # 汇编,产生test.o机器01代码,可直接运行

-D

#ifdef DEBUG
    printf("success\n");
#endif

添加上述代码后,命令行输入gcc test.c -o test -DDEBUG,此时添加DEBUG宏后,将会执行上述代码,打印success

1.3 静态库的制作和使用

1.3.1 静态库的制作

  • 库文件是计算机上的一类文件,可以简单的把库文件看成一种代码仓库,它提供给使用者一些可以直接拿来用的变量、函数或类。

  • 库是特殊的一种程序, 编写库的程序和编写一般的程序区别不大,只是库不能单独运行。

  • 库文件有两种,静态库和动态库(共享库),区别是:静态库在程序的链接阶段被复制到了程序中;动态库在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。

  • 库的好处:

    • 代码保密
    • 方便部署和分发
  • 命名规则:

    • Linux :libxxx.a
      • lib :前缀(固定)
      • XXX:库的名字,自己起
      • .a:后缀(固定)
    • Windows : libxxx. lib
  • 静态库的制作:

    • gcc获得.o文件
    • 将.o文件打包,使用ar工具(archive)
      ar rcs 1ibxxx.a xxx.o Xxx.o
      
      • r - 将文件插入备存文件中
      • c - 建立备存文件
      • s - 索引

1.3.2 静态库的使用

  • 生产静态库
  • 使用静态库gcc main.c -o app -L lib_address -l lib_name
    • main.c为执行文件
    • -o 为生成执行文件
    • lib_address 库地址
    • lib_name 库名字
cd ./calc
gcc -c add.c div.c mult.c sub.c # 生成四个函数的汇编文件
ar rcs libcalc.a add.o div.o mult.o sub.o # 生成对应四个函数的静态库calc
cd ../library
mv ../calc/libcalc.a ./lib
gcc main.c -o app -I ./include/ -l calc -L ./lib/ 
# 执行main.c 生产执行文件app,头文件地址为./include,使用库calc,库地址为./lib
./app # 执行代码

1.4 动态库的制作和使用

1.4.1 动态库的制作

  • 命名规则:
    • Linux : libxxx.so
      • lib : 前缀(固定)
      • xxx : 库的名字,自己起
      • .so : 后缀(固定)
        在Linux下是一个可执行文件
    • Windows : libxxx.dll
  • 动态库的制作:
    • gcc 得到 .o 文件,得到和位置无关的代码
      gcc -c –fpic/-fPIC a.c b.c
    • gcc 得到动态库
      gcc -shared a.o b.o -o libcalc.so

1.4.2 动态库加载失败的原因

  • 静态库:GCC 进行链接时,会把静态库中代码打包到可执行程序中
  • 动态库:GCC 进行链接时,动态库的代码不会被打包到可执行程序中
  • 程序启动之后,动态库会被动态加载到内存中(当GCC使用add方法的时候),通过 ldd(list dynamic dependencies)命令检查动态库依赖关系
  • 如何定位共享库文件呢?
    当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统的动态载入器来获取该绝对路径。对于elf格式的可执行程序,是由ld-linux.so来完成的,它先后搜索elf文件的 DT_RPATH段 ——> 环境变量LD_LIBRARY_PATH ——> /etc/ld.so.cache文件列表 ——> /lib/,/usr/lib目录找到库文件后将其载入内存。

1.4.3 解决动态库加载失败问题

添加环境变量LD_LIBRARY_PATH文件

  1. 方法一:在终端输入以下命令,缺点:临时生产,下次打开终端环境变量就没了

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/mobbu/Linux/lesson06/library/lib
    

    其中冒号:之后为动态所在的绝对地址,通过pwd命令获得

  2. 方法二:用户端修改环境变量,永久存在

    • 步骤一
    cd / #返回根目录
    vim .bashrc
    
    • 步骤二
      在bashrc文件中,shift+G跳到最后一行,并且插入export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/mobbu/Linux/lesson06/library/lib,保存退出后

    • 步骤三

    . .bashrc # 等于source .bashrc
    
  3. 方法三:root环境下修改环境变量,永久存在,需要root权限

    sudo vim /etc/profile

    插入export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/mobbu/Linux/lesson06/library/lib,

    保存退出后

    . .bashrc # 等于source .bashrc

1.5 静态库和动态库对比

1.5.1 程序编译成可执行程序的过程

Alt text
静态库、动态库区别来自链接阶段如何处理,链接成
可执行程序。分别称为静态链接方式和动态链接方式。

1.5.2 静态库制作过程

1.5.3 动态库制作过程

1.5.4 静态库的优缺点

  • 优点:

    • 静态库被打包到应用程序中加载速度快
    • 发布程序无需提供静态库,移植方便
  • 缺点:

    • 消耗系统资源,浪费内存
    • 更新、部署、发布麻烦

1.5.5 动态库的优缺点

  • 优点:
    • 可以实现进程间资源共享(共享库)
    • 更新、部署、发布简单
    • 可以控制何时加载动态库
  • 缺点:
    • 加载速度比静态库慢
    • 发布程序时需要提供依赖的动态库

1.6 MakeFile

1.6.1 什么是 Makefile

  • 一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,Makefile 文件定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 Makefile 文件就像一个 Shell 脚本一样,也可以执行操作系统的命令。
  • Makefile 带来的好处就是“自动化编译” ,一旦写好,只需要一个 make 命令,整个工程完全自动编译,极大的提高了软件开发的效率。make 是一个命令工具,是一个解释 Makefile 文件中指令的命令工具,一般来说,大多数的 IDE 都有这个命令,比如 Delphi 的 make,Visual C++ 的 nmake,Linux 下 GNU 的 make

tar -zxvf redis-5.0.10.tar.gz # 解压到当前文件夹

1.6.2 Makefile文件命名和规则

  • 文件命名
    makefile 或者 Makefile
  • Makefile 规则
    • 一个 Makefile 文件中可以有一个或者多个规则\
      目标 ...: 依赖 ...
          命令(Shell 命令)
          ...
      
      • 目标:最终要生成的文件(伪目标除外)
      • 依赖:生成目标所需要的文件或是目标
      • 命令:通过执行命令对依赖操作生成目标(命令前必须 Tab 缩进)
    • Makefile 中的其它规则一般都是为第一条规则服务的

例子:
首先输入vim Makefile,然后再Makefile文件里添加以下代码

app:sub.c add.c mult.c div.c main.c
        gcc sub.c add.c mult.c div.c main.c -o app

最后输入make指令即可

1.6.3 工作原理

  • 命令在执行之前,需要先检查规则中的依赖是否存在
    • 如果存在,执行命令
    • 如果不存在,向下检查其它的规则,检查有没有一个规则是用来生成这个依赖的,如果找到了,则执行该规则中的命令
  • 检测更新,在执行规则中的命令时,会比较目标和依赖文件的时间
    • 如果依赖的时间比目标的时间晚,需要重新生成目标
    • 如果依赖的时间比目标的时间早,目标不需要更新,对应规则中的命令不需要被执行

1.6.4 变量

  • 自定义变量
    变量名=变量值 var=hello
  • 预定义变量
    AR : 归档维护程序的名称,默认值为 ar
    CC : C 编译器的名称,默认值为 cc
    CXX : C++ 编译器的名称,默认值为 g++
    $@ : 目标的完整名称
    $< : 第一个依赖文件的名称
    $^ : 所有的依赖文件
  • 获取变量的值
    $(变量名)\
# define
src = sub.o add.o mult.o div.o main.o
target = app

$(target):$(src)
        $(CC) $(src) -o $(app)

sub.o:sub.c
        gcc -c sub.c -o sub.o

add.o:add.c
        gcc -c add.c -o add.o

mult.o:mult.c
        gcc -c mult.c -o mult.o

div.o:div.c
        gcc -c div.c -o div.o

main.o:main.c
        gcc -c main.c -o main.o

1.6.5 模式匹配

add.o:add.c
    gcc -c add.c
div.o:div.c
    gcc -c div.c
sub.o:sub.c
    gcc -c sub.c
mult.o:mult.c
    gcc -c mult.c
main.o:main.c
    gcc -c main.c
%.o:%.c
    - %: 通配符,匹配一个字符串
    - 两个%匹配的是同一个字符串
%.o:%.c
    gcc -c $< -o $@

例子:

# define
src = sub.o add.o mult.o div.o main.o
target = app

$(target):$(src)
        $(CC) $(src) -o $(app)

%.o:%.c
    gcc -c $< -o $@

1.6.6 函数

  • $(wildcard PATTERN...)

    • 功能:获取指定目录下指定类型的文件列表
    • 参数:PATTERN 指的是某个或多个目录下的对应的某种类型的文件,如果有多个目录,一般使用空格间隔
    • 返回:得到的若干个文件的文件列表,文件名之间使用空格间隔
    • 示例:
      $(wildcard *.c ./sub/*.c)
      返回值格式: a.c b.c c.c d.c e.c f.c
  • $(patsubst <pattern>,<replacement>,<text>)

    • 功能:查找<text>的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合
      模式<pattern>如果匹配的话,则以<replacement>替换。
    • <pattern>可以包括通配符%,表示任意长度的字串。如果<replacement>中也包含%,那么,<replacement>中的这个%将是<pattern>中的那个%所代表的字串。(可以用\来转义,以\%来表示真实含义的%字符)
    • 返回:函数返回被替换过后的字符串
    • 示例:
      $(patsubst %.c, %.o, x.c bar.c)
      返回值格式: x.o bar.o

示例:

# define
# add.c sub.c main.c mult.c div.c
src = $(wildcard ./*.c)
objs = $(patsubst %.c, %.o, $(src))
target = app

$(target):$(objs)
        $(CC) $(objs) -o $(target)

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

.PHONY:clean 
# clean为伪目标,防止外界有clean文件时无法执行make clean命令

clean:
        rm $(objs) -f

1.7 GDB调试

标签:文件,gcc,入门,++,编程,编译,Linux,main,sub
From: https://www.cnblogs.com/mobbu/p/17547122.html

相关文章

  • 1.3 Linux文件系统
    一、Linux文件系统结构Linux下都是文件,所以没有Windows一样的盘,有的只有文件夹。cd/    //进入根目录ls     //查看根目录"/"下的文件及文件夹/bin   :存储了很多系统命令,/usr/sbin也存储了许多系统命令。/sbin  :超级用户root的根目录文件。/root......
  • 暑假到了,你家小孩有学编程吗?
    暑假到了,孩子下学期要上一年级,住的地方比较偏,没有编程培训班,买了一块BBC的microbit开发板,带孩子一起学编程。视频内容持续更新中,欢迎大家一起学习交流,陪伴孩子共同成长。欢迎点赞关注转发,一键三连哦~  https://www.bilibili.com/video/BV1EN411U7Fx/https://www.bilibili.......
  • 常用的Linux命令
    目录/文件管理命令命令说明示例ls显示当前目录下的文件和文件夹  ll 显示当前目录下的文件和文件夹的属性信息,例如文件权限、所有者、大小、修改日期等  cd 切换目录  mkdir 创建文件夹  rm 删除文件  rm-rf......
  • Linux基础27 NFS原理, 搭建, NFS挂载卸载, NFS参数
    一、什么是NFS共享存储,文件服务器1.NFS基本概述NFS是NetworkFileSystem的缩写及网络文件系统。NFS主要功能是通过局域网让不同的主机系统之间可以共享文件或目录NFS系统和windows网络共享、网络驱动器类似,只不过windows用于局域网,NFS用于企业集群架构中如果是大型网页,会用到......
  • 动态规划DP入门笔记
    动态规划以斐波那契数列为例:\(f_i\)状态\(f_i=f_{i-1}+f_{i-2}\)转移方程\(f_0=0\),\(f_1=1\)初始化dp的实现方法一般有三种,其中的两种(最重要的)如下#include<bits/stdc++.h>usingnamespacestd;intf[200010];signedmain(){ intn; scanf("%d",&n);......
  • Linux工具之numactl
     NUMA(Non-UniformMemoryAccess)字面直译为“非一致性内存访问”,对于Linux内核来说最早出现在2.6.7版本上。这种特性对于当下大内存+多CPU为潮流的X86平台来说确实会有不少的性能提升,但相反的,如果配置不当的话,也是一个很大的坑。本文就从头开始说说Linux下关于CPUNUMA特性的配......
  • SpringMVC入门案例
                ......
  • linux 中 M-cM-^@M-^@M-cM-^@M-^@特殊字符的处理
     001、[root@PC1test01]#lstest.txt[root@PC1test01]#cat-Atest.txt##存在特殊字符 M-cM-^@M-^@M-cM-^@M-^@TomM-cM-^@M-^@M-cM-^@M-^@2012-12-11car53000$JohnM-cM-^@M-^@M-cM-^@M-^@2013-01-13bike41000$TomM-cM-^@M-^@M-cM-^@M-......
  • Bootstrap 4 教程_编程入门自学教程_菜鸟教程-免费教程分享
    教程简介Bootstrap4是功能强大且流行的移动第一前端框架,用于在Web上构建响应式移动第一站点。这是Bootstrap的最新版本,它使用HTML,CSS和JavaScript。为什么要使用Bootstrap?它包含整个库中的移动优先样式,而不是在单独的文件中使用它们。只需具备HTML和CSS的知识,任何人都可以开......
  • 3Ds max入门教程:为男性角色创建服装T 恤
    推荐:NSDT场景编辑器助你快速搭建可二次开发的3D应用场景3dsMax角色服装教程在本3dsMax教程中,我们将为角色模型创建一个简单的 T恤。我们提供了一个“human_figure.obj”文件供您导入模型。因此,本教程将重点介绍的是创建服装(T恤)并使用修饰符使衬衫轻松包裹在人体模型周围......