1# -*- python -*-
2
3# Copyright 2014 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7# This file is used to build the libchrome package for Chrome OS:
8# https://www.chromium.org/chromium-os/packages/libchrome
9
10import os
11
12env = Environment()
13
14BASE_VER = os.environ.get('BASE_VER', '0')
15PKG_CONFIG = os.environ.get('PKG_CONFIG', 'pkg-config')
16CHROME_INCLUDE_PATH = os.environ.get('CHROME_INCLUDE_PATH', '.')
17
18# This block will need updating whenever libchrome gets updated. The order of
19# the libs below doesn't matter (as scons will take care of building things in
20# the required order).  The split between them is purely to reduce excess
21# linking of third-party libraries, i.e. 'core' should require only a minimal
22# set of libraries, and other third-party libraries should get a unique 'xxx'
23# name.
24base_name = 'base'
25base_libs = [
26  {
27    'name' : 'core',
28    'sources' : """
29                allocator/allocator_extension.cc
30                at_exit.cc
31                base64.cc
32                base64url.cc
33                base_switches.cc
34                bind_helpers.cc
35                build_time.cc
36                callback_helpers.cc
37                callback_internal.cc
38                command_line.cc
39                cpu.cc
40                debug/alias.cc
41                debug/debugger.cc
42                debug/debugger_posix.cc
43                debug/stack_trace.cc
44                debug/stack_trace_posix.cc
45                debug/task_annotator.cc
46                environment.cc
47                files/file.cc
48                files/file_enumerator.cc
49                files/file_enumerator_posix.cc
50                files/file_path.cc
51                files/file_path_constants.cc
52                files/file_path_watcher.cc
53                files/file_path_watcher_linux.cc
54                files/file_posix.cc
55                files/file_tracing.cc
56                files/file_util.cc
57                files/file_util_linux.cc
58                files/file_util_posix.cc
59                files/important_file_writer.cc
60                files/memory_mapped_file.cc
61                files/memory_mapped_file_posix.cc
62                files/scoped_file.cc
63                files/scoped_temp_dir.cc
64                guid.cc
65                guid_posix.cc
66                json/json_file_value_serializer.cc
67                json/json_parser.cc
68                json/json_reader.cc
69                json/json_string_value_serializer.cc
70                json/json_value_converter.cc
71                json/json_writer.cc
72                json/string_escape.cc
73                lazy_instance.cc
74                location.cc
75                logging.cc
76                md5.cc
77                memory/ref_counted.cc
78                memory/ref_counted_memory.cc
79                memory/singleton.cc
80                memory/weak_ptr.cc
81                message_loop/incoming_task_queue.cc
82                message_loop/message_loop.cc
83                message_loop/message_loop_task_runner.cc
84                message_loop/message_pump.cc
85                message_loop/message_pump_default.cc
86                message_loop/message_pump_glib.cc
87                message_loop/message_pump_libevent.cc
88                metrics/bucket_ranges.cc
89                metrics/field_trial.cc
90                metrics/metrics_hashes.cc
91                metrics/histogram_base.cc
92                metrics/histogram.cc
93                metrics/histogram_samples.cc
94                metrics/histogram_snapshot_manager.cc
95                metrics/sample_map.cc
96                metrics/sample_vector.cc
97                metrics/sparse_histogram.cc
98                metrics/statistics_recorder.cc
99                pending_task.cc
100                pickle.cc
101                posix/file_descriptor_shuffle.cc
102                posix/global_descriptors.cc
103                posix/safe_strerror.cc
104                posix/unix_domain_socket_linux.cc
105                process/internal_linux.cc
106                process/kill.cc
107                process/kill_posix.cc
108                process/launch.cc
109                process/launch_posix.cc
110                process/process_handle_linux.cc
111                process/process_iterator.cc
112                process/process_iterator_linux.cc
113                process/process_handle_posix.cc
114                process/process_metrics.cc
115                process/process_metrics_linux.cc
116                process/process_metrics_posix.cc
117                process/process_posix.cc
118                profiler/alternate_timer.cc
119                profiler/scoped_profile.cc
120                profiler/scoped_tracker.cc
121                profiler/tracked_time.cc
122                rand_util.cc
123                rand_util_posix.cc
124                run_loop.cc
125                sequence_checker_impl.cc
126                sequenced_task_runner.cc
127                sha1_portable.cc
128                strings/pattern.cc
129                strings/safe_sprintf.cc
130                strings/string16.cc
131                strings/string_number_conversions.cc
132                strings/string_piece.cc
133                strings/stringprintf.cc
134                strings/string_split.cc
135                strings/string_util.cc
136                strings/string_util_constants.cc
137                strings/sys_string_conversions_posix.cc
138                strings/utf_string_conversions.cc
139                strings/utf_string_conversion_utils.cc
140                synchronization/cancellation_flag.cc
141                synchronization/condition_variable_posix.cc
142                synchronization/lock.cc
143                synchronization/lock_impl_posix.cc
144                synchronization/waitable_event_posix.cc
145                synchronization/waitable_event_watcher_posix.cc
146                sync_socket_posix.cc
147                sys_info.cc
148                sys_info_chromeos.cc
149                sys_info_linux.cc
150                sys_info_posix.cc
151                task_runner.cc
152                task/cancelable_task_tracker.cc
153                third_party/icu/icu_utf.cc
154                third_party/nspr/prtime.cc
155                threading/non_thread_safe_impl.cc
156                threading/platform_thread_internal_posix.cc
157                threading/platform_thread_linux.cc
158                threading/platform_thread_posix.cc
159                threading/post_task_and_reply_impl.cc
160                threading/sequenced_worker_pool.cc
161                threading/simple_thread.cc
162                threading/thread.cc
163                threading/thread_checker_impl.cc
164                threading/thread_collision_warner.cc
165                threading/thread_id_name_manager.cc
166                threading/thread_local_posix.cc
167                threading/thread_local_storage.cc
168                threading/thread_local_storage_posix.cc
169                threading/thread_restrictions.cc
170                threading/worker_pool.cc
171                threading/worker_pool_posix.cc
172                thread_task_runner_handle.cc
173                timer/elapsed_timer.cc
174                timer/timer.cc
175                time/clock.cc
176                time/default_clock.cc
177                time/default_tick_clock.cc
178                time/tick_clock.cc
179                time/time.cc
180                time/time_posix.cc
181                trace_event/malloc_dump_provider.cc
182                trace_event/heap_profiler_allocation_context.cc
183                trace_event/heap_profiler_allocation_context_tracker.cc
184                trace_event/heap_profiler_stack_frame_deduplicator.cc
185                trace_event/heap_profiler_type_name_deduplicator.cc
186                trace_event/memory_allocator_dump.cc
187                trace_event/memory_allocator_dump_guid.cc
188                trace_event/memory_dump_manager.cc
189                trace_event/memory_dump_request_args.cc
190                trace_event/memory_dump_session_state.cc
191                trace_event/process_memory_dump.cc
192                trace_event/process_memory_maps.cc
193                trace_event/process_memory_maps_dump_provider.cc
194                trace_event/process_memory_totals.cc
195                trace_event/process_memory_totals_dump_provider.cc
196                trace_event/trace_buffer.cc
197                trace_event/trace_config.cc
198                trace_event/trace_event_argument.cc
199                trace_event/trace_event_impl.cc
200                trace_event/trace_event_memory_overhead.cc
201                trace_event/trace_event_synthetic_delay.cc
202                trace_event/trace_log.cc
203                trace_event/trace_log_constants.cc
204                trace_event/trace_sampling_thread.cc
205                tracked_objects.cc
206                tracking_info.cc
207                values.cc
208                vlog.cc
209                """,
210    'prefix' : 'base',
211    'libs' : 'pthread rt libmodp_b64',
212    'pc_libs' : 'glib-2.0 libevent',
213  },
214  {
215    'name' : 'dl',
216    'sources' : """
217                native_library_posix.cc
218                """,
219    'prefix' : 'base',
220    'libs' : 'dl',
221    'pc_libs' : '',
222  },
223  {
224    'name' : 'dbus',
225    'sources' : """
226                bus.cc
227                dbus_statistics.cc
228                exported_object.cc
229                file_descriptor.cc
230                message.cc
231                object_manager.cc
232                object_path.cc
233                object_proxy.cc
234                property.cc
235                scoped_dbus_error.cc
236                string_util.cc
237                util.cc
238                values_util.cc
239                """,
240    'prefix' : 'dbus',
241    'libs' : '',
242    'pc_libs' : 'dbus-1 protobuf-lite',
243  },
244  {
245    'name' : 'timers',
246    'sources' : """
247                alarm_timer_chromeos.cc
248                """,
249    'prefix' : 'components/timers',
250    'libs' : '',
251    'pc_libs' : '',
252  },
253  {
254    'name' : 'crypto',
255    'sources' : """
256                hmac.cc
257                hmac_nss.cc
258                nss_key_util.cc
259                nss_util.cc
260                p224.cc
261                p224_spake.cc
262                random.cc
263                rsa_private_key.cc
264                rsa_private_key_nss.cc
265                scoped_test_nss_db.cc
266                secure_hash_default.cc
267                secure_util.cc
268                sha2.cc
269                signature_creator_nss.cc
270                signature_verifier_nss.cc
271                symmetric_key_nss.cc
272                third_party/nss/rsawrapr.c
273                third_party/nss/sha512.cc
274                """,
275    'prefix' : 'crypto',
276    'libs' : '%s-dl-%s' % (base_name, BASE_VER),
277    'pc_libs' : 'nss',
278  },
279  {
280    'name' : 'sandbox',
281    'sources' : """
282                linux/bpf_dsl/bpf_dsl.cc
283                linux/bpf_dsl/codegen.cc
284                linux/bpf_dsl/dump_bpf.cc
285                linux/bpf_dsl/policy.cc
286                linux/bpf_dsl/policy_compiler.cc
287                linux/bpf_dsl/syscall_set.cc
288                linux/bpf_dsl/verifier.cc
289                linux/seccomp-bpf/die.cc
290                linux/seccomp-bpf/sandbox_bpf.cc
291                linux/seccomp-bpf/syscall.cc
292                linux/seccomp-bpf/trap.cc
293
294                linux/seccomp-bpf-helpers/baseline_policy.cc
295                linux/seccomp-bpf-helpers/sigsys_handlers.cc
296                linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc
297                linux/seccomp-bpf-helpers/syscall_sets.cc
298
299                linux/services/init_process_reaper.cc
300                linux/services/proc_util.cc
301                linux/services/resource_limits.cc
302                linux/services/scoped_process.cc
303                linux/services/syscall_wrappers.cc
304                linux/services/thread_helpers.cc
305                linux/services/yama.cc
306                linux/syscall_broker/broker_channel.cc
307                linux/syscall_broker/broker_client.cc
308                linux/syscall_broker/broker_file_permission.cc
309                linux/syscall_broker/broker_host.cc
310                linux/syscall_broker/broker_policy.cc
311                linux/syscall_broker/broker_process.cc
312
313                linux/services/credentials.cc
314                linux/services/namespace_sandbox.cc
315                linux/services/namespace_utils.cc
316                """,
317    'prefix' : 'sandbox',
318    'libs' : '',
319    'pc_libs' : '',
320  },
321]
322
323env.Append(
324  CPPPATH=['files'],
325  CCFLAGS=['-g']
326)
327for key in Split('CC CXX AR RANLIB LD NM CFLAGS CXXFLAGS LDFLAGS'):
328  value = os.environ.get(key)
329  if value:
330    env[key] = Split(value)
331if os.environ.has_key('CPPFLAGS'):
332  env['CCFLAGS'] += Split(os.environ['CPPFLAGS'])
333
334env['CCFLAGS'] += ['-DOS_CHROMEOS',
335                   '-DUSE_NSS_CERTS',
336                   '-DUSE_SYSTEM_LIBEVENT',
337                   '-fPIC',
338                   '-fno-exceptions',
339                   '-Wall',
340                   '-Werror',
341                   '-Wno-deprecated-register',
342                   '-Wno-narrowing',
343                   '-Wno-psabi',
344                   '-Wno-unused-local-typedefs',
345                   # Various #defines are hardcoded near the top of
346                   # build_config.h to ensure that they'll be set both when
347                   # libchrome is built and when other packages include
348                   # libchrome's headers.
349                   '-I%s' % CHROME_INCLUDE_PATH]
350
351env.Append(
352  CXXFLAGS=['-std=c++11']
353)
354
355# Flags for clang taken from build/common.gypi in the clang==1 section.
356CLANG_FLAGS = (
357  '-Wno-char-subscripts',
358)
359
360env['CCFLAGS'] += ['-Xclang-only=%s' % x for x in CLANG_FLAGS]
361
362# Fix issue with scons not passing some vars through the environment.
363for key in Split('PKG_CONFIG SYSROOT'):
364  if os.environ.has_key(key):
365    env['ENV'][key] = os.environ[key]
366
367all_base_libs = []
368all_pc_libs = ''
369all_libs = []
370all_scons_libs = []
371
372# Build all the shared libraries.
373for lib in base_libs:
374  pc_libs = lib['pc_libs'].replace('${bslot}', BASE_VER)
375  all_pc_libs += ' ' + pc_libs
376
377  libs = Split(lib['libs'].replace('${bslot}', BASE_VER))
378  all_libs += libs
379
380  name = '%s-%s-%s' % (base_name, lib['name'], BASE_VER)
381  all_base_libs += [name]
382  corename = '%s-core-%s' % (base_name, BASE_VER)
383  # Automatically link the sub-libs against the main core lib.
384  # This is to keep from having to explicitly mention it in the
385  # table above (i.e. lazy).
386  if name != corename:
387    libs += [corename]
388
389  e = env.Clone()
390  e.Append(
391    LIBS = Split(libs),
392    LIBPATH = ['.'],
393    LINKFLAGS = ['-Wl,--as-needed', '-Wl,-z,defs',
394                 '-Wl,-soname,lib%s.so' % name],
395  )
396  if pc_libs:
397    e.ParseConfig(PKG_CONFIG + ' --cflags --libs %s' % pc_libs)
398
399  # Prepend prefix to source filenames.
400  sources = [os.path.join(lib['prefix'], x) for x in Split(lib['sources'])]
401
402  all_scons_libs += [ e.SharedLibrary(name, sources) ]
403
404
405# Build a static library of mocks for unittests to link against.
406# Being static allows us to mask this library out of the image.
407
408all_base_test_libs = []
409all_test_pc_libs = ''
410all_test_libs = []
411
412test_libs = [
413  {
414    'name': 'base_test_support',
415    'sources': """
416               simple_test_clock.cc
417               simple_test_tick_clock.cc
418               test_file_util.cc
419               test_file_util_linux.cc
420               test_switches.cc
421               test_timeouts.cc
422               """,
423    'prefix': 'base/test',
424    'libs': '',
425    'pc_libs': '',
426  },
427  {
428    'name': 'dbus_test_support',
429    'sources': """
430               mock_bus.cc
431               mock_exported_object.cc
432               mock_object_manager.cc
433               mock_object_proxy.cc
434               """,
435    'prefix': 'dbus',
436    'libs': '',  # TODO(wiley) what should go here?
437    'pc_libs': 'dbus-1 protobuf-lite',
438  },
439  {
440    'name': 'timer_test_support',
441    'sources': """
442               mock_timer.cc
443               """,
444    'prefix': 'base/timer',
445    'libs': '',
446    'pc_libs': '',
447  },
448]
449
450for lib in test_libs:
451  pc_libs = lib['pc_libs'].replace('${bslot}', BASE_VER)
452  all_test_pc_libs += ' ' + pc_libs
453
454  libs = Split(lib['libs'].replace('${bslot}', BASE_VER))
455  all_test_libs += libs
456
457  name = '%s-%s-%s' % (base_name, lib['name'], BASE_VER)
458  all_base_test_libs += [name]
459
460  static_env = env.Clone()
461  if pc_libs:
462    static_env.ParseConfig(PKG_CONFIG + ' --cflags --libs %s' % pc_libs)
463  sources = [os.path.join(lib['prefix'], x)
464             for x in Split(lib['sources'])]
465  static_env.StaticLibrary(name, sources)
466
467# Build the random text files (pkg-config and linker script).
468
469def lib_list(libs):
470  return ' '.join(['-l' + l for l in libs])
471
472prod_subst_dict = {
473  '@BSLOT@': BASE_VER,
474  '@PRIVATE_PC@': all_pc_libs,
475  '@BASE_LIBS@': lib_list(all_base_libs),
476  '@LIBS@': lib_list(all_libs),
477  '@NAME@': 'libchrome',
478  '@PKG_CFG_NAME@': 'libchrome-%s.pc' % BASE_VER,
479  '@LIB_NAME@': 'libbase-%s.so' % BASE_VER,
480  '@DESCRIPTION@': 'chrome base library',
481  # scons, in its infinite wisdom sees fit to expand this string if
482  # if we don't escape the $.
483  '@TARGET_LIB@': 'base-$${bslot}',
484}
485
486# Similarly, build text files related to the test libraries.
487test_subst_dict = {
488  '@BSLOT@': BASE_VER,
489  '@PRIVATE_PC@': all_test_pc_libs,
490  '@BASE_LIBS@': lib_list(all_base_test_libs),
491  '@LIBS@': lib_list(all_test_libs),
492  '@NAME@': 'libchrome-test',
493  '@PKG_CFG_NAME@': 'libchrome-test-%s.pc' % BASE_VER,
494  '@LIB_NAME@': 'libbase-test-%s.a' % BASE_VER,
495  '@DESCRIPTION@': 'chrome base test library',
496  # scons, in its infinite wisdom sees fit to expand this string if
497  # if we don't escape the $.
498  '@TARGET_LIB@': 'base-test-$${bslot}',
499}
500
501pc_file_contents = """
502prefix=/usr
503includedir=${prefix}/include
504bslot=@BSLOT@
505
506Name: @NAME@
507Description: @DESCRIPTION@
508Version: ${bslot}
509Requires:
510Requires.private: @PRIVATE_PC@
511Libs: -l@TARGET_LIB@
512Libs.private: @BASE_LIBS@ @LIBS@
513Cflags: -I${includedir}/@TARGET_LIB@ -Wno-c++11-extensions -Wno-unused-local-typedefs -DBASE_VER=${bslot}
514"""
515
516# https://sourceware.org/binutils/docs/ld/Scripts.html
517so_file_contents = """GROUP ( AS_NEEDED ( @BASE_LIBS@ ) )"""
518
519for subst_dict in (test_subst_dict, prod_subst_dict):
520  env = Environment(tools=['textfile'], SUBST_DICT=subst_dict)
521  env.Substfile(subst_dict['@LIB_NAME@'], [Value(so_file_contents)])
522  env.Substfile(subst_dict['@PKG_CFG_NAME@'], [Value(pc_file_contents)])
523