香橙派3B学习笔记13:deb 打包调用系统库与.so动态链接库的程序(部分失败)

之前接触到了snap打包自己的应用程序与依赖,但它的默认沙盒隔离的机制导致其访问系统库有局限性,它在访问硬件资源的时候没有的那些权限需要额外声明,不符合应用发布的便携性要求。

本文学习下如何用deb打包的方式打包自己需要调用系统库的程序。顺便将之前的gcc动态链接库的流程走一遍

本文失败的部分是,并没有像预期的那样能将我的so文件复制到usr/local/lib,正常的打包解包是可以的,感觉就只是和压缩包一样......

目录

DEB包的组成:

准备需要打包的程序:

GPIO_LED.c  与 GPIO_LED.h :

编译动态链接库:

程序文件调用动态链接库LED_light.c:

编译C文件为可执行文件:

验证程序运行:

安装必要的工具:

创建 ledlight 的 DEB 包:

创建项目目录结构:

创建control文件:

依赖库的处理_postinst文件:

创建install文件: 

卸载前脚本_prerm 文件:

构建规则rules 文件:

创建changelog版本号文件:

设定文件权限:

生成deb包:

解包deb:

参考文章:


DEB包的组成:

DEB(Debian Package)是Debian及其衍生系统(如Ubuntu)使用的软件包格式,主要用于软件的安装、升级和管理。

一个DEB包本质上是一个ar归档文件,他在构建前,包含以下核心组成部分:

myapp-1.0/                  # 项目根目录(通常与包名+版本一致)
├── debian/                 # Debian 打包专用目录(必须存在)
│   ├── control             # 包的元数据(名称、版本、依赖等)
│   ├── changelog           # 包的更新日志(生成版本号)
│   ├── rules               # 构建规则(Makefile 风格的脚本)
│   ├── copyright           # 版权信息
│   ├── compat              # 兼容性声明(如 "10" 表示 Debian Policy 10)
│   ├── source/             # 源码包相关配置(可选)
│   ├── install             # 指定安装文件的规则(如 `usr/bin/* usr/bin`)
│   ├── preinst             # 安装前脚本(可选)
│   ├── postinst            # 安装后脚本(可选)
│   ├── prerm               # 卸载前脚本(可选)
│   ├── postrm              # 卸载后脚本(可选)
│   └── conffiles           # 配置文件列表(如 `/etc/myapp/config.conf`)
├── src/                    # 项目源码目录(可选)
│   ├── main.c
│   └── Makefile
└── build/                  # 构建临时目录(通常自动生成)
文件名类型说明
control纯文本文件定义包的元数据(无后缀)。
changelog纯文本文件记录版本更新历史(无后缀,格式遵循 Debian Policy)。
rules可执行脚本构建规则(无后缀,本质是 Makefile 脚本,需 chmod +x)。
copyright纯文本文件版权声明(无后缀)。
compat纯文本文件兼容性声明(无后缀,内容如 10)。
install纯文本文件定义文件安装路径(无后缀,如 usr/bin/* usr/bin)。
preinst可执行脚本安装前脚本(无后缀,需 #!/bin/shchmod +x)。
postinst可执行脚本安装后脚本(无后缀)。
prerm可执行脚本卸载前脚本(无后缀)。
postrm可执行脚本卸载后脚本(无后缀)。
conffiles纯文本文件列出需要保留的配置文件(无后缀,每行一个路径如 /etc/myapp.conf)。

准备需要打包的程序:

这一部分先不要在 /home/orangepi/DEB_GPIOLED 进行写程序,推荐另起一个文件夹,后续将必要的内容复制过去即可

GPIO_LED.c  与 GPIO_LED.h :

GPIO_LED.c  与 GPIO_LED.h

这是基础的LED初始化与点亮程序 , 被注释部分用于测试其子函数是否奏效

该程序需要被构建为一个libGPIO_LED.so动态链接库

#include "GPIO_LED.h"void GPIO_LED_init(void)
{// 初始化 wiringPi(必须调用,否则会报错)wiringPiSetup();  // 使用 wiringPi 的引脚编号pinMode(LED_BLUE,OUTPUT);pinMode(LED_RED,OUTPUT);pinMode(LED_GREEN,OUTPUT); //初始化全灭digitalWrite(LED_BLUE ,LOW);digitalWrite(LED_RED ,LOW);digitalWrite(LED_GREEN ,LOW); }//控制LED 红色亮灭
void LED_RED_(char flag)
{if(flag == 1){digitalWrite(LED_RED ,HIGH);}else if(flag == 0){digitalWrite(LED_RED ,LOW); }
}//控制LED 蓝色亮灭
void LED_BLUE_(char flag)
{if(flag == 1){digitalWrite(LED_BLUE ,HIGH);}else if(flag == 0){digitalWrite(LED_BLUE ,LOW); }
}//控制LED 绿色亮灭
void LED_GREEN_(char flag)
{if(flag == 1){digitalWrite(LED_GREEN ,HIGH);}else if(flag == 0){digitalWrite(LED_GREEN ,LOW); }
}/*
int main(void)
{GPIO_LED_init();while(1){LED_GREEN_(0);LED_RED_(1);delay(500);LED_GREEN_(1); LED_RED_(0);  delay(500);    }
}
*/
#include <stdio.h>
#include <wiringPi.h>#define LED_BLUE 13
#define LED_RED 15
#define LED_GREEN 18void GPIO_LED_init(void);
void LED_RED_(char flag);
void LED_BLUE_(char flag);
void LED_GREEN_(char flag);

编译动态链接库:

编译动态链接库:

gcc GPIO_LED.c -fPIC -shared -o libGPIO_LED.so

将该动态链接库复制到目录 /usr/local/lib: 下:

sudo cp libGPIO_LED.so /usr/local/lib

更新动态链接器缓存:

sudo ldconfig

检查动态链接库:

ldd libGPIO_LED.so

但我们发现ldd命令检查出的libGPIO_LED.so是静态的,这是

ldd 的误判,ldd 通常用于检查动态库的依赖关系,但如果库 没有依赖任何其他动态库(比如没有调用 libc 的函数,或者 GCC 静态链接了部分库)

如果 GPIO_LED.c 没有使用任何 libc 函数(如 printfmalloc 等),并且没有链接其他库(如 -lpthread),那么 ldd 会认为它“静态链接”,因为没有外部依赖。

此时使用file命令更准确彻底:

根据 file 命令的输出, libGPIO_LED.so 确实是一个 动态链接库(shared object),并且显示为 dynamically linked,这与之前 ldd 显示的 statically linked 不同。

程序文件调用动态链接库LED_light.c:

现在我有个程序文件交LED_light.c,他会调用动态链接库 libGPIO_LED.so,以及WiringPi库

他会让LED红蓝交替闪烁:

#include <stdio.h>
#include "GPIO_LED.h"
#include <wiringPi.h>int main(void)
{GPIO_LED_init();while(1){LED_BLUE_(0);LED_RED_(1);delay(500);LED_BLUE_(1); LED_RED_(0);  delay(500);    }
}

编译C文件为可执行文件:

编译将LED_Light.c与动态库libGPIO_LED.so 以及libwiringPi 链接生成执行文件ledlight

gcc LED_Light.c -lGPIO_LED -lwiringPi -o ledlight

验证程序运行:

sudo ./ledlight

LED交替亮灭

 

安装必要的工具:

sudo apt-get update
sudo apt-get install dh-make dpkg-dev build-essential

创建 ledlight 的 DEB 包:

 每个文件的代码里的注释要删去!

创建项目目录结构:

一、先创建一个 DEB_GPIOLED 构建Deb包的目录:

cd /home/orangepi
mkdir DEB_GPIOLED

cd /home/orangepi/DEB_GPIOLED

二、创建打包目录:

mkdir DEBIAN

mkdir src

mkdir build

创建control文件:

进入目录:

cd /home/orangepi/DEB_GPIOLED/debian/

使用文本编辑器创建 control 文件

nano control

确保wiringpi可通过 apt 安装

apt-cache show wiringpi

Package: ledlight
Version: 1.0-1
Architecture: arm64   # arm64/amd64/armhf
Maintainer: Your Name <your.email@example.com>
Description: Control LED lights via GPIOA simple program to control LED lights using GPIO pins,dynamically linked to libGPIO_LED.so and WiringPi library.
Depends: libc6 (>= 2.28), wiringpi (>= 2.50) # 不写 libgpio-led ,libgpio-led (>= 1.0)
Section: utils
Priority: optional

在 Debian/Ubuntu 的 control 文件中,Depends 字段是核心的依赖声明部分,它会告诉包管理系统(如 apt/dpkg)在安装当前软件包时自动安装所依赖的包

将程序文件LED_light.c 和 ledlight复制到 /home/orangepi/DEB_GPIOLED/src/:

依赖库的处理_postinst文件:

/usr/local/lib/libGPIO_LED.so 是我自定义的库,手动安装的,不在 APT 仓库中,因此不能通过Depends自动安装,

因此这里将其放在项目的lib文件夹中,以便检查到目标机器没有这个库就复制一个到 /usr/local/lib。

因为库没有打包为debian,所以在 postinst 脚本中执行 ldconfig 更新库缓存:

nano postinst

#!/bin/sh
set -e# 符合FHS的路径定义
TEMP_LIB="/var/lib/ledlight/libGPIO_LED.so"
TARGET_LIB="/usr/local/lib/libGPIO_LED.so"case "$1" inconfigure)if [ ! -f "$TARGET_LIB" ]; thenecho "Installing libGPIO_LED.so to /usr/local/lib/"mkdir -p /usr/local/libcp "$TEMP_LIB" "$TARGET_LIB"chmod 644 "$TARGET_LIB"ldconfigfi# 总是清理临时文件rm -f "$TEMP_LIB"rmdir --ignore-fail-on-non-empty /var/lib/ledlight;;abort-upgrade|abort-remove|abort-deconfigure)# 安装失败时也清理rm -f "$TEMP_LIB"rmdir --ignore-fail-on-non-empty /var/lib/ledlight;;
esacldconfig  # 确保系统能找到 /usr/local/lib 下的库exit 0

最后别忘了把libGPIO_LED.so复制到/home/orangepi/DEB_GPIOLED/lib

cd /home/orangepi/DEB_GPIOLED/

mdir lib

cd /home/orangepi/gcc_cpp_codes/   #有libGPIO_LED.so的目录

cp libGPIO_LED.so /home/orangepi/DEB_GPIOLED/lib/

1

 

创建install文件: 

nano install

将项目目录下的 lib/libGPIO_LED.so 文件

安装到目标系统的 /var/lib/ledlight/ 目录(DEB 包内路径)

lib/libGPIO_LED.so var/lib/ledlight/

卸载前脚本_prerm 文件:

nano prerm

#!/bin/sh
set -eTARGET_LIB="/usr/local/lib/libGPIO_LED.so"case "$1" inremove|upgrade|failed-upgrade)# 仅在完全卸载(purge)时删除库文件if [ "$1" = "remove" ] || [ "$1" = "failed-upgrade" ]; thenif [ -f "$TARGET_LIB" ]; thenecho "Removing libGPIO_LED.so from /usr/local/lib/"rm -f "$TARGET_LIB"fifi;;purge)# 彻底清除时强制删除if [ -f "$TARGET_LIB" ]; thenecho "Purging libGPIO_LED.so from /usr/local/lib/"rm -f "$TARGET_LIB"fi;;
esacldconfig  # 更新库缓存
exit 0

构建规则rules 文件:

nano rules

#!/usr/bin/make -f%:dh $@ --with autotools-devoverride_dh_auto_configure:@:override_dh_auto_build:$(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS) -lWiringPi -L/usr/local/lib -lGPIO_LED" ledlightoverride_dh_auto_install:# 安装可执行文件到 /usr/bininstall -D -m 0755 ledlight $(CURDIR)/debian/ledlight/usr/bin/ledlight# 将库文件安装到临时位置(由postinst处理)install -D -m 0644 libGPIO_LED.so $(CURDIR)/debian/ledlight/var/lib/ledlight/libGPIO_LED.sooverride_dh_shlibdeps:dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info

创建changelog版本号文件:

基本格式:

package (version) distribution; urgency=urgency* change detail 1* change detail 2* change detail 3-- Maintainer Name <email@address>  Date

对应编写:

nano changelog

ledlight (1.0-1) unstable; urgency=medium* Initial release.* Includes ledlight executable and libGPIO_LED.so library.* Post-install script handles library installation to /usr/local/lib.-- Your Name <your.email@example.com>  Mon, 24 Jun 2024 14:30:00 +0800

生成日期以更新:

可以通过终端得到当前日期以更新changelog中的日期文件

date -R

如果时区不对,如此设置时区为上海:

sudo timedatectl set-timezone Asia/Shanghai

 

设定文件权限:

chmod 755 debian/postinst debian/prerm
chmod 644 lib/libGPIO_LED.so

生成deb包:

dpkg-deb --build . ../ledlight_1.0-1_arm64.deb

解包deb:

这里我先rm删除掉以前存在的libGPIO_LED.so

 尝试解包:

# 创建解压目录并解包
mkdir -p ledlight_extracted
dpkg -x ledlight_1.0-1_arm64.deb ledlight_extracted/# 单独提取控制文件(元数据和脚本)
dpkg -e ledlight_1.0-1_arm64.deb ledlight_extracted/DEBIAN

发现并没有像预期的那样将我的so文件复制到usr/local/lib :

参考文章:

如何把代码打包成一个 deb package_哔哩哔哩_bilibili文字稿在 haoduoshipin.com, 视频播放量 3715、弹幕量 0、点赞数 42、投硬币枚数 20、收藏人数 88、转发人数 10, 视频作者 好奇猫学院, 作者简介 编程,区块链,密码学等等。,相关视频:数字签名原理,如何把 deb 软件包上传到 apt 仓库中,动画演示 Diffie-Hellman 密钥交换算法,挑战魔改1300天前的塔防代码 | 手把手教你做冰冻炮台??,【网安】编写一个木马有多简单?,什么是密码学?,RSA 算法基本原理,如何使用 font-awesome “字体图标”,什么是 Ajax ?,最大的开放标准--古代中国https://www.bilibili.com/video/BV1kE411G7vt/?spm_id_from=333.337.search-card.all.click&vd_source=090e0b0724f6022d9ce8b14853097061

deb包构建详解_deb包制作详解-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/86271.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/86271.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第二十届“开源中国开源世界”大会:openKylin AI创新实践与成果分享

2025年6月13日&#xff0c;第二十届“开源中国开源世界“大会在北京万寿宾馆隆重召开。本届大会由开源软件推进联盟&#xff08;COPU&#xff09;主办&#xff0c;以“共建人工智能时代的开源生态”为主题&#xff0c;汇聚来自全球开源与AI领域的专家学者、技术领袖与前沿企业&…

微算法科技开发基于布尔函数平方和表示形式的最优精确量子查询算法

随着量子计算的迅猛发展&#xff0c;精确量子查询算法的研究成为量子信息科学的一个重要课题。量子决策树算法&#xff0c;作为量子计算的核心&#xff0c;微算法科技&#xff08;NASDAQ:MLGO&#xff09;提出了一种新的方式来解决布尔函数查询问题。该框架从布尔函数的平方和表…

鸿蒙(HarmonyOS)布局系统详解:Flex、Grid、Stack等布局方式全面解析

在移动应用和分布式系统开发中&#xff0c;界面布局是构建优秀用户体验的基础。鸿蒙操作系统(HarmonyOS)作为华为推出的全场景分布式操作系统&#xff0c;提供了一套强大而灵活的布局系统。本文将全面解析鸿蒙的布局方式&#xff0c;包括Flex、Grid、Stack等核心布局技术&#…

【软件系统架构】系列四:嵌入式软件开发流程全解析(包含示例)

目录 一、需求分析阶段 二、系统架构设计阶段: 三、开发准备阶段 四、底层驱动开发阶段(HAL / BSP) 五、操作系统集成阶段(RTOS / OS) 六、中间件与协议栈集成阶段 七、应用逻辑开发阶段 八、调试与测试阶段: 九、集成与联调阶段 十、发布与维护阶段 总结:完…

接口自动化测试面试(高频面试常问)+答案

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、结合项目讲解项…

Kubernetes 从入门到精通-StatefulSet控制器

一、StatefulSet 基础概念 1. 与 Deployment 的关键区别 特性StatefulSetDeployment网络标识稳定的 DNS 名称随机生成存储每个 Pod 独立 PVC&#xff0c;数据持久化 共享存储或无状态启停顺序严格按序号顺序&#xff08;0→N-1 启动&#xff0c;N-1→0 停止&#xff09;并行适…

Redis ①②-事务

Redis 事务 先来看看 MySQL 事务的四大特性&#xff1a; 原子性&#xff1a;将事务里的多个操作打包成一个整体&#xff0c;要么全部成功&#xff0c;要么全部失败&#xff0c;失败后会进行回滚操作。一致性&#xff1a;确保事务执行前后&#xff0c;其数据的整体变化一致。隔…

Leetcode+JAVA+回溯

39.组合总和 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复…

嘉讯科技:医院电子病历系统的关键性作用

电子病历系统在现代医疗领域发挥着至关重要的作用。 电子病历系统极大地提高了医疗效率。以往&#xff0c;医生需要翻阅大量的纸质病历&#xff0c;耗费时间和精力去查找关键信息。而电子病历系统通过数字化的存储和检索方式&#xff0c;使得医生能够在短时间内获取患者的完整病…

解决 Docker 里 DrissionPage 无法连接浏览器的问题,内含直接可用的Docker镜像(DrissionPage 浏览器链接失败 怎么办?)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 报错现象与诊断 📒📑 源码🐞 DrissionPage 报错内容🐞 手动启动 Chrome 测试📒 原因分析与解决方案 📒🔍 为什么会这样?🔧 解决办法🔧 推荐方案🎯 测试🐳 可直接使用的Docker镜像 🐳📦 镜像下载地址…

Mysql 数据库中设备实时状态表水平分表

一、 需求概述 在使用 Mysql 数据库存储设备上报日志时&#xff0c;存在一张设备实时状态表&#xff0c;随着时间推移&#xff0c;数据量变得十分庞大。为了更好地管理和查询数据&#xff0c;提高数据库性能&#xff0c;需要对该表进行水平分表操作。同时&#xff0c;存在分页…

nginx的下载与安装 mac

1. 下载 方法一&#xff1a;本地下载 链接&#xff1a;https://nginx.org/en/download.html&#xff08;可直接搜官网&#xff09; 下载到本地后&#xff0c;上传到linux的某个文件夹中 方法二&#xff1a;直接linux上下载&#xff08;推荐&#xff09; wget -c http://ngi…

在 Mac 上配置 Charles,抓取 iOS 手机端接口请求

工具官网&#xff1a;https://www.charlesproxy.com/ Charles 激活码 一、简介 Charles 是一款强大的网络抓包工具&#xff0c;支持 HTTP 和 HTTPS 协议&#xff0c;适用于调试手机 App、微信小程序、H5 页面等网络请求。 它能作为代理服务器&#xff0c;转发并记录本机及其他…

较大项目 git(gitee, github) 拉取失败解决方法

问题描述 近期遇到了一个拉取一个比较大项目失败的问题&#xff0c;229M这么大 每次都失败 我在自己的PC上&#xff0c;只有极好的环境才能拉取&#xff0c;笔记本办公热点怎么都不行 解决办法 后面通过https链接 首次会报错&#xff0c;因为我输入错了gitee的username&am…

爬虫中网络知识基础

HTTP&#xff08;HyperText Transfer Protocol&#xff09;和 HTTPS&#xff08;HyperText Transfer Protocol Secure&#xff09;是互联网上用于传输网页内容等数据的两种主要协议&#xff0c;以下是它们的定义和基本工作原理&#xff1a; HTTP 定义 &#xff1a;HTTP 是一种…

安全工具-二进制安全-testssl.sh

1 需求 --openssl <PATH> &#xff1a;use this openssl binary (default: look in $PATH, $RUN_DIR of testssl.sh) --quiet&#xff1a;dont output the banner. By doing this you acknowledge usage terms normally appearing in the banner --severity <severity…

WHAT - 组件库与 Storybook

文章目录 什么是 Storybook&#xff1f;使用场景举例快速上手教程&#xff08;React 为例&#xff09;1. 安装 Storybook2. 创建一个 Story&#xff08;组件故事&#xff09;3. 启动 Storybook 常用功能常见生态扩展示例&#xff1a;用 Args 和 Controls 动态控制 Props推荐资料…

魔音音乐 5.0.2 | 无损下载 同步网易云歌单UI美观

魔音音乐是一款功能丰富的音乐播放软件&#xff0c;提供高保真音质、智能推荐系统和用户友好界面。其丰富的音乐库几乎覆盖了所有类型的音乐&#xff0c;无论是流行歌曲还是小众音乐&#xff0c;都能在这里找到。这款应用非常适合音乐爱好者使用&#xff0c;它不仅让你享受高品…

云原生时代的中国答案:OLARDB、OceanBase与PostgreSQL的共生革命

以下是对阿里自研数据库的全景式技术调查,重点梳理其产品体系、与PostgreSQL的技术关联及发展历程: 一、阿里自研数据库全景图谱 ​​1. 核心自研产品​​ ​​数据库名称​​​​类型​​​​技术定位​​​​与PostgreSQL关系​​​​PolarDB​​云原生分布式数据库存储计…

HTTP 请求方法与状态码

前言&#xff1a;构建可靠前端应用的 HTTP 通信基础 在当今复杂的 Web 应用生态中&#xff0c;前端开发已远超简单的页面构建&#xff0c;转而成为与后端系统紧密交互的复杂体系。作为这一交互的核心机制&#xff0c;HTTP 协议承载着几乎所有的前后端数据交换&#xff0c;其设…