1.python setuptool包介绍
2.GNU Autotools 介绍
3.pnpm+workspace+changesets构建你的发包发包monorepo工程
4.[源码和文档分享]基于Libpcap实现的局域网嗅探抓包发包解析工具
5.Qt实用技巧:在CentOS上使用linuxdeployqt打包发布qt程序
python setuptool包介绍
Python的setuptools是一个关键工具,专为构建和分发Python包而设计。工具工具它整合了一系列强大功能,源码源码用于管理和定义包的发包发包元数据、依赖关系以及构建选项,工具工具还能生成易于安装的源码源码探探破解源码包。以下是发包发包setuptools的基本应用步骤:安装:使用pip简单快捷,只需在命令行输入`pip install setuptools`。工具工具
配置:创建核心的源码源码setup.py文件,替换`your_package_name`为你的发包发包包名,描述你的工具工具包功能,将依赖项列表如['dependency1',源码源码 'dependency2']替换为实际的依赖。`setup()`函数可添加作者和许可证等额外信息。发包发包
构建:
生成wheel文件(可分发的工具工具二进制包):在项目根目录下,执行`python setup.py bdist_wheel`,源码源码会在dist目录下生成一个`--py3-none-any.whl`文件。
创建源码分发包(tar.gz文件):若需要源码包,运行`python setup.py sdist`,dist目录下会生成一个`.tar.gz`文件。
通过setuptools,开发者可以高效地管理和构建自己的Python包,确保它们在不同环境中正确安装和运行。
GNU Autotools 介绍
GNU Autotools,这个看似神秘的构建工具,实际上正改变着我们提交代码的方式。即使是初次接触Linux的用户,若想深入了解软件构建过程,这篇文章将为你揭示其工作原理和优势。它不仅是开发人员的得力助手,还是软件包管理者的理想选择,支持诸如DEB和RPM等标准格式。
使用Autotools,即使你的项目简单,也能享受到其带来的便利。它的核心工作流程涉及对源代码的管理和打包,使得用户可以轻松编译和安装软件。对于初学者,可能需要从理解Autotools的快手视频php源码工作步骤开始,如下载源代码、运行预设的./configure、make && make install命令链。
Autotools的优势在于其可移植性和与GCC的集成,几乎所有的POSIX系统上的运行软件都是通过这种方式构建的。它的配置过程虽看似复杂,实则背后是自动化的生成。对于高级用户,Autotools提供了定制安装选项,允许他们根据个人系统调整安装细节。
打包方面,无论是RPM、DEB还是TGZ,Autotools都提供了无缝支持,使得将项目交付给发行版打包者变得简单。这不仅节省了时间,还确保了项目的统一性。
要使用Autotools,首先需要安装,这可能涉及查找和安装特定的开发工具包。项目的基本结构包括src目录以及一系列必要的配置文件,如configure.ac、Makefile.am等。配置阶段,创建configure.ac来定义项目元数据,如包名和版本,然后调用相关宏生成configure脚本和Makefile.am,后者定义了源代码的结构和编译需求。
生成的Makefile会利用在configure阶段检测到的配置选项,自动处理大部分编译和安装细节。尽管如此,你仍需在Makefile.am中提供一些特定于项目的配置,如目标文件的编译和安装位置。通过这种方式,Autotools提供了一个既高效又结构化的开发框架。
最后,了解如何创建dist目标,手游网址源码用于生成包含源代码和构建工具的分发包,这是Autotools发布的关键步骤。通过构建和测试,你可以确保分发的包可以顺利安装和运行,从而为用户提供可靠的软件体验。
总的来说,GNU Autotools以其强大的适应性和标准化流程,值得开发者投入时间去学习和掌握。无论你的项目规模如何,它都能提供所需的结构和灵活性,让软件构建更加高效和可维护。
pnpm+workspace+changesets构建你的monorepo工程
pnpm+workspace+changesets构建你的monorepo工程什么是monorepo?
什么是monorepo?以及和multirepo的区别是什么?
关于这些问题,在之前的一篇介绍lerna的文章中已经详细介绍过,感兴趣的同学可以再回顾下。
简而言之,monorepo就是把多个工程放到一个git仓库中进行管理,因此他们可以共享同一套构建流程、代码规范也可以做到统一,特别是如果存在模块间的相互引用的情况,查看代码、修改bug、调试等会更加方便。
什么是pnpm?pnpm是新一代的包管理工具,号称是最先进的包管理器。按照官网说法,可以实现节约磁盘空间并提升安装速度和创建非扁平化的node_modules文件夹两大目标,具体原理可以参考pnpm官网。
pnpm提出了workspace的概念,内置了对monorepo的支持,那么为什么要用pnpm取代之前的lerna呢?
这里我总结了以下几点原因:
lerna已经不再维护,后续有任何问题社区无法及时响应
pnpm装包效率更高,并且可以节约更多磁盘空间
pnpm本身就预置了对monorepo的支持,不需要再额外第三方包的支持
onemorething,就是好奇心了?
如何使用pnpm来搭建menorepo工程安装pnpm$?npm?install?-g?pnpm v7版本的pnpm安装使用需要node版本至少大于v..0,所以在安装之前首先需要检查下node版本。工程初始化为了便于后续的演示,先在工程根目录下新建packages目录,商用商城的源码并且在packages目录下创建pkg1和pkg2两个工程,分别进到pkg1和pkg2两个目录下,执行npminit命令,初始化两个工程,package.json中的name字段分别叫做@qftjs/menorepo1和@qftjs/monorepo2(PS:@qftjs是提前在npm上创建好的组织,没有的话需要提前创建)。
为了防止根目录被发布出去,需要设置工程工程个目录下package.json配置文件的private字段为true。
为了实现一个完整的例子,这里我使用了father-build对模块进行打包,father-build是基于rollup进行的一层封装,使用起来更加便捷。
在pkg1和pkg2的src目录下个创建一个index.ts文件:
//?pkg1/src/index.tsimport?pkg2?from?'@qftjs/monorepo2';function?fun2()?{ ?pkg2();?console.log('I?am?package?1');}export?default?fun2;//?pkg2/src/index.tsfunction?fun2()?{ ?console.log('I?am?package?2');}export?default?fun2;分别在pkg1和pkg2下新增.fatherrc.ts和tsconfig.ts配置文件。
//?.fatherrc.tsexport?default?{ ?target:?'node',?cjs:?{ ?type:?'babel',?lazy:?true?},?disableTypeCheck:?false,};//?tsconfig.ts{ ?"include":?["src",?"types",?"test"],?"compilerOptions":?{ "target":?"es5","module":?"esnext","lib":?["dom",?"esnext"],"importHelpers":?true,"declaration":?true,"sourceMap":?true,"rootDir":?"./","strict":?true,"noImplicitAny":?true,"strictNullChecks":?true,"strictFunctionTypes":?true,"strictPropertyInitialization":?true,"noImplicitThis":?true,"alwaysStrict":?true,"noUnusedLocals":?true,"noUnusedParameters":?true,"noImplicitReturns":?true,"noFallthroughCasesInSwitch":?true,"moduleResolution":?"node","baseUrl":?"./","paths":?{ ?"*":?["src/*",?"node_modules/*"]},"jsx":?"react","esModuleInterop":?true?}}全局安装father-build:
$?pnpm?i?-Dw?father-build最后在pkg1和pkg2下的package.json文件中增加一条script:
{ ?"scripts":?{ "build":?"father-build"?}}这样在pkg1或者pkg2下执行build命令就会将各子包的ts代码打包成js代码输出至lib目录下。
要想启动pnpm的workspace功能,需要工程根目录下存在pnpm-workspace.yaml配置文件,并且在pnpm-workspace.yaml中指定工作空间的目录。比如这里我们所有的子包都是放在packages目录下,因此修改pnpm-workspace.yaml内容如下:
packages:?-?'packages/*'初始化完毕后的工程目录结构如下:
.├──?README.md├──?package.json├──?packages│├──?pkg1││├──?package.json││├──?src│││└──?index.ts││└──?tsconfig.json│└──?pkg2│├──?package.json│├──?src││└──?index.ts│└──?tsconfig.json├──?pnpm-workspace.yaml└──?tsconfig.root.json安装依赖包使用pnpm安装依赖包一般分以下几种情况:
全局的公共依赖包,比如打包涉及到的rollup、typescript等
pnpm提供了-w,--workspace-root参数,可以将依赖包安装到工程的根目录下,作为所有?package的公共依赖。
比如:
$?pnpm?install?react?-w如果是一个开发依赖的话,可以加上-D参数,表示这是一个开发依赖,会装到pacakage.json中的devDependencies中,比如:
//?pkg1/src/index.tsimport?pkg2?from?'@qftjs/monorepo2';function?fun2()?{ ?pkg2();?console.log('I?am?package?1');}export?default?fun2;0给某个package单独安装指定依赖
pnpm提供了--filter参数,可以用来对特定的package进行某些操作。
因此,如果想给pkg1安装一个依赖包,比如axios,可以进行如下操作:
//?pkg1/src/index.tsimport?pkg2?from?'@qftjs/monorepo2';function?fun2()?{ ?pkg2();?console.log('I?am?package?1');}export?default?fun2;1需要注意的是,--filter参数跟着的是package下的package.json的name字段,并不是目录名。
关于--filter操作其实还是很丰富的,比如执行pkg1下的微课堂源码免费scripts脚本:
//?pkg1/src/index.tsimport?pkg2?from?'@qftjs/monorepo2';function?fun2()?{ ?pkg2();?console.log('I?am?package?1');}export?default?fun2;2filter后面除了可以指定具体的包名,还可以跟着匹配规则来指定对匹配上规则的包进行操作,比如:
//?pkg1/src/index.tsimport?pkg2?from?'@qftjs/monorepo2';function?fun2()?{ ?pkg2();?console.log('I?am?package?1');}export?default?fun2;3此命令会执行所有package下的build命令。具体的用法可以参考filter文档。
模块之间的相互依赖
最后一种就是我们在开发时经常遇到的场景,比如pkg1中将pkg2作为依赖进行安装。
基于pnpm提供的workspace:协议,可以方便的在packages内部进行互相引用。比如在pkg1中引用pkg2:
//?pkg1/src/index.tsimport?pkg2?from?'@qftjs/monorepo2';function?fun2()?{ ?pkg2();?console.log('I?am?package?1');}export?default?fun2;4此时我们查看pkg1的package.json,可以看到dependencies字段中多了对@qftjs/monorepo2的引用,以workspace:开头,后面跟着具体的版本号。
//?pkg1/src/index.tsimport?pkg2?from?'@qftjs/monorepo2';function?fun2()?{ ?pkg2();?console.log('I?am?package?1');}export?default?fun2;5在设置依赖版本的时候推荐用workspace:*,这样就可以保持依赖的版本是工作空间里最新版本,不需要每次手动更新依赖版本。
当pnpmpublish的时候,会自动将package.json中的workspace修正为对应的版本号。
只允许pnpm当在项目中使用pnpm时,如果不希望用户使用yarn或者npm安装依赖,可以将下面的这个preinstall脚本添加到工程根目录下的package.json中:
//?pkg1/src/index.tsimport?pkg2?from?'@qftjs/monorepo2';function?fun2()?{ ?pkg2();?console.log('I?am?package?1');}export?default?fun2;6preinstall脚本会在install之前执行,现在,只要有人运行npminstall或yarninstall,就会调用only-allow去限制只允许使用pnpm安装依赖。
Release工作流在workspace中对包版本管理是一个非常复杂的工作,遗憾的是pnpm没有提供内置的解决方案,一部分开源项目在自己的项目中自己实现了一套包版本的管理机制,比如Vue3、Vite等。
pnpm推荐了两个开源的版本控制工具:
changesets
rush
这里我采用了changesets来做依赖包的管理。选用changesets的主要原因还是文档更加清晰一些,个人感觉上手比较容易。
按照changesets文档介绍的,changesets主要是做了两件事:
Changesetsholdtwokeybitsofinformation:aversiontype(followingsemver),andchangeinformationtobeaddedtoachangelog.
简而言之就是管理包的version和生成changelog。
配置changesets安装
//?pkg1/src/index.tsimport?pkg2?from?'@qftjs/monorepo2';function?fun2()?{ ?pkg2();?console.log('I?am?package?1');}export?default?fun2;7初始化
//?pkg1/src/index.tsimport?pkg2?from?'@qftjs/monorepo2';function?fun2()?{ ?pkg2();?console.log('I?am?package?1');}export?default?fun2;8执行完初始化命令后,会在工程的根目录下生成.changeset目录,其中的config.json作为默认的changeset的配置文件。
修改配置文件如下:
//?pkg1/src/index.tsimport?pkg2?from?'@qftjs/monorepo2';function?fun2()?{ ?pkg2();?console.log('I?am?package?1');}export?default?fun2;9说明如下:
changelog:changelog生成方式
commit:不要让changeset在publish的时候帮我们做gitadd
linked:配置哪些包要共享版本
access:公私有安全设定,内网建议restricted,开源使用public
baseBranch:项目主分支
updateInternalDependencies:确保某包依赖的包发生upgrade,该包也要发生versionupgrade的衡量单位(量级)
ignore:不需要变动version的包
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH:在每次version变动时一定无理由patch抬升依赖他的那些包的版本,防止陷入major优先的未更新问题
如何使用changesets一个包一般分如下几个步骤:
为了便于统一管理所有包的发布过程,在工程根目录下的pacakge.json的scripts中增加如下几条脚本:
编译阶段,生成构建产物
//?pkg2/src/index.tsfunction?fun2()?{ ?console.log('I?am?package?2');}export?default?fun2;0清理构建产物和node_modules
//?pkg2/src/index.tsfunction?fun2()?{ ?console.log('I?am?package?2');}export?default?fun2;1执行changeset,开始交互式填写变更集,这个命令会将你的包全部列出来,然后选择你要更改发布的包
//?pkg2/src/index.tsfunction?fun2()?{ ?console.log('I?am?package?2');}export?default?fun2;2执行changesetversion,修改发布包的版本
//?pkg2/src/index.tsfunction?fun2()?{ ?console.log('I?am?package?2');}export?default?fun2;3这里需要注意的是,版本的选择一共有三种类型,分别是patch、minor和major,严格遵循semver规范。
这里还有个细节,如果我不想直接发release版本,而是想先发一个带tag的prerelease版本呢(比如beta或者rc版本)?
这里提供了两种方式:
手工调整
这种方法最简单粗暴,但是比较容易犯错。
首先需要修改包的版本号:
//?pkg2/src/index.tsfunction?fun2()?{ ?console.log('I?am?package?2');}export?default?fun2;4然后运行:
//?pkg2/src/index.tsfunction?fun2()?{ ?console.log('I?am?package?2');}export?default?fun2;5注意发包的时候不要忘记加上--tag参数。
通过changeset提供的Prereleases模式
利用官方提供的Prereleases模式,通过preenter<tag>命令进入先进入pre模式。
常见的tag如下所示:
名称功能alpha是内部测试版,一般不向外部发布,会有很多Bug,一般只有测试人员使用beta也是测试版,这个阶段的版本会一直加入新的功能。在Alpha版之后推出rcReleaseCandidate)系统平台上就是发行候选版本。RC版不会再加入新的功能了,主要着重于除错//?pkg2/src/index.tsfunction?fun2()?{ ?console.log('I?am?package?2');}export?default?fun2;6之后在此模式下的changesetpublish均将默认走beta环境,下面在此模式下任意的进行你的开发,举一个例子如下:
//?pkg2/src/index.tsfunction?fun2()?{ ?console.log('I?am?package?2');}export?default?fun2;7完成版本发布之后,退出Prereleases模式:
//?pkg2/src/index.tsfunction?fun2()?{ ?console.log('I?am?package?2');}export?default?fun2;8构建产物后发版本
//?pkg2/src/index.tsfunction?fun2()?{ ?console.log('I?am?package?2');}export?default?fun2;9规范代码提交代码提交规范对于团队或者公司来说是非常重要的,养成良好的代码提交规范可以方便回溯,有助于对本次提交进行review,如果单纯的只是要求团队成员遵循某些代码提交规范,是很难形成强制约束的,现在我们就尝试通过工具来约束代码提交规范。
使用commitizen规范commit提交格式commitizen的作用主要是为了生成标准化的commitmessage,符合Angular规范。
一个标准化的commitmessage应该包含三个部分:Header、Body和Footer,其中的Header是必须的,Body和Footer可以选填。
//?.fatherrc.tsexport?default?{ ?target:?'node',?cjs:?{ ?type:?'babel',?lazy:?true?},?disableTypeCheck:?false,};0Header部分由三个字段组成:type(必需)、scope(可选)、subject(必需)
Typetype必须是下面的其中之一:
feat:增加新功能
fix:修复bug
docs:只改动了文档相关的内容
style:不影响代码含义的改动,例如去掉空格、改变缩进、增删分号
refactor:代码重构时使用,既不是新增功能也不是代码的bud修复
perf:提高性能的修改
test:添加或修改测试代码
build:构建工具或者外部依赖包的修改,比如更新依赖包的版本
ci:持续集成的配置文件或者脚本的修改
chore:杂项,其他不需要修改源代码或不需要修改测试代码的修改
revert:撤销某次提交
scope
用于说明本次提交的影响范围。scope依据项目而定,例如在业务项目中可以依据菜单或者功能模块划分,如果是组件库开发,则可以依据组件划分。
subject
主题包含对更改的简洁描述:
注意三点:
使用祈使语气,现在时,比如使用"change"而不是"changed"或者”changes“
第一个字母不要大写
末尾不要以.结尾
Body
主要包含对主题的进一步描述,同样的,应该使用祈使语气,包含本次修改的动机并将其与之前的行为进行对比。
Footer
包含此次提交有关重大更改的信息,引用此次提交关闭的issue地址,如果代码的提交是不兼容变更或关闭缺陷,则Footer必需,否则可以省略。
使用方法:
commitizen和cz-conventional-changelog如果需要在项目中使用commitizen生成符合AngularJS规范的提交说明,还需要安装cz-conventional-changelog适配器。
//?.fatherrc.tsexport?default?{ ?target:?'node',?cjs:?{ ?type:?'babel',?lazy:?true?},?disableTypeCheck:?false,};1工程根目录下的package.json中增加一条脚本:
//?.fatherrc.tsexport?default?{ ?target:?'node',?cjs:?{ ?type:?'babel',?lazy:?true?},?disableTypeCheck:?false,};2接下来就可以使用$pnpmcommit来代替$gitcommit进行代码提交了,看到下面的效果就表示已经安装成功了。
commitlint&&husky前面我们提到,通过commitizen&&c
[源码和文档分享]基于Libpcap实现的局域网嗅探抓包发包解析工具
完成一个基于Libpcap的网络数据包解析软件,其设计目的是构建一个易于使用、界面美观的网络监控工具。该软件主要功能包括局域网数据包捕获、分析、图形化显示及统计分析等。具体功能如下:
1. 数据包捕获:利用Libpcap,软件能够扫描并选取不同类型的网卡(如WiFi/以太)进行局域网数据包监听与捕获。用户可选择混杂模式或非混杂模式,混杂模式下,软件接收并分析整个局域网的数据包。
2. 数据包分析:捕获的数据包被分类整理并提取内容进行分析。软件解析数据包版本、头长度、服务类型、总长度、标识、分段标志、分段偏移值、生存时间、上层协议类型、校验和、源IP地址及目的IP地址等信息,以规范形式展示。对于HTTP、ARP等特定协议,能深入解析内容。
3. 图形化显示:通过表格组件,直观展示数据包信息,用户可方便查看并交换数据以获取更深层内容。
4. 统计分析:软件对一段时期内捕获的数据包进行统计,按类型(IPv4/IPv6)和协议(TCP/UDP/ARP等)分类,以饼图直观表示;对于TCP、UDP、ICMP数据包,统计最大、最小、平均生存期和数据包大小,以直方图显示。
5. 数据包清空:提供功能清除所有已捕获的数据包。
6. Ping功能:实现与目标主机的连通性测试。
7. TraceRoute功能:了解从本机到互联网另一端主机的路径。
8. ARP-Attack功能:在局域网内实现ARP攻击,测试并断开指定IP地址主机的网络连接。通过欺骗目标主机的网关地址,使ARP缓存表错误,导致无法正常发送数据包。若将欺骗的MAC地址设置为自己的MAC地址,则截获目标机器发送的数据包。
详细参考文档和源码下载地址:write-bug.com/article/1...
Qt实用技巧:在CentOS上使用linuxdeployqt打包发布qt程序
在CentOS上使用linuxdeployqt打包发布Qt程序,这一过程与Ubuntu或麒麟系统有相似之处,但也存在系统兼容性问题。文章详细介绍了CentOS8.2和CentOS7.5的发布流程,并强调了使用linuxdeployqt的好处。该工具能将应用程序所需的资源(如库、图形和插件)复制到一个包中,使其成为自包含的程序,可以作为AppDir或AppImage分发,也可以放入交叉分发包中。为了确保在不同系统上的一致性,linuxdeployqt特别适用于Qt应用程序的部署。
使用linuxdeployqt需要访问其源代码下载地址。对于CentOS系统,文章提供了详细的编译步骤。首先,需要下载源码并解压。接着,修改源码,移除版本检查部分,以避免潜在的兼容性问题。确保系统中安装了CMake,这对于构建linuxdeployqt至关重要。在CentOS8.2中,CMake通常是预装的,而在CentOS7.5中,可能需要卸载系统自带的较旧版本,并使用源码安装较新版本,以确保正确编译。
为了支持Qt的依赖环境,步骤包括指定Qt库的路径,以及使用cmake-gui来配置依赖。这确保了linuxdeployqt能正确识别并打包Qt相关的库,避免运行时错误。配置完成后,通过生成generate文件和执行make命令完成编译。随后,将linuxdeployqt安装到系统目录,并进行测试以确认其正确性。
打包Qt程序时,确保应用可执行文件和一个空目录准备就绪。使用环境变量设置,特别是通过source env.sh引入QT_DIR到系统路径中,确保打包过程能正确识别和使用Qt库。打包命令使用linuxdeployqt 可执行程序 -appimage,这一步骤将程序及其依赖库打包成一个独立的可执行文件。测试表明,使用此方法打包的Qt程序能在不同CentOS版本上成功运行,无需额外的库加载。
为了验证这一过程在不同环境中的可靠性,文章介绍了在全新CentOS8.2系统上进行测试的过程。通过对比发现,使用linuxdeployqt -appimage打包的Qt程序能有效解决依赖库问题,确保程序在不同操作系统环境下均可正常运行。