Update Snapshot(2018-12-12)
[platform/upstream/iotivity.git] / scons_script_how_to.txt
1 == How to write IoTivity build script ==
2
3 IoTivity projects are built with Scons. Scons is a cross-platform build tool,
4 it's quite similar to 'make'. 'SConstruct' is the entrance of scons build, it's
5 equivalent to 'Makefile' to 'make'.
6
7 This document only a brief reference. Detail about how to write scons script,
8 please refer to:
9         http://www.scons.org/doc/production/HTML/scons-user.html#
10
11 == Background: How to control source code compiling ==
12
13 Environment is a base conception of Scons. An environment is a collection of
14 values that can affect how a program is built.
15
16 e.g. There is a C file named hello.c, enter the following into a file named
17 SConstruct:
18         env = Environment()
19         env.Program('H', 'hello.c')
20
21 When run Scons in console, following will be executed:
22 cc -o hello.o -c hello.c
23 cc -o H hello.o
24
25 If you would like keep debug information in the binary, '-g' flag should be added
26 when build the source code. To do this, append a C compiler flags as following:
27         env = Environment()
28         env.AppendUnique(CFLAGS = ['-g'])
29         env.Program('H', 'hello.c')
30
31 When run Scons, following will be executed:
32 cc -o hello.o -c -g hello.c
33 cc -o H hello.o
34
35 In above example, 'CFLAGS' is changed. Following list the frequently used keys:
36
37 CFLAGS: General options that are passed to the C compiler
38 CCFLAGS: General options that are passed to the C & C++ compiler
39 CXXFLAGS: General options that are passed to the C++ compiler
40 CPPPATH: The directories that the preprocessor will search for include headers.
41 CPPDEFINES: Platform independent specification of C preprocessor definitions.
42
43 Note: CPPPATH and CPPDEFINES is common for all compiler. But others are
44 compiler specific, when change the key value, it may required to specify the
45 target platform(actually the compiler).
46
47 e.g.
48         env.AppendUnique(CPPPATH = ['.', 'include'])
49         env.AppendUnique(CPPDEFINES = ['NDEBUG', 'VER_TEST'])
50 Above two lines are fine for all target platform. but below line:
51         env.AppenUnique(CXXFLAGS = ['-g'])
52 is only fine for gcc compiler, as '-g' is a gcc flag, other compiler may don't
53 understand it. so it may should be:
54         if target_os not in ['windows', 'winrt']:
55                 env.AppenUnique(CXXFLAGS = ['-g'])
56
57 Still take the hello.c as example. Assume hello.h is in ./include/ directory,
58 #include "hello.h"
59 int main(int argc, char** argv)
60 {
61 #ifdef LANG_FR
62     printf("Bonjour\n");
63 #else
64         printf("Hello\n");
65 #endif
66 }
67
68 The Scons configure file should as following:
69         env = Environment()
70         env.AppendUnique(CFLAGS = ['-g'])
71         env.AppendUnique(CPPPATH = ['include'])
72         env.AppendUnique(CPPDEFINES = ['LANG_FR'])
73         env.Program('H', 'hello.c')
74
75 When run Scons, following will be executed:
76 cc -o hello.o -c -g -Iinclude -DLANG_FR hello.c
77 cc -o H hello.o
78
79 === Get extra information ===
80
81 In above example, 'target_os' is used. How to get it?
82
83 User can build IoTivity project on Linux / Windows / MAC OSX for various
84 targets(Linux, Tizen, Android, Arduino, Windows, MAC OSX, IOS ...). Most
85 platform specific configurations have been done in the common scripts which are in
86 build_common. The common scripts prepare an environment named 'env' with
87 target platform specific configuration.
88
89 When write IoTivity project build script, you can get this environment as
90 following:
91         Import('env')
92
93 You can use 'env' directly after import it(it isn't recommended). You can also
94 clone a new environment and update its keys(recommended).
95
96         new_env1 = Clone('env')
97         new_env2 = Clone('env')
98         new_env1.AppendUnqiue(xxx = [...])
99         new_env2.AppendUnqiue(xxx = [...])
100
101 The 'env' environment contains platform specific configuration, besides, there is
102 some common information. You can get the information with following line:
103         env.get('XXX')
104 or
105         env['XXX']
106
107 XXX is the information name, below are the extra information added by IoTivity
108 common scripts:
109 BUILD_DIR: the path of the build directory, all output are in this directory
110 SRC_DIR: the path of the top directory of the source code
111 RELEASE: build type, boolean. True - release build, False - debug build
112 TARGET_OS: the name of the target OS. The possible value depends on the host
113         platform. Bellow is the list of host and possible target OS. (darwin means
114         MAC OSX)
115                 linux: linux / android / arduino / tizen (means on Linux, you can build the
116                         project for Linux/Android/Arduino/Tizen)
117                 windows: windows / winrt / android / arduino
118                 darwin: darwin / ios / android / arduino
119
120 TARGET_ARCH: the target CPU arch. Its possible value depends on the target OS.
121         Bellow list the target OS and allowed CPU architecture.
122                 linux: x86 / x86_64 / arm / arm64 (means if the target OS is Linux, the CPU
123                         arch can be x86/x86_64/arm/arm64)
124                 android: x86 / x86_64 / armeabi / armeabi-v7a / armeabi-v7a-hard / arm64-v8a
125                 windows: x86 / amd64 / arm
126                 winrt: arm
127                 darwin: i386 / x86_64
128                 ios: i386 / x86_64 / armv7 / armv7s / arm64,
129                 arduino: avr / arm
130
131 === Extra functions ===
132
133 For convenience, in the common scripts, some extra functions are added.
134
135 PrintTargets(): print all target names in the help information.
136 AppendTarget(name, target = None): add a target name into targets list, when use
137         PrintTargets, the target name will be print
138 # @param name - the name of the target(s)(user defined name)
139 # @param target - Final binary, file(s) etc generated after build.
140
141 InstallTarget(files, name): it takes the same action as AppendTarget, besides,
142         it installs the 'files' to BUILD_DIR.
143
144 Following functions are only for Arduino:
145 ImportLib(lib): Arduino IDE includes many libraries. By default, no library is
146 compiled. If your project use some libraries, you can import the library by
147 this function. 'lib' is the name of the library to import. The 'include' path
148 will be auto added to the environment and the library will be built and linked
149 into the final binary.
150
151 CreateBin(bin, src): For Arduino, after build the program, it's required to
152 be converted into specific format (e.g .hex). This function will generate the
153 required .hex (and .eep if target arch is avr) file from 'bin'.
154
155 UploadHelp(): For different board, the upload command line is different, this
156 function print the recommended upload command line. You can see the recommended
157 upload command line in the help information(the output of command "scons
158 [options] -h")
159 Functions for external library management:
160 PrepareLib(libname, lib = None, path = None, script = None): Check whether a
161 library exists, if not, notify user to install it or try to download the source
162 code and build it
163 # @param libname - the name of the library try to prepare
164 # @param lib - the lib(.so, .a etc) to check (a library may include more then
165 #      one lib, e.g. boost, includes boost_thread, boost_system ...
166 # @param path - the path of the library building script, if it's not set,
167 #                       by default, it's <src_dir>/extlibs/<libname>/
168 # @param script - the building script, by default, it's 'SConscript'
169
170 Download(target, url): Download source code from URL 'url' and save as 'target'.
171 # @param target - the name of the source code package to be saved as
172 # @param url - the URL from which to download the source code
173
174 Configure(cwd, cmd): Run configure command(such as: bootstrap, configure etc.
175 usually it's done before build a library)
176 # @param cwd - the work directory, full path or relative path to the directory
177                 where the library build script in
178 # @param cmd - the command to run, can be a script or system command
179
180 Install_head_file(file): Install header file(s) to <src_dir>/deps/<target_os>/include
181 # @param file - the head file(s) to install
182
183 Install_lib(lib): Install library binaries to <src_dir>/deps/<target_os>/lib/<arch>
184 # @param lib - the library binary(.so, .a etc) to install
185
186 ==== Scripts Hierarchy ====
187
188 Scons provides a function 'SConscript(scripts, [exports, variant_dir, duplicate])'
189 It tells scons to execute one or more subsidiary configuration files(A script,
190 usually named SConscript). Take below project hierarchy as example to show how
191 to organise the scripts.
192
193                 prj
194                 |-------prj_1
195                 |               |--------sub_prj_11
196                 |               |--------sub_prj_..
197                 |               |--------sub_prj_1n
198                 |-------prj_2
199                 |
200                 | ... ...
201                 |
202                 |-------prj_n
203
204 As above project hierarchy, in 'SConstruct' file in the 'prj' directory, there
205 should include some lines like these:
206
207 #Please change this part according to the organisation of your projects.
208 #Note: To make the output is in build_dir, the path of the scripts should
209 #be relevant to build_dir
210 SConscript(build_dir + 'prj_1/SConscript')
211 SConscript(build_dir + 'prj_2/SConscript')
212 ... ...
213 SConscript(build_dir + 'prj_n/SConscript')
214
215
216 It's the same, in the 'prj_1/SConscript', there should include lines like
217 these:
218 SConscript('sub_prj_11/SConscript')
219 ... ...
220 SConscript('sub_prj_1n/SConscript')
221
222 The path is relevant to 'prj_1/SConscript'. You can also use the full path
223 (build_dir + 'prj_1/sub_prj_1x/SConscript'), but it's not recommended.
224
225 Above just to show a recommended way to manage subsidiary scripts. You don't
226 need strictly follow it.
227
228 ==== The content of a typical script ====
229
230 After run the scripts in build_common (usually it's done at the beginning of
231 SConstruct), an global environment 'env' is exported, 'env' has include the
232 default configuration of the target OS and arch. 'env' is used in all projects,
233 should avoid to change its keys. To avoid change 'env', usually clone 'env' and
234 update it according to the requirement of current sub project. Then specify the
235 target (usually binary) to build.
236
237 Below is an example:
238         # import the global environment 'env'
239         Import('env')
240
241         # Clone a new environment from 'env'
242         new_env = env.Clone()
243
244         # Update the new environment, usually include add header file paths,
245         # library path, libs to link and other compiler flags. This part is
246         # optional.
247         new_env.AppendUnique(xxx = [ .... ])
248
249         # Specify the target(application, library, object or others) to build
250         ts = new_env.Program('program_name', [source_list])
251
252         # Install the target (optional)
253         # If it's an important library or daemon to be published
254         new_env.InstallTarget(ts, 'target_name')
255 or
256         # If it's examples or test program or others will not be published
257         new_env.AppendTarget('target_name', ts)
258
259 ==== Tips ====
260 1. library order: if A lib use B lib, both A and B are linked to target T, when
261         specify libraries, A should in front of B, otherwise there may be link
262         error. e.g.
263                 xx_env.AppendUnique(LIBS = ['A', 'B'])
264
265 2. On android:
266         (1)'pthread' is in libc. So don't use '-lpthread' for android
267         (2)By default 'rtti' and 'exception' is disabled, to enable it, you need
268         add flags '-frtti' and '-fexceptions'
269         (3)If STL is used, need link 'gnustl_shared' library