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 10 import os 11 12 env = Environment() 13 14 BASE_VER = os.environ.get('BASE_VER', '0') 15 PKG_CONFIG = os.environ.get('PKG_CONFIG', 'pkg-config') 16 CHROME_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. 24 base_name = 'base' 25 base_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 323 env.Append( 324 CPPPATH=['files'], 325 CCFLAGS=['-g'] 326 ) 327 for 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) 331 if os.environ.has_key('CPPFLAGS'): 332 env['CCFLAGS'] += Split(os.environ['CPPFLAGS']) 333 334 env['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 351 env.Append( 352 CXXFLAGS=['-std=c++11'] 353 ) 354 355 # Flags for clang taken from build/common.gypi in the clang==1 section. 356 CLANG_FLAGS = ( 357 '-Wno-char-subscripts', 358 ) 359 360 env['CCFLAGS'] += ['-Xclang-only=%s' % x for x in CLANG_FLAGS] 361 362 # Fix issue with scons not passing some vars through the environment. 363 for key in Split('PKG_CONFIG SYSROOT'): 364 if os.environ.has_key(key): 365 env['ENV'][key] = os.environ[key] 366 367 all_base_libs = [] 368 all_pc_libs = '' 369 all_libs = [] 370 all_scons_libs = [] 371 372 # Build all the shared libraries. 373 for 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 408 all_base_test_libs = [] 409 all_test_pc_libs = '' 410 all_test_libs = [] 411 412 test_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 450 for 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 469 def lib_list(libs): 470 return ' '.join(['-l' + l for l in libs]) 471 472 prod_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. 487 test_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 501 pc_file_contents = """ 502 prefix=/usr 503 includedir=${prefix}/include 504 bslot=@BSLOT@ 505 506 Name: @NAME@ 507 Description: @DESCRIPTION@ 508 Version: ${bslot} 509 Requires: 510 Requires.private: @PRIVATE_PC@ 511 Libs: -l@TARGET_LIB@ 512 Libs.private: @BASE_LIBS@ @LIBS@ 513 Cflags: -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 517 so_file_contents = """GROUP ( AS_NEEDED ( @BASE_LIBS@ ) )""" 518 519 for 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