ZYNQ - 嵌入式Linux开发 -05- Linux C编程和Makefile(一)

简介: ZYNQ - 嵌入式Linux开发 -05- Linux C编程和Makefile

写在前面


本文主要介绍了关于Linux C编程的相关内容以及介绍了Makefile的简单使用教程。

VIM编辑器


如果要在终端模式下进行文本编辑或者修改文件就可以使用 VI/VIM 编辑器,Ubuntu 自带了 VI 编辑器,但是 VI 编辑器使用不方便,比如不能使用键盘上的上下左右键调整光标位置。

VIM 编辑器是 VI 编辑器升级版本, VI/VIM 编辑器都是一种基于指令式的编辑器,不需要鼠标,也没有菜单,仅仅使用键盘来完成所有的编辑工作。

需要先安装 VIM 编辑器,命令如下:

sudo apt-get install vim

VIM 默认是以只读模式打开的文档,因此我们要切换到输入模式,切换到输入模式的命令如下:

切换输入指令:

image.png

移动光标指令:

image.png

屏幕翻滚指令:

指令 介绍
Ctrl+b 屏幕向上翻一页,相当于上一页。
Ctrl+f 屏幕向下翻一页,相当于下一页。

复制、删除和粘贴指令:

image.png

保存文档的命令是在底行模式中,要先进入到指令模式,进入底行模式的方式是先进入指令模式下,然后在指令模式下输入“:”进入底行模式, 常用的命令如下:

image.png

GCC 编译器


gcc 命令


gcc 命令格式如下:

gcc [选项] [文件名字]

image.png

编译流程


GCC 编译器的编译流程是:预处理、汇编、编译和链接。预处理就是对程序中的宏定义等相关的内容先进行前期的处理。汇编是先将 C 文件转换为汇编文件。当 C 文件转换为汇编文件以后就是文件编译了,编译过程就是将 C 源文件编译成.o 结尾的目标文件。编译生成的.o 文件不能直接执行,而是需要最后的链接,如果你的工程有很多个 c 源文件的话最终就会有很多.o 文件,将这些.o 文件链接在一起形成完整的一个可执行文件。

编程第一课:hello world!


编写代码包括两部分:代码编写和编译。

创建一个test.c编写代码:

 #include "stdio.h"
 int main(){    
  printf("hello_Word!\n");
 }

然后进行编译

gcc test.c -o test

输入ls命令进行查看,此时已经生成了test可执行文件。

image.png

此时进行运行可执行文件即可打印出编程实现的结果:

image.png

Makefile


使用 GCC 编译器在 Linux 进行 C 语言编译,通过在终端执行 gcc 命令来完成 C

文件的编译,在使用GCC进行编程的时候,实际上的编程流程是先把c文件进行编译,生成.o文件,然后将所有编译出来的.o文件进行重新编译执行成可执行文件。

在进行编译的过程中,可能会碰到修改过后不知道哪个的文件被修改了,或者希望自己只把个别文件进行编译等情况,上述情况使用GCC编译器也可以进行解决,但是,GCC编译默认情况下是对所有的文件进行编译,一旦工程量变大这将花费大量的时间,通样,GCC也可以对指定文件进行编译,但是操作过于繁琐,大部分都是重复性的工作,所以就有了Makefile这样的工具解决编译中的重复操作的问题,提高开发的效率。

示例工程


编写一个实验makefile的示例工程用于学习makefile的使用。

main.c

#include <stdio.h>
#include "test.h"
#include "test1.h"
void main(){
    test1();
    test2();
}

test.h

#ifndef _TEST_H_
#define _TEST_H_
#include <stdio.h>
void test1();
#endif // !_TEST_H_

test.c

#include "test.h"
void test1(){
    printf("this is test1\n");
}

test1.h

#ifndef _TEST1_H_
#define _TEST1_H_
#include <stdio.h>
void test2();
#endif // !_TEST_H_

test1.c

#include "test1.h"
void test2(){
    printf("this is test2\n");
}

Makefile格式


Makefile 里面是由一系列的规则组成的,这些规则格式如下:

目标…... : 依赖文件集合……
  命令 1
  命令 2
  ……

比如:

main : main.o test.o test1.o
  gcc -o main main.o test.o test1.o

这条规则的目标是 main, main.o,test.o 和 test1.o 是生成 main 的依赖文件,如果要更新目标 main,就必须要先更新它的所有依赖文件,如果依赖文件中的任何一个有更新,那么目标也必须更新,“更新”就是执行一遍规则中的命令列表。

为上述demo工程创建一个Makefile文件,在终端中键入vim Makefile创建Makefile文件,然后在Makefile文件中键入以下内容:

main:main.o test.o test1.o
  gcc -o main main.o test.o test1.o
main.o:main.c
  gcc -c main.c
test.o:test.c
  gcc -c test.c
test1.o:test1.c
  gcc -c test1.c
clean:
  rm *.o
  rm main

在Makefile文件中,第一条规则会成为默认的目标,默认的目标更新的工作,也即Makefile文件执行就为了完成整个更新工作。在首次编译时,main文件未存在,所以第一条规则会正常执行,同时该规则依赖于main.o test.o test1.o三个.o文件,所以要进行更新三个.o文件,然后Makefile检索到更新.o文件的规则,gcc -c *.c,也即不链接编译.c文件,生成.o。最后一个规则目标是

clean,它没有依赖文件,因此会默认为依赖文件都是最新的,所以其对应的命令不会执行,当我们想要执行clean 的话可以直接使用命令“make clean”,执行以后就会删除当前目录下所有的.o 文件以及 main,因此,clean 的功能就是完成工程的清理。

image.png

总结一下 Make 的执行过程:

  1. make 命令会在当前目录下查找以 Makefile(makefile 其实也可以)命名的文件。
  2. 当找到 Makefile 文件以后就会按照 Makefile 中定义的规则去编译生成最终的目标文件。
  3. 当发现目标文件不存在,或者目标所依赖的文件比目标文件新(也就是最后修改时间比目标文件晚)的话就会执行后面的命令来更新目标。
目录
相关文章
|
9天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
62 13
|
2月前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
116 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
3月前
|
存储 Linux 开发工具
如何进行Linux内核开发【ChatGPT】
如何进行Linux内核开发【ChatGPT】
|
4月前
|
Java Linux API
Linux设备驱动开发详解2
Linux设备驱动开发详解
60 6
|
4月前
|
消息中间件 算法 Unix
Linux设备驱动开发详解1
Linux设备驱动开发详解
62 5
|
4月前
|
NoSQL Linux C语言
嵌入式GDB调试Linux C程序或交叉编译(开发板)
【8月更文挑战第24天】本文档介绍了如何在嵌入式环境下使用GDB调试Linux C程序及进行交叉编译。调试步骤包括:编译程序时加入`-g`选项以生成调试信息;启动GDB并加载程序;设置断点;运行程序至断点;单步执行代码;查看变量值;继续执行或退出GDB。对于交叉编译,需安装对应架构的交叉编译工具链,配置编译环境,使用工具链编译程序,并将程序传输到开发板进行调试。过程中可能遇到工具链不匹配等问题,需针对性解决。
156 3
|
消息中间件 缓存 Unix
[面试必备]嵌入式Linux内核开发必须了解的三十道题
[面试必备]嵌入式Linux内核开发必须了解的三十道题
|
Linux
嵌入式Linux QT开发之如何实现获取磁盘空间大小的应用逻辑
嵌入式Linux QT开发之如何实现获取磁盘空间大小的应用逻辑
253 0
|
Linux Go 人机交互
嵌入式linux之go语言开发(十三)LittlevGL,漂亮的嵌入式GUI的go语言绑定
嵌入式linux之go语言开发(十三)LittlevGL,漂亮的嵌入式GUI的go语言绑定
|
存储 XML JSON
嵌入式linux之go语言开发(十二)参数配置文件存储模块开发
嵌入式linux之go语言开发(十二)参数配置文件存储模块开发