#! -*- python -*- # # Copyright (c) 2011 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Build file for running scripts in the build_tools directory Adapted from scons documentation: http://www.scons.org/wiki/UnitTests and from ../project_templates/test.scons """ __author__ = 'mball@google.com (Matt Ball)' from build_tools import build_utils from build_tools import make_nacl_tools from build_tools import make_sdk_tools import os import sys Import('env') # Add the system path to this environment so that we can run gclient and such env.AppendENVPath('PATH', os.environ['PATH']) # Duplicate all the shell environment variables, so that various Visual Studio # tools will have the variables they expect (e.g. VS 2008 needs VS90COMNTOOLS). # Do this using "if not in" instead of update(), so that os.environ variables # don't override variables in env['ENV']. for shell_var in os.environ: if shell_var not in env['ENV']: env['ENV'][shell_var] = os.environ[shell_var] def run_generate_installer(env, target, source): '''Runs the generate_installer script to create the SDK installer''' args = [] if env['IS_WINDOWS']: from build_tools import generate_windows_installer return generate_windows_installer.main(args) else: from build_tools import generate_installers return generate_installers.main(args) installer_node = env.Command( target='generate_installers_dummy_target.txt', source='generate_installers.py', action=run_generate_installer) env.Depends(installer_node, env.GetToolchainNode()) env.Depends(installer_node, env.GetInstallerPrereqsNode()) env.AddNodeAliases(installer_node, ['bot'], 'installer') install_file = 'nacl-sdk.exe' if sys.platform == 'win32' else 'nacl-sdk.tgz' installer = os.path.join(os.path.dirname(env['ROOT_DIR']), install_file) def BuildSdkTools(env, target, source): make_sdk_tools.MakeSdkTools(str(target[0].abspath), str(target[1].abspath)) sdk_tools_node = env.Command( target=['nacl_sdk.zip', 'sdk_tools.tgz'], source=[os.path.join('sdk_tools', 'sdk_update.py'), 'make_sdk_tools.py', os.path.join(env['ROOT_DIR'], 'LICENSE')], action=BuildSdkTools) env.AddNodeAliases(sdk_tools_node, ['bot'], 'sdk_tools') installer_test_node = env.CreatePythonUnitTest( 'tests/installer_test.py', [installer_node if not env['USE_EXISTING_INSTALLER'] else installer], buffered=False, params=['--jobs=%s' % env['JOB_COUNT'], '--outdir=%s' % os.path.join('scons-out', 'sdk_installer'), '--nacl-sdk', env.File('nacl_sdk.zip'), '--sdk-tools', env.File('sdk_tools.tgz'), installer], banner='test installer',) env.AddNodeToTestSuite(installer_test_node, ['bot'], 'run_installer_test', 'large') env.Depends(env.GetInstallerTestNode(), installer_test_node) #------------------------------------------------------------------------------ # Add build_tools unit tests def AddPythonUnitTest(command, file, size='small', **kwargs): ''' Adds a new python unit test Args: command: The scons command to run this unit test file: The python file containing the unit test size: How big is this test? small, medium, or large kwargs: See named parameters to CreatePythonUnitTest returns: test node for this newly created test''' test_node = env.CreatePythonUnitTest(file, **kwargs) env.AddNodeToTestSuite(test_node, ['bot'], command, size) return test_node AddPythonUnitTest('run_build_utils_test', 'tests/build_utils_test.py') AddPythonUnitTest('run_tar_archive_test', 'tests/tar_archive_test.py') AddPythonUnitTest('run_update_manifest_test', 'tests/update_manifest_test.py', size='medium') AddPythonUnitTest('run_sdk_update_test', 'tests/sdk_update_test.py') AddPythonUnitTest('run_set_nacl_env_test', 'tests/set_nacl_env_test.py', dependencies=[env.GetToolchainNode()]) AddPythonUnitTest('run_installer_contents_test', 'tests/installer_contents_test.py') AddPythonUnitTest('run_nacl_utils_test', 'nacl_sdk_scons/nacl_utils_test.py') AddPythonUnitTest('run_path_set_test', 'tests/path_set_test.py') AddPythonUnitTest('run_apply_patch_test', 'tests/apply_patch_test.py') AddPythonUnitTest('run_nmf_test', 'nacl_sdk_scons/nmf_test.py', size='medium', dependencies=[env.GetToolchainNode()], params=['--toolchain-dir=%s' % env['NACL_TOOLCHAIN_ROOTS'][('x86', 'glibc')]]) AddPythonUnitTest('run_html_check_test', 'html_checker.py', params=[os.path.join(env['ROOT_DIR'], 'examples', name) for name in ['index.html', 'index_staging.html']]) if env['IS_WINDOWS']: AddPythonUnitTest('run_install_nsis_test', 'tests/install_nsis_test.py') AddPythonUnitTest('run_nsis_script_test', 'tests/nsis_script_test.py') #------------------------------------------------------------------------------ # Put together the toolchain import gyp_extract import re def GypSources(gyp_data, pattern): """Extract a sources from a target matching a given pattern. Args: gyp_data: list containing sources from gyp file. pattern: re pattern that sources must match. Returns: A list of strings containing source filenames. """ # Extract source files that match. re_compiled = re.compile(pattern) return [source_file for source_file in gyp_data if re_compiled.match(source_file)] ppapi_base = os.path.join(env['SRC_DIR'], 'ppapi') # Unfortunately gyp_extract does not handle variables or includes so we must # pull the list of sources from ppapi_sources.gypi directly. ppapi_sources_gypi = open(os.path.join(ppapi_base, 'ppapi_sources.gypi'), 'r').read() ppapi_sources_map = eval(ppapi_sources_gypi)['variables'] # Load ppapi_cpp.gypi ppapi_cpp_gypi = gyp_extract.LoadGypFile(os.path.join(ppapi_base, 'ppapi_cpp.gypi')) # Load ppapi_gl.gypi ppapi_gl_gypi = gyp_extract.LoadGypFile(os.path.join(ppapi_base, 'ppapi_gl.gypi')) # From ppapi_cpp.gypi:ppapi_c:c/[^/]*\.h c_headers = GypSources(ppapi_sources_map['c_source_files'], 'c/[^/]*\.h') # From ppapi_cpp.gypi:ppapi_c:c/dev/[^/]*\.h c_dev_headers = GypSources(ppapi_sources_map['c_source_files'], 'c/dev/[^/]*\.h') # From ppapi_cpp.gypi:ppapi_cpp_objects:cpp/[^/]*\.h # From ppapi_cpp.gypi:ppapi_cpp:cpp/[^/]*\.h cpp_headers = ( GypSources(ppapi_sources_map['cpp_source_files'], 'cpp/[^/]*\.h') + gyp_extract.GypTargetSources( ppapi_cpp_gypi, 'ppapi_cpp', 'cpp/[^/]*\.h') ) # From ppapi_cpp.gypi:ppapi_cpp_objects:cpp/dev/[^/]*\.h cpp_dev_headers = GypSources(ppapi_sources_map['cpp_source_files'], 'cpp/dev/[^/]*\.h') # From ppapi_gl.gypi:ppapi_gles2:.*\.h gles2_headers = gyp_extract.GypTargetSources( ppapi_gl_gypi, 'ppapi_gles2', '.*\.h') c_header_install = env.AddHeaderToSdk( [os.path.join(ppapi_base, h) for h in c_headers], os.path.join('ppapi', 'c')) c_dev_header_install = env.AddHeaderToSdk( [os.path.join(ppapi_base, h) for h in c_dev_headers], os.path.join('ppapi', 'c', 'dev')) cpp_header_install = env.AddHeaderToSdk( [os.path.join(ppapi_base, h) for h in cpp_headers], os.path.join('ppapi', 'cpp')) cpp_dev_header_install = env.AddHeaderToSdk( [os.path.join(ppapi_base, h) for h in cpp_dev_headers], os.path.join('ppapi', 'cpp', 'dev')) # TODO(dspringer): Remove these lines when trusted ppapi builds are no longer # needed for debugging. # -------- 8< Cut here -------- # From ppapi_cpp.gypi:ppapi_cpp_objects:cpp/[^/]*\.cc # From ppapi_cpp.gypi:ppapi_cpp:cpp/[^/]*\.cc cpp_trusted_sources = ( GypSources(ppapi_sources_map['cpp_source_files'], 'cpp/[^/]*\.cc') + gyp_extract.GypTargetSources( ppapi_cpp_gypi, 'ppapi_cpp', 'cpp/[^/]*\.cc') ) cpp_trusted_source_install = env.AddHeaderToSdk( [os.path.join(ppapi_base, cpp) for cpp in cpp_trusted_sources], subdir=os.path.join('ppapi', 'cpp'), base_dirs=[os.path.join(env['ROOT_DIR'], 'third_party')]) # -------- 8< Cut here -------- #env.AddLibraryToSdk(['ppapi_cpp']) env.Requires('ppapi_cpp', [c_header_install, c_dev_header_install, cpp_header_install, cpp_dev_header_install, # TODO(dspringer): Remove this when trusted ppapi # builds are no longer needed. cpp_trusted_source_install]) # GLES2 headers go into the GLES2 subdir, Khronos headers into the KHR subdir, # EGL header go in the EGL subdir. gl_base = os.path.join(ppapi_base, 'lib', 'gl', 'include') egl_base = os.path.join(gl_base, 'EGL') egl_header_install = env.AddHeaderToSdk([ os.path.join(egl_base, 'egl.h'), os.path.join(egl_base, 'eglext.h'), os.path.join(egl_base, 'eglplatform.h'), ], 'EGL') gles2_base = os.path.join(gl_base, 'GLES2') gles2_header_install = env.AddHeaderToSdk([ os.path.join(gles2_base, 'gl2.h'), os.path.join(gles2_base, 'gl2ext.h'), os.path.join(gles2_base, 'gl2platform.h'), ], 'GLES2') khr_header_install = env.AddHeaderToSdk([ os.path.join(gl_base, 'KHR', 'khrplatform.h'), ], 'KHR') ppapi_gles2_header_install = env.AddHeaderToSdk( [os.path.join(ppapi_base, h) for h in gles2_headers], os.path.join('ppapi', 'gles2')) #env.AddLibraryToSdk(['ppapi_gles2']) env.Requires('ppapi_gles2', [ egl_header_install, gles2_header_install, khr_header_install, ppapi_gles2_header_install, ]) #------------------------------------------------------------------------------ # Build Native Client components that are not included in the toolchain zip def build_nacl_tools(env, target, source): ''' Tool for running make_nacl_tools This builds sel_ldr, ncval, and the nacl libraries''' build_utils.BotAnnotator().BuildStep('build NaCl tools') for key, toolchain in env['NACL_TOOLCHAIN_ROOTS'].items(): (_, variant) = key make_nacl_tools_args = [ '--toolchain', toolchain, '--jobs', env['JOB_COUNT'], '--nacl_dir', env['SRC_DIR'], ] if env.GetOption('clean'): make_nacl_tools_args.extend(['--clean']) args = make_nacl_tools_args + ['--lib=%s' % variant] print 'Running make_nacl_tools with ', args sys.stdout.flush() make_nacl_tools.main(args) exe = '.exe' if sys.platform in ['cygwin', 'win32'] else '' tools = [ os.path.join('bin', 'sel_ldr_x86_32%s' % exe), os.path.join('bin', 'sel_ldr_x86_64%s' % exe), os.path.join('bin', 'ncval_x86_32%s' % exe), os.path.join('bin', 'ncval_x86_64%s' % exe), os.path.join('runtime', 'irt_core_x86_32.nexe'), os.path.join('runtime', 'irt_core_x86_64.nexe'), ] all_tools = [] for dir in env['NACL_TOOLCHAIN_ROOTS'].values(): all_tools += [os.path.join(dir, tool) for tool in tools] nacl_tools_cmd = env.Command(all_tools, ['make_nacl_tools.py', os.path.join(env['SRC_DIR'], 'DEPS')], build_nacl_tools) env.Depends(nacl_tools_cmd, env.GetHeadersNode()) env.Depends(env.GetToolchainNode(), nacl_tools_cmd) env.AddCleanAction([], build_nacl_tools, ['toolchain', 'bot'], nacl_tools_cmd)