図書館レコード作物:動的ライブラリをトリミング

1.ライブラリーとは何ですか?

私は、多かれ少なかれ、自分の理解のいくつかを持っているが、いくつかの点でライブラリがあり、最終的に誰に頼まれた場合にはどのようなときには、おそらく多くはアプリケーション開発の経験の一定量、ライブラリーをコンセプトに、私に同じ白を言ったことを信じていますまた、私のような、一時半にはわからないだろう。ライブラリの説明をここにウィキペディアからの抜粋は、私は図書館学におけるコンピュータの概念を非常に明確な博覧会を感じる:「コンピュータサイエンスでは、ライブラリー(英語:ライブラリ)を開発するために使用されるソフトウェアルーチンの収集とライブラリを。違いの実行可能ファイルのライブラリは、コンピュータプログラムの独立していない、彼らは他のプログラムにサービスを提供するコード。」[ 1 ]

順番に基づいて実用的なアプリケーション、ライブラリのリンク異なった方法では、ライブラリは、さらにに分割されます静的ライブラリ(静的リンクライブラリ)とDLL(ダイナミックリンクライブラリ)。ここでは、ライブラリのリンクは、プログラムに含まれてライブラリを指します。リンク・ライブラリーは、分割され、静的リンク動的リンク静的リンクは、リンカーライブラリのリンクが実行可能なプログラムの内容を、対応する静的ライブラリに追加されました。動的リンク手段実行可能ファイルがロードされたまたはプログラムを実行すると、ライブラリは、オペレーティングシステムローダ、対応する動的ライブラリによってロードされます[ 1 ]

静的ライブラリを使用すると、バイナリライブラリファイルを公開する際に問題とユーザーのコンピュータ上のバージョン、および回避のがあるかどうかを考慮する必要がないという利点があるDLL地獄の問題を、しかし同時に、結果の実行可能ファイルが大きいほど、メモリにロードされたシステムリソースは、より多くの時間を消費します[ 2 ]

ダイナミックリンクが同時にサブルーチンコールを複数のプログラムを確実にするために、モジュラー共有ライブラリを提供し、静的ライブラリとは異なり、このようにアプリケーションのディスクとメモリ空間で必要な節約、同じコードの複数のコピーをコピーする必要はありません。しかし同時に、動的ライブラリが存在することになるDLL地獄のバージョンの競合が発生し、いくつかの用途では、得られたが実行できない、共有動的ライブラリを使用して、同時に複数のアプリケーションを参照し、問題、いわゆるDLL地獄[ 3 ]

2.ライブラリ作物は何ですか?

名前が示すように、コンパイルされたライブラリのサイズを減少させる目的を達成するために、プロジェクトファイルとリンクしたファイル内の冗長コードを切断して切断されたライブラリを示唆しています。文献[ 4 ]体系を含む、ライブラリを切断するいくつかの方法を要約したもの:(1)削除冗長ファイル、次のとおり支援プログラム、設定ファイル、データテンプレートと、不要なコメントの内容、(2)共有ライブラリ作物冗長コードよりも常に小さい共有ライブラリを削除するには、代替のパッケージの(3)の使用は、同じ機能を持っていますが、少ないスペースを取る;(4)のソースコードを変更し、以下のとおりです。再構成し、パッケージをコンパイルし、不要を取り除きます切断効率を改善するために、ソフトウェアの機能モジュールを増大;再構成コアは不要モジュールやドライバを削除します。

テキストなどの多くの図書館は、そのような私たちがソフトウェアを開発する場合、アプリケーション・シナリオを、切削標準ライブラリやライブラリシステムを引用し、すべてではなく、我々が使用している機能の、あなたはコンパイラオプションを変更することができます([ 5 ]でQtライブラリ言及切断)またはソースコードを変更する(例えば、テキスト[ 6は】ライブラリを切断する)libiconvをライブラリを切断述べ。

ライブラリを切断することに加えてコンパイルされたライブラリの外のサイズを小さくするだけでなく、効果的に、増加の開発効率をコンパイル時間を短縮し、かつ、ライブラリを切断した後、運用効率を向上させる量を削減し、ソフトウェアのコストソフトウェアリリースを減らすことができます。

3.エンジニアリングの実践記録

グループは、主に既存のコードに基づいて、プロジェクトを開発され、現在のプロジェクトには、ユーザーのニーズに応じて、再構成がユーザーに利用可能な新しい独立したライブラリファイルを生成します。この開発モデルは、それがコストを節約し、開発効率を向上させることができ、エンジニアリングでは一般的です。実際には、このような開発プロセスは、厳密に古いコードを、古いコードに基づいて新しい機能を開発する必要性をユーザーのニーズと開発コストのバランスをとるだけでなく、削除するために機能する必要はありません。図書館の必要性について、いくつかの段階で、この開発手法は、ユーザーのプラットフォームに応じて、カット、しかし、本質的に削除されたかに依存しないコード、コンパイルとリンクによって隔離異なりますライブラリを切断する方法は、不要なファイルを取り消し、ライブラリ作物を達成するためです。これは、MacとiOSの4つのプラットフォーム、主に顧客の需要に基づいて、私の主なタスク今週は、図書館の窓の切り出しで、アンドロイド。

(1)Windowsプラットフォーム

Windowsプラットフォームライブラリ作物を達成するのは簡単です。それ以外の場合は安定したリリースバージョンが使用されている支店で使用されるコードなので、リリースバージョンの安定性に影響を与えないために、直接、余分なコードを削除しません。あなたは、プロパティが含まに焦点を当てる必要があります、私たちに必要なライブラリ、およびプロジェクトファイルの設定プロパティを生成するために、別のプロジェクトをコンパイルするために、あなたのソリューションを追加することができます:追加のインクルードディレクトリ、プリプロセッサ定義、追加の依存関係、これらの属性3に、図1に示したCI位置。

ファイルをインクルード

                                                                                                     図1

プリコンパイルヘッダ

                                                                                                     図2

追加の依存

                                                                                                     図3

其中,附加包含目录应删除工程不需要依赖的头文件所在的目录,预处理器定义中添加宏定义,该宏定义作用域为当前工程,可以实现在该工程中隔离不需要代码的目的。具体实现可按照下面的方式进行:

// 隔离的宏定义为IS_NEED_ISOLATION

#ifndef IS_NEED_ISOLATION
    {
        code block;    // 稳定发布版本需要但新开发项目不需要的代码块
    }
#endif

附加依赖项中删除项目工程文件不再依赖的静态库文件。除了修改工程属性并在代码中添加隔离宏外,由于部分不需要的代码是直接以文件的形式提供的,还需要在工程目录中删除这些不需要的文件,具体操作如图4所示。

                                                                                                     图 4

在完成了以上工作后,还有最后一步:即修改编译脚本文件。windows平台下的编译脚本一般以cmake文件提供,可以直接拷贝原来的release版本编译脚本并修改文件名为old_name_win_isolation.cmake(此处old_name_win代指原来的文件名),并且,编辑脚本文件中的内容,删除不再需要编译的部分。这样可以有效减少编译发布版本的时间。

(2)android平台

android平台库裁剪也包括无关代码的隔离和无关代码文件的删除。隔离代码通过.bat文件和Application.mk组合实现,比如:首先,在.bat文件中定义了一个变量IS_ISOLATION,并将其值置为true,这个变量作用于.bat文件调用到的所有.mk文件。然后,在Application.mk文件中,根据变量IS_ISOLATION的值,判断是否需要在APP_CFLAGS项添加宏定义IS_NEED_ISOLATION,这个宏定义作用于工程目录下的所有.c文件。(如果项目源文件是用C++编写的,则使用APP_CPPFLAGS)。无关代码文件的删除主要通过在Android.mk文件中隔离不需要的源文件名称来实现。

android平台库裁剪花费了很多时间,耗时的点主要在于:1)安卓编译脚本运行依赖环境搭建更为复杂;2)安卓编译脚本包括old_name_and.bat、Application.mk和Android.mk三类文件,这三者之间的关系没有第一时间厘清;3)安卓裁剪后的库需要借助android studio来验证,而android studio的环境搭建最为复杂。

首先,安卓编译脚本运行依赖环境包括三方面:cygwin、ndk和android sdk,三者缺一不可。cygwin是在windows下模拟unix环境的工具集,其中包括的动态库文件cywin1.dll是编译安卓库文件不可或缺的,这个文件的主要作用是模拟linux下的API,在编译的过程中,如果C/C++ 调用了linux中的API,cygwin就会利用cygwin1.dll 来编译 C/C++源代码,从而可以在windows下生成linux下的lib...so文件[7] 。ndk是一个官方的安卓工具集,能够让开发者以本地平台支持的编程语言(比如C/C++)开发部分安卓应用程序功能代码[8],可以理解为是安卓官方提供的一种跨平台开发的支持。ndk编译命令在检测到所编写代码为本地编程语言开发时,会自动构建并生成二进制文件。android sdk是安卓应用程序开发时必须依赖的官方工具集,使用它可以将由Kotlin、Java或C++编写的应用程序编译成.apk文件[9]

其次,编译安卓库时需要运行.bat文件,其中通过调用ndk_build.cmd文件实现编译。需要说明的是,每次调用ndk_build.cmd后,Application.mk和Android.mk文件会依次运行。起初我对这种运行机制并不清楚,在发现编译脚本.bat文件中定义的变量没有作用到所有.mk文件后,在所有脚本中都加了日志打印,才推理出这种运行机制。由于这种运行机制,在每次调用ndk_build.cmd文件时,必须先对变量IS_ISOLATION进行赋值,然后再执行ndk命令,比如:

call path_of_ndk_cmd\ndk_build.cmd IS_ISOLATION=true clean

Application.mk文件中声明了一些工程范围内的配置,这些配置内容一般包括:应用程序二进制文件接口(Application Binary Interface, ABI,提供了一种系统级的编程约定)、工具链(编译C/C++程序的编译工具)、编译模式(debug或release)和STL。这些配置内容可以通过已定义的宏变量实现,比如:可以通过配置APP_CFLAGS的值,创建应用于当前工程所有.c文件的宏IS_NEED_ISOLATION:[10]

APP_CFLAGS += -DIS_NEED_ISOLATION

Android.mk文件主要包含了本地库文件、定义了作用于当前文件夹下所有文件的宏变量和通过"JNI"目录编译的所有头文件[11]

最后,验证平台android studio在安装完成之后,需要配置代理设置,否则由于公司内网不能连接到相关网站,导致部分jar包无法下载,就会出现安卓工程编译不过的问题。这块主要通过软件cntlm绕过公司的代理,连接到了相关网站,具体细节就不赘述了。

(3) ios和mac平台

这里把ios和mac平台放在一起,主要是因为二者的库都是由.xcode工程编译出来的,二者的库裁剪步骤也是完全相同的。以ios平台为例,库裁剪主要包括无关代码的隔离和无关代码文件的删除,以及编译脚本中代码的修改,这块和windows平台相似,即在项目文件目录下,把原来生成动态库的.xcodeprj文件拷贝一份并重命名后,再通过xcode打开该工程文件,在build_settting选项的preprocessor_macro栏添加宏定义IS_NEED_ISOLATION,这样,工程中的所有无关代码都可以通过宏IS_NEED_ISOLATION实现隔离。并且,删除掉库依赖栏中不再依赖的库文件。最后,在xcode左侧的工程目录下,删除无关代码文件的依赖和不再依赖的库工程文件。在终端执行下面的命令,即可编译生成裁剪后的库文件:

cd path_of_ios_build_script
./old_name_ios_isolation.sh

4. 总结

库裁剪是软件开发过程中不可避免的一个过程,涉及的面比较广,既要求开发者对代码十分熟悉,又要求开发者掌握一定的运维知识,体现了开发者的综合能力。自以为这方面掌握的知识还有所欠缺,具体体现在应用于各平台的库文件生成原理,包括编译、链接和装载的具体原理,这方面的知识仍有待加强。希望通过后续静态库裁剪对这些内容有更深刻的理解。

refs: 

[1] https://zh.wikipedia.org/wiki/%E5%87%BD%E5%BC%8F%E5%BA%AB

[2] https://zh.wikipedia.org/wiki/%E9%9D%99%E6%80%81%E5%BA%93

[3] https://zh.wikipedia.org/wiki/%E5%8A%A8%E6%80%81%E9%93%BE%E6%8E%A5%E5%BA%93

[4]  http://www.jsjkx.com/CN/article/openArticlePDF.jsp?id=9653

[5]  http://blog.chinaunix.net/uid-25765968-id-359557.html

[6]  https://blog.csdn.net/mayue_web/article/details/100108034

[7]  https://www.cnblogs.com/xiaoxuetu/p/3467613.html

[8]  https://developer.android.com/ndk

[9]  https://developer.android.com/guide/components/fundamentals

[10]  https://developer.android.google.cn/ndk/guides/application_mk.html

[11]  https://developer.android.google.cn/ndk/guides/concepts

おすすめ

転載: www.cnblogs.com/niceland/p/0x0008.html