当前位置: 首页 > 工具软件 > SCons > 使用案例 >

SCons教程(3) 编译程序

缑智敏
2023-12-01

编译

重定义目标输出文件名称

admin@DESKTOP-NQU1HUV C:\Users\admin\Desktop\scons\day3
$ scons
scons: Reading SConscript files ...
Finished calling Program()
scons: done reading SConscript files.
scons: Building targets ...
gcc -o hello.o -c hello.c
gcc -o hello.exe hello.o
gcc -o new_hello.exe hello.o
scons: done building targets.

admin@DESKTOP-NQU1HUV C:\Users\admin\Desktop\scons\day3
$ ls
SConstruct  hello.c  hello.exe  hello.o  new_hello.exe

可以看到有两个文件输出,分别是默认输出文件 hello.exenew_hello.exe

编译多文件

在实际工程中,不会只编译一个文件,这样就无法体现出来 scons 的作用了。一般情况下,是对整个工程内的多个文件共同编译,同时也可能涉及到多个文件夹。和开发者创建的工程目录有关系。

编译同一个文件夹下的多个源文件

admin@DESKTOP-NQU1HUV C:\Users\admin\Desktop\scons\day3
$ scons
scons: Reading SConscript files ...
Finished calling Program()
scons: done reading SConscript files.
scons: Building targets ...
gcc -o hello.o -c hello.c
gcc -o src_file1.o -c src_file1.c
gcc -o src_file2.o -c src_file2.c
gcc -o hello.exe hello.o src_file1.o src_file2.o
scons: done building targets.

admin@DESKTOP-NQU1HUV C:\Users\admin\Desktop\scons\day3
$ ls
SConstruct  hello.exe  src_file1.c  src_file2.c  ????.md
hello.c     hello.o    src_file1.o  src_file2.o

admin@DESKTOP-NQU1HUV C:\Users\admin\Desktop\scons\day3
$ hello.exe
hello
file1
file2

在生成的文件中,可以看到每个源文件都对应一个目标文件(.o),同时可以看到生成了一个 hello.exe 文件,运行该文件,可以看到分别输出三条语句。

下面我们修改一下 SConstruct 文件内容,看一下生成的文件是否有不同。

# Program(['hello.c', 'src_file1.c', 'src_file2.c'])
# 修改城下面的语句,交换 hello.c 和 src_file1.c 的位置
Program(['src_file1.c', 'hello.c', 'src_file2.c'])

执行 scons 生成文件后,可以看到之前的 hello.exe 已经没有了,多了一个 src_file1.exe 文件,因为没有显示指出 target 的名称,则第一个源文件名称被作为目标名称进行构建。

admin@DESKTOP-NQU1HUV C:\Users\admin\Desktop\scons\day3
$ scons
scons: Reading SConscript files ...
Finished calling Program()
scons: done reading SConscript files.
scons: Building targets ...
gcc -o hello.o -c hello.c
gcc -o src_file1.o -c src_file1.c
gcc -o src_file2.o -c src_file2.c
gcc -o src_file1.exe src_file1.o hello.o src_file2.o
scons: done building targets.

admin@DESKTOP-NQU1HUV C:\Users\admin\Desktop\scons\day3
$ ls
SConstruct  hello.o      src_file1.exe  src_file2.c  ????.md
hello.c     src_file1.c  src_file1.o    src_file2.o

admin@DESKTOP-NQU1HUV C:\Users\admin\Desktop\scons\day3
$ src_file1.exe
hello
file1
file2

用 Glob 来创建文件列表

SCons 支持使用 Glob 函数来辅助查找与某个模板想匹配的多喝文件,且支持通配符 *.?,这使得一些多文件系统中,构建文件变得比较容易。

使用 Glob 来构建程序。

Program('program', Glob('*.c'))

可以看出构建程序是正常执行,且构建后的程序,运行正常。

admin@DESKTOP-NQU1HUV C:\Users\admin\Desktop\scons\day3
$ scons
scons: Reading SConscript files ...
Finished calling Program()
scons: done reading SConscript files.
scons: Building targets ...
gcc -o hello.o -c hello.c
gcc -o src_file1.o -c src_file1.c
gcc -o src_file2.o -c src_file2.c
gcc -o program.exe hello.o src_file1.o src_file2.o
scons: done building targets.

admin@DESKTOP-NQU1HUV C:\Users\admin\Desktop\scons\day3
$ ls
SConstruct  hello.o      src_file1.c  src_file2.c  ????.md
hello.c     program.exe  src_file1.o  src_file2.o

admin@DESKTOP-NQU1HUV C:\Users\admin\Desktop\scons\day3
$ program.exe
hello
file1
file2

由于 SCons 是支持 python 语法的,所以可以在 SConstruct 中使用 python 语法来处理一些简单事务,帮助我们来理解这个构建过程。如果对 python 熟悉的话,那么下面语句回变得相对简单理解。

// 使用 Split 分割字符串
Program('program', Split('hello.c src_file1.c src_file2.c'))

// 使用中间变量
src_files = Split('hello.c src_file1.c src_file2.c')
Program('program', src_files)

// 多行字符串方式
src_files = Split("""hello.c
                    src_file1.c
                    src_file2.c""")
Program('program', src_files)

共享源文件,构建多个目标

上面我们介绍了,怎么去一次构建多个目标,可以复习一下:
首先创建 hello2.c 文件,内容如下:

// hello2.c
#include <stdio.h>

extern void file1(void);
extern void file2(void);

int main(void)
{
    printf("hello2\r\n");
    file1();
    file2();
    return 0;
}

编写构建多个目标的 SConstruct

Program(['hello.c', 'src_file1.c', 'src_file2.c'])
Program(['hello2.c', 'src_file1.c', 'src_file2.c'])

执行 scons ,可以看到窗口正常构建了两个程序 hello.exehello2.exe

admin@DESKTOP-NQU1HUV C:\Users\admin\Desktop\scons\day3
$ scons
scons: Reading SConscript files ...
Finished calling Program()
scons: done reading SConscript files.
scons: Building targets ...
gcc -o hello.o -c hello.c
gcc -o src_file1.o -c src_file1.c
gcc -o src_file2.o -c src_file2.c
gcc -o hello.exe hello.o src_file1.o src_file2.o
gcc -o hello2.o -c hello2.c
gcc -o hello2.exe hello2.o src_file1.o src_file2.o
scons: done building targets.

构建程序脚本中,可以看到两个程序的构建源文件是重复的,简单构建爱你过程可能没有什么感觉,但是在一个超过上百个源文件的工程内,如果构建两个目标,则会变得复杂。

下面介绍一种方法,对于这种拥有一些同样的源文件,变得更加简单。

common = ['src_file1.c', 'src_file2.c']
hello_files = ['hello.c'] + common
hello2_files = ['hello2.c'] + common
Program('hello', hello_files)
Program('hello2', hello2_files)

执行 scons 进行构建,可以看到生成了 hello.exehello2.exe 两个文件

admin@DESKTOP-NQU1HUV C:\Users\admin\Desktop\scons\day3
$ scons
scons: Reading SConscript files ...
Finished calling Program()
scons: done reading SConscript files.
scons: Building targets ...
gcc -o hello.o -c hello.c
gcc -o src_file1.o -c src_file1.c
gcc -o src_file2.o -c src_file2.c
gcc -o hello.exe hello.o src_file1.o src_file2.o
gcc -o hello2.o -c hello2.c
gcc -o hello2.exe hello2.o src_file1.o src_file2.o
scons: done building targets.
 类似资料: