02.嵌入式Linux开发工具

嵌入式Linux开发工具

1.vi/vim/gvim:文本编辑器

(1)适用场景

单文件编辑;vim+插件(高度定制)>IDE

(2)vim模式

命令行模式(初次进入,按a,i进入插入模式)

底行模式(shift+:)wq保存退出;wq!强制保存退出

插入模式(按esc可切换为命令行模式)

(3)vim配置(vimrc):

通过修改/etc/vim/vimrc文件(可以修改行号、缩进风格、鼠标支持等);

同时可以安装插件;

(4)vim的使用

命令行:yy复制 p粘贴 dd删除 u恢复上一行

底行模式:1. 查找 /+字符串?+字符串

​ 2.替换:s/旧的字符串/新的字符串 替换一个;

s/旧的字符串/新的字符串/g 替换一整行

行号,行号 s/旧的字符串/新的字符串/g 替换a-b行

%s/旧的字符串/新的字符串/g 替换全文

s/旧的字符串/新的字符串/gc 询问该行的字符串是否要替换

​ 3.编辑多个文件:vim 文件1 文件2 文件3;跳转 n+文件名;在文件中导入其他文件 r+文件名;另外存储使用 w+文件名;另存储从a行到b行使用 行号,行号 w+文件名;同时编辑其他文件使用切屏命令 sp+文件名

2.gcc编译器:将文本文件编译成可执行文件

(1)、背景

GCC(GNU Compiler Collection,GNU 编译器套装),是一套由 GNU 开发的编程语言编译器。GCC 原名为 GNU C 语言编译器,因为它原本只能处理 C语言。GCC 快速演进,变得可处理 C++、Fortran、Pascal、Objective-C、Java 以及 Ada 等他语言。

(2)、优点:

1、可以交叉编译:在一种计算机环境中运行的编译程序,能编译出在另一种环境下运行的代码,我们就称这种编译器支持交叉编译。这个编译过程就叫交叉编译。简单来说,就是在一个平台上生成另一个平台上的可执行代码,在宿主机编译出在目标机运行的文件。

2、编译优化:优化等级越高,编译时间越长,运行时间越短;省时间省空间

​ 【1】‘-O’:基本的优化;删除未使用的代码、简化表达式、删除冗余的指令等。

​ 【2】'-O2’更高级别的优化;包括基本优化级别的所有优化,并增加了额外的优化,如函数内联、循环展开、常量传播、数据流分析等。

​ 【3】‘-O3’最高级别的优化;它包括’-O2’级别的所有优化,并且进一步增加了一些更激进的优化,如向量化、循环优化、函数调用优化等。

其他优化:’-Os‘优化代码大小和’-Ofast‘最大优化

(3)、编译过程 .c -> .s - > .o ->elf

1、预处理:将头文件和所有的宏定义展开,gcc -E 1.c -o 1.i 可查看

eg:stdio.h 中包含了输入输出

2、翻译:gcc -S 1.i -o 1.s将C语言文件变成汇编语言;

3、汇编:将汇编语言变成目标文件(二进制文件);gcc -c 1.s -o 1.o

4、链接:把二进制重新排版变成可执行的二进制文件;gcc 1.o -o 1

5、执行:./1

(4)、相关指令

gcc -w 1.c -o 1 忽略警告;

gcc -Wall 1.c -o 1 显示所有的错误及警告;

gcc -D紧跟一个定义 1.c -o 1 定义一个宏定义;相当于参数传入进行判断,原代码没有改变。eg:

条件编译:在预处理的时候进行判断使用ifdef …else…endif

#include<stdio.h>
#define Max 30
int main()
{
#ifdef DEFINE
	printf("I have a define!\n");
#else
	printf("I don't have a define!\n");
#endif
	return 0;
}//使用正常编译输出结果为I don't have a define!
//使用gcc -DDEFINE 1.c -o 1命令进行编译则结果会显示I have a define!但是代码并未发生改变。

(5)、库函数和库文件

1、库文件:保存函数和变量,里面的函数和变量只能使用,但是看不到其实现过程

2、库函数(保存在库文件里):printf scanf strcpy struct

3、库文件分类

【1】、静态库.a:保存函数和变量,在编译阶段加载到可执行文件中;

【2】、动态库.so:保存的函数和变量,在执行阶段加载到执行文件中;

4、使用静态库和动态库的区别

【1】、使用静态库编译出来的执行文件大小 > 使用动态库编译出来的可执行文件大小 —>内存的开销

【2】、使用静态库编译出来的执行文件执行速度 > 使用动态库编译出来的可执行文件执行速度

【3】、使用静态库编译出来的执行文件升级 < 使用动态库编译出来的可执行文件升级

【4】、使用静态库编译出来的执行文件程序部署 > 使用动态库编译出来的可执行文件程序部署

5、库文件的存放路径:系统运行所需要的库文件:/lib

​ 第三方软件和工具所需要的库:/usr/lib

编译时,编译器会自动到这两个目录里查找所需要链接的库文件

6、制作和使用静态库:

【1】、将目标源文件编译成目标文件;gcc -c 目标源文件 -o 目标文件.o

【2】、使用ar工具制作静态库:ar -rcs(库不存在就创建,存在就更新) 所要生成的库文件名字(lib+库名+后缀.a) 目标文件.o

【3】、使用静态库:-l:指定加载哪一个静态库 -l库名

-L:指定加载的库文件的存放路径

当使用静态库时不指定静态库的存放路径会报错;可以通过cp命令将静态库拷贝到/urs/lib 或/lib 也就是第三方软件和工具或者系统所需要的库文件目录下

7、制作和使用动态库:

【1】、创建动态库:gcc -shared -fPIC -o 库名.so 源文件.c

【2】、使用动态库:gcc 源文件.c ./库名.so -o 可执行文件名

也可以通过cp命令将动态库复制到系统库文件目录下面,然后使用gcc 源文件.c -o 可执行文件名 -l库名实现对动态库的使用。

注意:当动态库和静态库同时存在时,优先调用动态库;

(6)、实现多文件同时编译:

**方法1、**添加自己定义的头文件

注意:#include<stdio.h> vs #include"stdio.h" 的不同

”stdio.h“表示从当前文件目录下开始寻找头文件,若没有,再到系统文件目录查找,再没有就报错。

<stdio.h>表示从系统库文件目录开始寻找,若没有,就报错。

规范:<>包含系统头文件,“ ”自定义头文件

如果在当前目录下没有找到相应的自定义头文件,可以使用gcc -I/root/205/1105/test main.c add.c -o main进行编译,其中gcc -I指定头文件的第三方搜索路径。

//要插入的头文件add.h
int add(int a,int b);//声明
//要插入的主体add.c
int add(int a,int b)
{
    return a+b;
}
//被插入的主体test.c
#include<stdio.h>
#include"add.h"
int main()
{
    int a=add(1,2);
    printf("%d\n",a);
    return 0;
}//使用gcc main.c add.c -o main命令进行编译

**方法2、**生成动态库:

将其他文件生成一个动态库ad.so,在运行主体的时候使用动态库(动态库不可被查看具有保密性;);

生成动态库:gcc -shared add.c -o ad.so

生动态库之后,删除add.c之后,运行不受影响;

使用动态库:gcc test.c ./ad.so -o test

修改动态库之后其他代码不受影响,不需要编译主体文件,可以直接运行结果;

动态库不参与编译,当删除动态库时候,有影响,主体会报错。

**方法3、**生成静态库:

将要被插入的目标文件add.c生成可执行文件;

gcc -c add.c -o add.o

将目标文件add.o打包成一个静态库;

ar rcs libAdd.a add.o

要执行的文件test.c加入静态库生成执行结果

gcc test.c -o test -L. -lAdd

静态库参与编译,主体生成的执行文件含有静态库内容,当删除静态库之后,主体不受影响

(7)、目标文件ELF

1、可重定位目标文件:包含二进制代码和数据,其形式可以和其他目标文件进行合并,创建一个可执行目标文件。比如编译的中间产物.o文件。

2、可执行目标文件:包含二进制代码和数据,可直接被加载器加载执行

3、共享目标文件:可被动态的加载和链接

额外小知识:time ./main可以测试main这个可执行文件的运行速度

3、工程管理工具:makefile

由目标 依赖 指令三个部分组成;Make工具从上

target:可以实一个目标文件,也可以是一个执行文件,还可以是一个标签

prerequisites:生成该target所依赖的文件,可以有多个依赖

command:该target要执行的命令(任意的shell命令)

#基本格式:
#target...:prerequisites
#	   command.....

func: add.c test.c
	gcc add.c test.c -o func

直接输入make进行执行生成目标文件func

写法二:使用变量代替要执行的文件

OBJECTS=add.c sub.c test.c
func: ${OBJECTS}
	gcc ${OBJECTS} -o func

伪目标:提供给make工具的一些命令,而不是用来构建文件,不对应实际的文件,目的是执行一些特定的操作:如清理编译过的目标文件、运行测试等。

.PHONY:clean install
clean://卸载目标文件
	rm -f func
	
install://复制目标文件添加到本地
	cp func /home/lvguanzhong/
4、gdb调试工具

编译的可执行程序需要带上调试信息

gcc -g main.c -o main

gdb main

设置断点:breakpoint b + num(行数)

展示断点信息:info b

运行:r

打印某个变量的值 :print a

单步调试:step

运行至下一行(不进入函数):next

通过vscode进行断点调试:F5 run F10 next F11 step

5.shell脚本

shell脚本:一个用户跟操作系统之间的一个命令解释器;

常见的shell:Bourne Shell(/usr/bin/sh或/bin/sh);Bourne Again Shell(/bin/bash);C Shell(/usr/bin/csh);K Shell(/usr/bin/ksh);Shell for Root(/sbin/sh)

首先需要对1.sh文件进行修改权限,然后直接运行./1.sh

#!/bin/bash
#创建10个.c文件
for((i=1;i<=10;i++))
do
	filename="$i.c"
	touch $filename
	chmod 666 $filename//对文件修改权限
done
#!/bin/bash
#删除.c文件
rm -f *.c
#!/bin/bash
#单独对1.c文件进行额外的赋予权限
for ((i=1; i<=10; i++))
do
	filename="$i.c"//不能有空格
	if [ $filename == "1.c" ]; then//注意每一个中间必须要有空格
		chmod 444 $filename
	fi
done

echo输出字符,向文件中编辑内容

#!/bin/bash
for file in *.c
do 
	echo "#include<stdio.h>
#输出文本内容
		int main()
		{
			return 0;
		}
	" >> $file 
#>>重定向符号,将输出内容定位到.c文件中
done
#!/bin/bash
#编译所有.c文件,生成可执行文件
index=0
for file in *.c
do
	index=`expr $index + 1 `
	gcc $file -o $index
done
#!/bin/bash
#删除所有的可执行文件
floder=$(pwd)
for file in $folder/*
do
	if [[ -x "$file" && "${file##*.}" != "sh" ]]; then
#-x "$file"代表可执行文件,${file##*.}对文件取后缀名
		rm -f $file
		echo "delete $file"
	fi
done
6、git 版本管理工具
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值