目录一、gcc 编译器1.1 gcc的编译过程1.1.1 预处理1.1.2 编译1.1.3 连接链接1.1.4 汇编1.2 gcc的使用(1) 安装命令有些系统会默认安装(2) 单个文件生成可执行文件命令(3) 多文件生成可执行文件二、使用虚拟机的共享文件夹三、gdb调试器3.1 gdb的使用(1) 使用gcc编译包含标准调试信息的可执行文件(2) 启动gdb进入调试(3) 查看载入的文件(4) 设置断点(5) 查看断点(6) 运行代码(7) 查看变量值(8) 单步运行(9) 恢复运行(10) gdb命令四、make工程管理器4.1 makefile4.2 makefile的规则4.3 自动变量五、cmake5.1 为什么要cmake5.2 安装5.3 使用5.4 编写CMakeList.txt5.4.1 代码源文件不多,并且处于同一目录下5.4.2 代码源文件很多并且处于同一目录下时5.4.3 源文件多并且处于不同的目录下5.5 执行cmake一、gcc 编译器GCC 编译器是 Linux 系统下最常用的C/C 编译器GCC 编译器通常以gcc命令的形式在终端Shell中使用它有很多选项这是我们要重点学习的。gcc能够在当前CPU平台上为多种不同体系结构的硬件平台开发软件因此适合在嵌入式领域开发编译。1.1 gcc的编译过程1.1.1 预处理gcc首先对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析处理。1.1.2 编译用GCC编译C/C代码时它会试着用最少的时间完成编译并且编译后的代码易于调试。易于调试意味着编译后的代码与源代码有同样的执行顺序编译后的代码没有经过优化。1.1.3 连接链接当所有的目标文件都生成之后gcc就调用ld链接器来完成最后的关键性工作这个阶段就是连接。在连接阶段所有的目标文件被安排在可执行程序中的恰当的位置同时该程序所调用到的库函数也从各自所在的档案库中连到合适的地方。1.1.4 汇编汇编过程是针对汇编语言的步骤调用as进行工作一般来讲.S为后缀的汇编语言源代码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。1.2 gcc的使用(1)安装命令有些系统会默认安装sudo apt install gcc(2)单个文件生成可执行文件命令gcc test.c -o test.outo选项可以指定生成文件的名称和类型如果不指定则直接生成 a.out(3)多文件生成可执行文件gcc -c add.c -o add.o gcc -c suntraction.c -o subtraction.o gcc -c main.c -o main.o gcc main.o add.o subtraction.o -o test.out选项含义-c把预处理、编译、汇编都做了但是不链接(.o)-S只编译不汇编生成汇编代码-E只进行预编译不做其他处理-g在可执行程序中包含标准调试信息-o将 file 文件指定为输出文件-v打印出编译器内部编译各过程的命令行信息和编译器的版本-I指定头文件目录-L指定链接时库文件目录二、使用虚拟机的共享文件夹我们在Windows下写代码然后到Linux下编译是一种常见的编程方式。流程如下在Windows上创建文件夹设置虚拟机共享linux上创建文件夹sudo mkdir -p /mnt/hgfs/myshare关联两个系统下的文件夹挂载sudo mount -t vboxsf share /mnt/hgfs/myshare查看是否关联成功ls三、gdb调试器在写代码的过程中经常需要对代码进行调试虽然调试器并不是代码执行过程中必备的但确是一个必不可少的组成部分。gdb就是多数Linux开发人员使用的调试器可以方便的设置断点进行代码调试。我们在Windows下面会用到类似于DevC这样集成编译器、编辑器、调试器一体的开发工具而我们在Linux下面更多的则是使用Vim、gcc等。3.1 gdb的使用(1)使用gcc编译包含标准调试信息的可执行文件gcc -g test.c -o test.out(2)启动gdb进入调试gdb test.out进入调试后在gdb的启动过程会输出gdb当前的一些信息随后会显示到(gdb)开头的命令(3)查看载入的文件gdb l输入“l”(list)指令不仅可以查看文件代码还可以查看左边的行号方便我们对代码进行定位。(4)设置断点(gdb) b 5输入“b 行号”指令b的英文指的是BreakPoint可以在指定的行号设置一个断点。(5)查看断点gdb info b可以使用“info b”查看当前设置的断点情况。(6) 运行代码gdb r //从首行开始运行代码 gdb r 5//如果想从指定行开始运行可以在r后面加行号输入“r”run即可运行代码并且程序会在断点行执行前停止。(7) 查看变量值(gdb) p a //查看当前变量a的值输入“p 变量名”即可查看当前变量的值可以在调试时直接使用$X来访问变量。(8) 单步运行(gdb) n //n指的是next的缩写使用n命令会让代码往下执行并且不进入具体的函数。 (gdb) s //s指的是step的缩写也会让代码往下执行但如果遇到函数会跳转到函数。(9) 恢复运行(gdb) c //c指的是continue会把没有执行完的代码执行完毕代码执行完毕后程序处于停止状态。(10) gdb命令gdb有很多命令我们可以使用help来查看。(gdb) help //直接查看所有命令 (gdb) help n //查看n命令说明四、make工程管理器一个工程中的源文件不计其数其按类型、功能、模块分别放在若干个目录中makefile定义了一系列的规则来指定哪些文件需要先编译哪些文件需要后编译哪些文件需要重新编译甚至于进行更复杂的功能操作。4.1 makefilemakefile是make工程管理的配置文件我们只需要关注makefile文件的编写规则即可使用make。make以及makefile本身并不具备编译功能但是它们可以很好地协调、沟通gcc这样的编译器。4.2 makefile的规则在makefile文件中通常包含如下内容最终需要生成的文件或者可执行文件创建最终文件所需要依赖的文件创建可执行文件、依赖文件所时所需要运行的命令格式如下最终生成的文件:依赖文件 所需要的命令 //这里需要遵循makefile的规则使用Tab键添加一个缩进表示声明的是命令举个例子以加减法多文件项目为例咱们有main.c、add.c、subtraction.c文件最终需要生成一个可执行文件需要分别编译生成main.o、add.o、subtraction.o然后再将他们编译后的文件链接起来生成可执行文件过程很繁琐。但我们可以使用makefile来完成这件事情。main.out:main.o add.o subtraction.o gcc main.o add.o subtraction.o -o main.out main.o:main.c gcc -c main.c -o main.o add.o:add.c gcc -c add.c -o add.o subtraction.o:subtraction.c gcc -c subtraction.c -o subtraction.omake //使用make指令make会自行查找当前目录下的makefile执行其中的规则从而执行编译命令clean: rm -f *.o main.out //删除当前目录下的所有.o文件以及main.out文件4.3 自动变量我们可以使用自动变量来编写makefile这样可以简化工作量。和上面同样的makefile我们可以这样写main.out:main.o add.o subtraction.o gcc *.o -o $ %.o:%.c gcc -c $ -o $* 指的是当前目录下所有的同类型文件。% 指的是当前makefile文件中的所有文件。自动变量含义$*不包含扩展名的目标文件名称$所有的依赖文件以空格分开并以出现的先后为序可能包含重复的依赖文件$第一个依赖文件的名称$?所有时间戳比目标文件晚的依赖文件并以空格分开$目标文件的完整名称$^所有不重复的依赖文件以空格分开$%如果目标是归档成员则该变量表示目标的归档成员名称五、cmakecmake是一款跨平台项目构建工具可以用简单的语句来描述所有平台的编译过程能够输出各种各样的makefile或者project文件。cmake 可以编译源代码、制作程序库、产生适配器wrapper、还可以用任意的顺序建构执行档。5.1 为什么要cmake决定代码的组织方式及其编译方式也是程序设计的一部分。因此我们需要cmake和autotools这样的工具来帮助我们构建并维护项目代码。不同Make工具遵循着不同的规范和标准所执行的 Makefile 格式也千差万别。如果软件想跨平台必须要保证能够在不同平台编译。而如果使用上面的 Make 工具就得为每种标准写一次Makefile。cmake和autotools正是makefile的上层工具它们的目的正是为了产生可移植的makefile并简化自己动手写makefile时的巨大工作量。我们可以编写一个与平台无关的文本文件来制定整个编译流程来解决跨平台需要多个makefile的问题。5.2 安装sudo apt install cmake //安装cmake cmake -version //查看版本 sudo apt install g //安装cmake所依赖的g(gcc)5.3 使用编写 CMake 配置文件 CMakeLists.txt 。执行命令 cmake PATH 生成 Makefile。其中 PATH 是 CMakeLists.txt 所在的目录。使用 make 命令进行编译。5.4 编写CMakeList.txt5.4.1 代码源文件不多,并且处于同一目录下./more3 | ---main.c | ---add.c | ---add.h | ---subtraction.c | ---subtractuon.h#指定cmake运行本配置文件最低版本号要求 cmake_minimum_required(VERSION 3.10.2) #项目名称信息 project(Demo) #将这些c文件编译成Demo.out add_executable(Demo.out main.c add.c subtraction.c)5.4.2 代码源文件很多并且处于同一目录下时./more3 | ---main.c | ---add.c | ---add.h | ---subtraction.c | ---subtractuon.h | #假如还有很多源文件....#指定cmake运行本配置文件最低版本号要求 cmake_minimum_required(VERSION 3.10.2) #项目名称信息 project(Demo) #查找当前目录下所有源文件并将名称保存到DIR_SRCS变量 aux_source_directory(. DIR_SRCS) #生成指定目标文件Demo.out add_executable(Demo.out ${DIR_SRCS}) 源文件多并且处于不同的目录下5.4.3 源文件多并且处于不同的目录下./more3 | ---main.c | ---math/ | ---add.c | ---add.h | ---subtraction.c | ---subtractuon.h对于这种情况我们会在根目录以及不同的子目录下各编写一个CMakeLists.txt文件然后将子目录里的文件编译成静态库供main调用。#根目录下的CMakeLists.txt #指定cmake运行本配置文件最低版本号要求 cmake_minimum_required(VERSION 3.10.2) #项目名称信息 project(Demo) #查找当前目录下所有源文件并将名称保存到DIR_SRCS变量 aux_source_directory(. DIRSRCS) #编译math目录内的头文件 include_directories(./math) #添加math子目录 add_subdirectory(math) #生成指定目标文件Demo.out add_executable(Demo.out main.c) #添加链接库 target_link_libraries(Demo.out MathFunctions)#子目录下的CMakeLists.txt # 查找当前目录下的所有源文件并将名称保存到 DIRS 变量 aux_source_directory(. DIRS) # 生成链接库 这里的MathFunctions要和根目录下CMakeLists.txt中target_link_libraries对应 add_library (MathFunctions ${DIRS})5.5 执行cmakecmake CMakeList.txt所在位置 #执行cmake生成makefile文件 make #运行makefile编译
Linux编程笔记2【个人用】
目录一、gcc 编译器1.1 gcc的编译过程1.1.1 预处理1.1.2 编译1.1.3 连接链接1.1.4 汇编1.2 gcc的使用(1) 安装命令有些系统会默认安装(2) 单个文件生成可执行文件命令(3) 多文件生成可执行文件二、使用虚拟机的共享文件夹三、gdb调试器3.1 gdb的使用(1) 使用gcc编译包含标准调试信息的可执行文件(2) 启动gdb进入调试(3) 查看载入的文件(4) 设置断点(5) 查看断点(6) 运行代码(7) 查看变量值(8) 单步运行(9) 恢复运行(10) gdb命令四、make工程管理器4.1 makefile4.2 makefile的规则4.3 自动变量五、cmake5.1 为什么要cmake5.2 安装5.3 使用5.4 编写CMakeList.txt5.4.1 代码源文件不多,并且处于同一目录下5.4.2 代码源文件很多并且处于同一目录下时5.4.3 源文件多并且处于不同的目录下5.5 执行cmake一、gcc 编译器GCC 编译器是 Linux 系统下最常用的C/C 编译器GCC 编译器通常以gcc命令的形式在终端Shell中使用它有很多选项这是我们要重点学习的。gcc能够在当前CPU平台上为多种不同体系结构的硬件平台开发软件因此适合在嵌入式领域开发编译。1.1 gcc的编译过程1.1.1 预处理gcc首先对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析处理。1.1.2 编译用GCC编译C/C代码时它会试着用最少的时间完成编译并且编译后的代码易于调试。易于调试意味着编译后的代码与源代码有同样的执行顺序编译后的代码没有经过优化。1.1.3 连接链接当所有的目标文件都生成之后gcc就调用ld链接器来完成最后的关键性工作这个阶段就是连接。在连接阶段所有的目标文件被安排在可执行程序中的恰当的位置同时该程序所调用到的库函数也从各自所在的档案库中连到合适的地方。1.1.4 汇编汇编过程是针对汇编语言的步骤调用as进行工作一般来讲.S为后缀的汇编语言源代码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。1.2 gcc的使用(1)安装命令有些系统会默认安装sudo apt install gcc(2)单个文件生成可执行文件命令gcc test.c -o test.outo选项可以指定生成文件的名称和类型如果不指定则直接生成 a.out(3)多文件生成可执行文件gcc -c add.c -o add.o gcc -c suntraction.c -o subtraction.o gcc -c main.c -o main.o gcc main.o add.o subtraction.o -o test.out选项含义-c把预处理、编译、汇编都做了但是不链接(.o)-S只编译不汇编生成汇编代码-E只进行预编译不做其他处理-g在可执行程序中包含标准调试信息-o将 file 文件指定为输出文件-v打印出编译器内部编译各过程的命令行信息和编译器的版本-I指定头文件目录-L指定链接时库文件目录二、使用虚拟机的共享文件夹我们在Windows下写代码然后到Linux下编译是一种常见的编程方式。流程如下在Windows上创建文件夹设置虚拟机共享linux上创建文件夹sudo mkdir -p /mnt/hgfs/myshare关联两个系统下的文件夹挂载sudo mount -t vboxsf share /mnt/hgfs/myshare查看是否关联成功ls三、gdb调试器在写代码的过程中经常需要对代码进行调试虽然调试器并不是代码执行过程中必备的但确是一个必不可少的组成部分。gdb就是多数Linux开发人员使用的调试器可以方便的设置断点进行代码调试。我们在Windows下面会用到类似于DevC这样集成编译器、编辑器、调试器一体的开发工具而我们在Linux下面更多的则是使用Vim、gcc等。3.1 gdb的使用(1)使用gcc编译包含标准调试信息的可执行文件gcc -g test.c -o test.out(2)启动gdb进入调试gdb test.out进入调试后在gdb的启动过程会输出gdb当前的一些信息随后会显示到(gdb)开头的命令(3)查看载入的文件gdb l输入“l”(list)指令不仅可以查看文件代码还可以查看左边的行号方便我们对代码进行定位。(4)设置断点(gdb) b 5输入“b 行号”指令b的英文指的是BreakPoint可以在指定的行号设置一个断点。(5)查看断点gdb info b可以使用“info b”查看当前设置的断点情况。(6) 运行代码gdb r //从首行开始运行代码 gdb r 5//如果想从指定行开始运行可以在r后面加行号输入“r”run即可运行代码并且程序会在断点行执行前停止。(7) 查看变量值(gdb) p a //查看当前变量a的值输入“p 变量名”即可查看当前变量的值可以在调试时直接使用$X来访问变量。(8) 单步运行(gdb) n //n指的是next的缩写使用n命令会让代码往下执行并且不进入具体的函数。 (gdb) s //s指的是step的缩写也会让代码往下执行但如果遇到函数会跳转到函数。(9) 恢复运行(gdb) c //c指的是continue会把没有执行完的代码执行完毕代码执行完毕后程序处于停止状态。(10) gdb命令gdb有很多命令我们可以使用help来查看。(gdb) help //直接查看所有命令 (gdb) help n //查看n命令说明四、make工程管理器一个工程中的源文件不计其数其按类型、功能、模块分别放在若干个目录中makefile定义了一系列的规则来指定哪些文件需要先编译哪些文件需要后编译哪些文件需要重新编译甚至于进行更复杂的功能操作。4.1 makefilemakefile是make工程管理的配置文件我们只需要关注makefile文件的编写规则即可使用make。make以及makefile本身并不具备编译功能但是它们可以很好地协调、沟通gcc这样的编译器。4.2 makefile的规则在makefile文件中通常包含如下内容最终需要生成的文件或者可执行文件创建最终文件所需要依赖的文件创建可执行文件、依赖文件所时所需要运行的命令格式如下最终生成的文件:依赖文件 所需要的命令 //这里需要遵循makefile的规则使用Tab键添加一个缩进表示声明的是命令举个例子以加减法多文件项目为例咱们有main.c、add.c、subtraction.c文件最终需要生成一个可执行文件需要分别编译生成main.o、add.o、subtraction.o然后再将他们编译后的文件链接起来生成可执行文件过程很繁琐。但我们可以使用makefile来完成这件事情。main.out:main.o add.o subtraction.o gcc main.o add.o subtraction.o -o main.out main.o:main.c gcc -c main.c -o main.o add.o:add.c gcc -c add.c -o add.o subtraction.o:subtraction.c gcc -c subtraction.c -o subtraction.omake //使用make指令make会自行查找当前目录下的makefile执行其中的规则从而执行编译命令clean: rm -f *.o main.out //删除当前目录下的所有.o文件以及main.out文件4.3 自动变量我们可以使用自动变量来编写makefile这样可以简化工作量。和上面同样的makefile我们可以这样写main.out:main.o add.o subtraction.o gcc *.o -o $ %.o:%.c gcc -c $ -o $* 指的是当前目录下所有的同类型文件。% 指的是当前makefile文件中的所有文件。自动变量含义$*不包含扩展名的目标文件名称$所有的依赖文件以空格分开并以出现的先后为序可能包含重复的依赖文件$第一个依赖文件的名称$?所有时间戳比目标文件晚的依赖文件并以空格分开$目标文件的完整名称$^所有不重复的依赖文件以空格分开$%如果目标是归档成员则该变量表示目标的归档成员名称五、cmakecmake是一款跨平台项目构建工具可以用简单的语句来描述所有平台的编译过程能够输出各种各样的makefile或者project文件。cmake 可以编译源代码、制作程序库、产生适配器wrapper、还可以用任意的顺序建构执行档。5.1 为什么要cmake决定代码的组织方式及其编译方式也是程序设计的一部分。因此我们需要cmake和autotools这样的工具来帮助我们构建并维护项目代码。不同Make工具遵循着不同的规范和标准所执行的 Makefile 格式也千差万别。如果软件想跨平台必须要保证能够在不同平台编译。而如果使用上面的 Make 工具就得为每种标准写一次Makefile。cmake和autotools正是makefile的上层工具它们的目的正是为了产生可移植的makefile并简化自己动手写makefile时的巨大工作量。我们可以编写一个与平台无关的文本文件来制定整个编译流程来解决跨平台需要多个makefile的问题。5.2 安装sudo apt install cmake //安装cmake cmake -version //查看版本 sudo apt install g //安装cmake所依赖的g(gcc)5.3 使用编写 CMake 配置文件 CMakeLists.txt 。执行命令 cmake PATH 生成 Makefile。其中 PATH 是 CMakeLists.txt 所在的目录。使用 make 命令进行编译。5.4 编写CMakeList.txt5.4.1 代码源文件不多,并且处于同一目录下./more3 | ---main.c | ---add.c | ---add.h | ---subtraction.c | ---subtractuon.h#指定cmake运行本配置文件最低版本号要求 cmake_minimum_required(VERSION 3.10.2) #项目名称信息 project(Demo) #将这些c文件编译成Demo.out add_executable(Demo.out main.c add.c subtraction.c)5.4.2 代码源文件很多并且处于同一目录下时./more3 | ---main.c | ---add.c | ---add.h | ---subtraction.c | ---subtractuon.h | #假如还有很多源文件....#指定cmake运行本配置文件最低版本号要求 cmake_minimum_required(VERSION 3.10.2) #项目名称信息 project(Demo) #查找当前目录下所有源文件并将名称保存到DIR_SRCS变量 aux_source_directory(. DIR_SRCS) #生成指定目标文件Demo.out add_executable(Demo.out ${DIR_SRCS}) 源文件多并且处于不同的目录下5.4.3 源文件多并且处于不同的目录下./more3 | ---main.c | ---math/ | ---add.c | ---add.h | ---subtraction.c | ---subtractuon.h对于这种情况我们会在根目录以及不同的子目录下各编写一个CMakeLists.txt文件然后将子目录里的文件编译成静态库供main调用。#根目录下的CMakeLists.txt #指定cmake运行本配置文件最低版本号要求 cmake_minimum_required(VERSION 3.10.2) #项目名称信息 project(Demo) #查找当前目录下所有源文件并将名称保存到DIR_SRCS变量 aux_source_directory(. DIRSRCS) #编译math目录内的头文件 include_directories(./math) #添加math子目录 add_subdirectory(math) #生成指定目标文件Demo.out add_executable(Demo.out main.c) #添加链接库 target_link_libraries(Demo.out MathFunctions)#子目录下的CMakeLists.txt # 查找当前目录下的所有源文件并将名称保存到 DIRS 变量 aux_source_directory(. DIRS) # 生成链接库 这里的MathFunctions要和根目录下CMakeLists.txt中target_link_libraries对应 add_library (MathFunctions ${DIRS})5.5 执行cmakecmake CMakeList.txt所在位置 #执行cmake生成makefile文件 make #运行makefile编译