makefile 基础知识 嵌入式linux带有configure的开源项目的编译 lvgl 编译ffmpeg
带有configure的开源项目的编译案例
以ffmpeg为例 嵌入式开发项目一般需要交叉编译一些常用的动态库, 编译时,需要指定头文件位置,库文件位置, 部分时候还需要指定库文件 此处编译参考lvgl的编译需求 注意交叉编译链的配置
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg ./configure --disable-all --disable-autodetect --disable-podpages --disable-asm --enable-avcodec --enable-avformat --enable-decoders --enable-encoders --enable-demuxers --enable-parsers --enable-protocol='file' --enable-swscale --enable-zlib --cc=aarch64-linux-gnu-gcc --strip=aarch64-linux-gnu-strip --arch=arm --prefix=/root/mylvgl --enable-cross-compile --enable-shared --extra-ldflags="-L/opt/EmbedSky/TQT507/CoreA/longan/out/t507/evb/longan/buildroot/host/lib -L/opt/EmbedSky/TQT507/CoreA/longan/out/t507/evb/longan/buildroot/target/usr/lib -L/opt/EmbedSky/TQT507/CoreA/longan/out/t507/evb/longan/buildroot/target/lib" --extra-cflags="-I/opt/EmbedSky/TQT507/CoreA/longan/out/t507/evb/longan/buildroot/host/include/ -I/opt/EmbedSky/TQT507/CoreA/longan/out/t507/evb/longan/buildroot/host/aarch64-buildroot-linux-gnu/sysroot/usr/include" make clean && make -j4 && make install
使用gcc编译c++ eg: gcc --stdc++ main.cpp
makefile从入门到项目编译实战
gcc 编译c++ eg: gcc -lstdc++ main.c -o mian
根据以上变量对makefile进行一步一步改造 使用系统量一个好处是可以跨平台
如果没有伪目标, make clean 会先看当前目录下是否有clean文件夹,有了伪目标,make clean会直接在makefile中执行clean 对应命令,不管是否有clean文件 伪目标在makefile哪个地方无所谓(一般在文件开头或者结尾) makefile进一步简化
5 makefile执行过程 makefile检测文件时间是否改变
执行时候,可能报错找不到动态库,解决方案 1 将库copy到指定目录,linux下一般为 /usr/lib /usr/local/lib 2 在linux修改文件/etc/ld.so.conf 或者/etc/ld.so.conf/*.config,指定动态库目录 3 将当前目录设置为动态库目录
将二进制反汇编为汇编语言 objdump -DC main>main.txt
在汇编代码中可以找到静态库对应的汇编代码,但是找不到动态库的汇编代码
特殊情况下:
8 makefile的 包含 类似于c语言的include
注意 = 和 := 是不一样的概念 前面带上@ 可以不输出命令行直接执行命令
Y=123
Y=$(Y) 这中写法会报错,因为这样会造成死循环(=表示使用最终变量,使用=即说明,之前这个变量没有存在过)
正确的使用如下
:=表示就在当前行,计算出当前值,若需要推论其他值,则也是当前位置之前的其他值带入计算出来的结果
=表示makefile文档加载完毕后,在执行函数前变量最后一次=f赋值结果
若是当前值与上面的值有关系 则直接使用:=
实际使用案例
9 makefile中调用shell命令
10 makefile 嵌套调用
11 makefile条件判断
12 循环
makefile 传参 eg: make flag=1 就将flag=1传入程序中了
13 函数定义和调用 本质上是多行命令,放在外面了 传参,多一个,少一个不影响,无效参数,默认为空 $(0) 默认是函数名 函数没有返回值
14 make make install 启动
makefile
TARGET:=006_main OBJ:=$(TARGET).o CC:=g++ PATHS:=/tmp/006_main/ BIN:=/usr/local/bin/ START_SH:=$(TARGET)_start STOP_SH:=$(TARGET)_stop LOG:=$(PATHS)$(TARGET).log $(TARGET):$(OBJ) install:$(TARGET) if [ -d $(PATHS) ];\ then echo $(PATHS) exist; \ else \ mkdir $(PATHS);\ cp $(TARGET) $(PATHS);\ ln -sv $(PATHS)$(TARGET) $(BIN);\ touch $(LOG);\ chmod a+rwx $(LOG);\ echo "$(TARGET)>$(LOG) & echo $(TARGET) running...">$(PATHS)$(START_SH);\ echo "killall $(TARGET)">$(PATHS)$(STOP_SH);\ chmod a+x $(PATHS)$(START_SH);\ chmod a+x $(PATHS)$(STOP_SH);\ ln -sv $(PATHS)$(START_SH) $(BIN);\ ln -sv $(PATHS)$(STOP_SH) $(BIN);\ fi; clean: $(RM) $(TARGET) $(OBJ) $(BIN)$(TARGET) $(BIN)$(START_SH) $(BIN)$(STOP_SH) $(RM) -rf $(PATHS) .PHONY:clean install
006_main.cpp
// // #include<iostream> #include<unistd.h> using namespace std; int main(){ int i=0; while (true){ i++; cout<<"006-main-running-"<<i<<endl; sleep(1); } return 0; }
关于网络下载的源码用configure 进行配置的,可参考如下步骤(交叉编译)
用png举例
wget https://nchc.dl.sourceforge.net/project/libpng/libpng16/1.6.38/libpng-1.6.38.tar.gz
tar -zxvf libpng-1.6.38.tar.gz
cd libpng-1.6.38
编译png
./configure CC=aarch64-linux-gnu-gcc --host=arm --prefix=/root/jclvgl CPPFLAGS="-I/opt/EmbedSky/TQT507/CoreA/longan/out/t507/evb/longan/buildroot/host/aarch64-buildroot-linux-gnu/sysroot/usr/include" LDFLAGS="-L/opt/EmbedSky/TQT507/CoreA/longan/out/t507/evb/longan/buildroot/target/usr/lib"
sudo make
sudo make install
注意库之间的依赖
//
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构