SCons 第四章 编译链接库文件

第四章 编译链接库文件

​ 大型软件工程一般都是由很多库文件构成,采用SCons编译库文件是一件非常简单的事情。

4.1 编译库文件

​ 您只需要采用Library的构建方法代替Program即可:

Library('foo', ['f1.c', 'f2.c', 'f3.c'])

​ SCons会自动根据系统来创建合适的库文件前缀和后缀,因此在POSIX或者Linux系统上,上述示例将会构建以下内容(ranlib可能在某系系统中不会被调用):

> scons -Q
cc -o f1.o -c f1.c
cc -o f2.o -c f2.c
cc -o f3.o -c f3.c
ar rc libfoo.a f1.o f2.o f3.o
ranlib libfoo.a

​ 在Windows系统中,编译输出将会如下所示:

C:\>scons -Q
cl /Fof1.obj /c f1.c /nologo
cl /Fof2.obj /c f2.c /nologo
cl /Fof3.obj /c f3.c /nologo
lib /nologo /OUT:foo.lib f1.obj f2.obj f3.obj

​ 目标文件的构建规则和Program方法类似,如果你不特别指定目标库文件名称,SCons将会从源文件列表中选择第一个作为库文件名称,同时SCons还会自动给库文件加入前缀和后缀。

4.1.1 通过源文件或中间文件编译

​ 上述示例介绍了通过源文件列表构建库文件,SCons同样也支持通过中间文件构建,或者源文件和中间文件混在一起构建也可以。

Library('foo', ['f1.c', 'f2.o', 'f3.c', 'f4.o'])

​ 同时SCons也会意识到,只有源文件才需要进一步构建成中间文件:

> scons -Q
cc -o f1.o -c f1.c
cc -o f3.o -c f3.c
ar rc libfoo.a f1.o f2.o f3.o f4.o
ranlib libfoo.a

​ 当然,无论源文件还是中间文件,要想构建成功,它们都必须真实存在。下一章节将会进一步介绍关于Node Objects的相关内容。

4.1.2 构建静态库文件:StaticLibrary方法

Library构建方法构建的是传统静态库,如果您想特别声明构建的是静态库文件,则可以通过调用StaticLibrary来进一步显示声明:

StaticLibrary('foo', ['f1.c', 'f2.c', 'f3.c'])

​ 对于LibraryStaticLibrary,他们完全等价,没有任何区别。

4.1.3 构建动态库文件(DLL):SharedLibrary方法

​ 如果您想构建动态库文件(POSIX系统, WINDOWS系统是DLL文件),您可以采用SharedLibrary方法:

SharedLibrary('foo', ['f1.c', 'f2.c', 'f3.c'])

​ 在POSIX系统上的输出为:

> scons -Q
cc -o f1.os -c f1.c
cc -o f2.os -c f2.c
cc -o f3.os -c f3.c
cc -o libfoo.so -shared f1.os f2.os f3.os

​ 在Windows系统上输出为:

C:\>scons -Q
cl /Fof1.obj /c f1.c /nologo
cl /Fof2.obj /c f2.c /nologo
cl /Fof3.obj /c f3.c /nologo
link /nologo /dll /out:foo.dll /implib:foo.lib f1.obj f2.obj f3.obj
RegServerFunc(target, source, env)
embedManifestDllCheck(target, source, env)

​ SCons在构建时,会自动添加-shared(POSIX)或者/dll(Windows系统)编译选项,以保证编译的正确性。

4.2 链接库文件

​ 链接是库文件使用的最后一步,您可以通过指明LIBS变量关键字,来指定需要链接的库文件;通过指明LIBPATH变量关键字,来指定库文件的查找路径:

Library('foo', ['f1.c', 'f2.c', 'f3.c'])
Program('prog.c', LIBS=['foo', 'bar'], LIBPATH='.')

​ 请注意,您不需要特别声明库文件的前缀(如lib),或者后缀(如.a或.lib),SCons会自动根据系统来查找相关前缀或后缀。

​ 在POSIX或Linux系统中,上述编译过程如下:

> scons -Q
cc -o f1.o -c f1.c
cc -o f2.o -c f2.c
cc -o f3.o -c f3.c
ar rc libfoo.a f1.o f2.o f3.o
ranlib libfoo.a
cc -o prog.o -c prog.c
cc -o prog prog.o -L. -lfoo -lbar

​ 在Windows系统中,编译输出如下:

C:\>scons -Q
cl /Fof1.obj /c f1.c /nologo
cl /Fof2.obj /c f2.c /nologo
cl /Fof3.obj /c f3.c /nologo
lib /nologo /OUT:foo.lib f1.obj f2.obj f3.obj
cl /Foprog.obj /c prog.c /nologo
link /nologo /OUT:prog.exe /LIBPATH:. foo.lib bar.lib prog.obj
embedManifestExeCheck(target, source, env)

​ 另外,如果依赖的库文件只有一个,您也可以直接指定LIBS变量,而不是列表形式:

Program('prog.c', LIBS='foo', LIBPATH='.')
Program('prog.c', LIBS=['foo'], LIBPATH='.')

​ 上述两种写法完全等价。

4.3 查找库文件:LIBPATH变量

​ 默认情况下,连接器只会在系统路径中查找库文件,SCons可以通过用户指定的LIBPATH变量,来查找用户定义路径:

Program('prog.c', LIBS = 'm',
                  LIBPATH = ['/usr/lib', 'usr/local/lib'])

​ 这里推荐使用python的列表(list),因为python是跨平台的,这要迁移起来比较方便。当然您也可以将搜索路径放到一个字符串中,采用系统指定的分割符分开,如POSIX系统中采用冒号,Windows系统中采用分号:

# POSIX
LIBPATH = '/usr/lib:/usr/local/lib'
# Windows
LIBPATH = 'C:\\lib;D:\\lib'  

​ 请注意,python在Windows路径中要求采用反斜杠转义符。

​ 当链接器执行时,SCons会自动创建合适的标志,以便在和工程文件相同目录下查找,在POSIX或Linux系统中,上述示例编译输出如下:

> scons -Q
cc -o prog.o -c prog.c
cc -o prog prog.o -L/usr/lib -L/usr/local/lib -lm

​ 在Windows系统中,输出如下:

C:\>scons -Q
cl /Foprog.obj /c prog.c /nologo
link /nologo /OUT:prog.exe /LIBPATH:\usr\lib /LIBPATH:\usr\local\lib m.lib prog.obj
embedManifestExeCheck(target, source, env)

​ 整体而言,SCons会自动根据系统不同,而创建不同的编译选项,以保证编译输出的正确性。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,265评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,274评论 1 288
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,087评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,479评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,782评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,218评论 1 207
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,594评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,316评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,955评论 1 237
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,274评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,803评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,177评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,732评论 3 229
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,953评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,687评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,263评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,189评论 2 258

推荐阅读更多精彩内容