linux一般通过makefile控制编译。linux代码目录结构是
+scons_project_root
【src】 #源代码目录
[dir1]
[dir2]
[dir3]
main.c
【target】 #目标输出目录
[include]
[lib]
[bin]
通过2天的学习及摸索。通过scons也实现这些功能。
至于scons的一些基本知识,请baidu查找,这里不要提及。
一:代码目录结构
+scons_project_root
【src dir】
[sub]
->sub.c
->sub.h
->sub1.c
[add]
->add.c
->add.h
->main.c # 主函数main定义,程序入口。其要调用sub.c sub1.c add.c里的函数
【target] # 编译输出目标文件。
[include]
libsub.a # sub.c sub1.生成的lib
libadd.a # add.c 生成的lib
[lib]
->sub.h # sub.c sub1.c对应的头文件
->add.h # add.c 对应的头文件
[bin]
->main # 最后输出的程序。
二:工程编译
单独编译sub
cd scons_project_root/src/sub
scons
单独编译add
cd scons_project_root/src/add
scons
单独编译main sub,add
cd scons_project_root/src
scons
全编译工程:
cd scons_project_root
scons
总结,每个目录都可以单独编译,对于某工程师只负责某部门lib,提高编译效率。这个是非常方便的。
三:软件发布
如果要发布lib给第三方开发。则把target里的include,lib目录发布即可。
如果要发布最后程序bin文件。则把target dir里的bin目录main发布即可。
四:在现在的lib增加新.c文件。
如果要在目录的sub子目录增加新.c代码文件。则直接在sub增加即可。SConstruct不用做任何修改即可实现编译。
但是如果yyy.c函数要声明给外部使用,则在sub.h头文件增加增加即可。如果只是新.c内部使用,则不用增加。
五:新lib增加
理解透sub目录的SConstruct文件每个语句。则后续添加lib是一个很简单的事情。
step1:
1: 在project_root/src增加“XXX”子目录。同时XXX也作为库名。最后输出libXXX.a
2: 把sub目录的SConstruct拷贝到XXX子目录
3:打开XXX子目录SConstruct文件,修改如下两个变量的值
LIB_NAME="XXX" # Please modify by yourself from projiect
HEAD_NAME="XXX.h" # Please modify by yourself from projiect
4: 打开project_root/src/main.c
在开头include "XXX.h"
step2:修改project_root/src/SConstruct. 只修改生成main程序连接lib就可以了。修改这个变量. “XXX”代码是新增加的lib名。注意要去掉lib头和.a尾字符
LIBS_LIST=['add','sub','XXX']
六:本scons使用到的关键技术。
1: 目录嵌套通过 具体看 scons_project_root/SConstruct scons_project_root/src/SConstruct
env = Environment()
env.SConscript(['src/SConstruct'])
2:指定include路径 等同makefile -I参数 具体看 scons_project_root/src/SConstruct
CPPPATH
3:指定 LIBS 路径:等同makefile -L参数 具体看 scons_project_root/src/SConstruct
LIBPATH
4:指定lib连接库名。等同makefile -l参数 具体看 scons_project_root/src/SConstruct
LIBS
5:编译完成后,把libxxx.a,xxx.h拷贝到指定目录, 具体看 scons_project_root/src/sub/SConstruct
env.Install('./../../target/lib', build_lib)
特备注意,目标路径一定要用相对路径,不能用绝对路径。./代表SConstruct文件所在路径。
6:通配符函数Glob使用。 具体看 scons_project_root/src/sub/SConstruct
LIB_NAME="sub"
src_files=Glob('*.c')
build_lib=env.StaticLibrary(LIB_NAME,src_files)
七: 对于makefile,执行make clean。一定要在makefile的clean宏里写具体清楚命令代码。但是对于scons。
只要在project_root目录下执行 scons -c 。则
1 scons_project_root->target子目录全清楚。 通过env.Install语句识别是反向操作的。
2 src 各个子目录下的 *.o *.a 要自动清除。通过builder method识别是反向操作的。builder method类型如下
Program : generate executable file
Object : generate Object file
Java : 编译java程序, User Guide 2.3, Chapter 25
Library : 静态库, 也可以使用 StaticLibrary替代
SharedLibrary: 动态库
所以变得非常简单