C 可疑的静态链接可执行文件大小

C 可疑的静态链接可执行文件大小,c,makefile,linker,blackberry-10,qnx,C,Makefile,Linker,Blackberry 10,Qnx,我有一个BB 10/QNX应用程序,其中我需要使用比BB 10默认版本更新的SQLite版本。我想我可以通过将我自己的SQLite代码链接到我的应用程序来做到这一点。我意识到在我的qmake生成的Makefile中,选项-lsqlite3被传递给qcc。在库位置(/opt/bbndk/target_10_2_0_1155/qnx6/armle-v7/usr/lib)中,我找到了以下文件: size filename 559386 libsqlite3.a 560662 libsqlite3S.a

我有一个BB 10/QNX应用程序,其中我需要使用比BB 10默认版本更新的SQLite版本。我想我可以通过将我自己的SQLite代码链接到我的应用程序来做到这一点。我意识到在我的qmake生成的Makefile中,选项-lsqlite3被传递给qcc。在库位置(/opt/bbndk/target_10_2_0_1155/qnx6/armle-v7/usr/lib)中,我找到了以下文件:

size filename
559386 libsqlite3.a
560662 libsqlite3S.a
15 libsqlite3.so -> libsqlite3.so.1
496503 libsqlite3.so.1

我认为我可以用我自己的文件替换libsqlite3.a,该文件是从最新的sqlite3.c(合并)编译而来的。让我困惑的是,我的应用程序可执行文件的大小只有180 kB,所以libsqlite3.a中的代码似乎不在其中。如果SQLite是动态链接的,我希望应用程序归档(.bar)包含libsqlite3.so,但这也不是真的,因为归档只有130 kB大。应用程序如何可能使用SQLite(通过Qt数据库类),但SQLite代码从未进入应用程序存档?

静态版本

将可执行文件链接到静态库时,编译器知道您正在构建一个“成品”:任何东西都不会依赖于可执行文件。它允许编译器不包含未使用的代码。假设您只使用库中的一个函数,而它本身没有使用库中的任何其他函数。编译器将只选取与此特定函数对应的机器代码,并轻轻地忽略其余部分

动态版本


关于bar归档和动态库的大小,可以归结为什么是真正的bar归档。它只是一个zip存档(可能添加了一些元数据,不知道细节)。两种可能性:要么.so文件被大大压缩,要么编译器依赖于系统库而不将其捆绑在bar归档中。

编译器将在构建可执行文件时优化并从静态库中删除不需要/使用的内容。可执行文件不必总是包含来自静态库的所有代码。是的,这就是
.a
存档的全部思想。如果库做得很好,并且真正划分为非常小的编译单元,那么加载程序实际上只在最终的可执行文件中获取它所需要的内容。