def main(self, argv): # self._print_env() (params, cmake_argv) = self._parse_command_line(argv) if params.install_dir: top_dir = util.get_top_dir() os.chdir(top_dir) script_dir = util.get_script_dir() # print("sys.path: ", sys.path) script_installer = BuildScriptInstaller(verbose=True) script_installer.install_script( params.install_dir, os.path.join(script_dir, 'cmake.py'), self._cmake_mod_list) elif params.py_cache_dirs: for dname in params.py_cache_dirs: if not os.path.exists(dname): continue if not os.path.isdir(dname): continue self._remove_pycache(dname) else: # Apply additional checks on params. self._check_params(params) if self._sys_info.is_linux() or self._sys_info.is_macosx(): self._remove_make_env_vars() # Delayed construction to get the current log level at construction time of CMakeLauncher. self._cmake_launcher = cmksupp.CMakeLauncher() self._cmake_launcher.launch(params, cmake_argv)
def get_test_data_top_dir(): """Returns the default test data directory based on the script directory avoiding hardcoded paths while switching between BoostBuild and CMakeBuild.""" script_dir_up = os.path.normpath(os.path.join(util.get_script_dir(), '..')) repo_name = os.path.basename(script_dir_up) # repo_name: either BoostBuild or CMakeBuild top_dir = util.get_top_dir() test_data_dir = os.path.join(top_dir, 'TestData', repo_name) assert os.path.exists(test_data_dir) return test_data_dir
def main(self, argv): # self._print_env() (params, cmake_argv) = self._parse_command_line(argv) if params.install_dir: top_dir = util.get_top_dir() os.chdir(top_dir) script_dir = util.get_script_dir() script_installer = BuildScriptInstaller(top_dir, verbose=True) #if ver.version_compare(self._sys_info.get_python_version(), (3, 0)) >= 0: # script_installer.install_script(params.install_dir, os.path.join(script_dir, 'cmake3.py'), self._cmake_mod_list, rename='cmake.py') #else: # script_installer.install_script(params.install_dir, os.path.join(script_dir, 'cmake.py'), self._cmake_mod_list) script_installer.install_script( params.install_dir, os.path.join(script_dir, 'cmake.py'), self._cmake_mod_list) else: # Apply additional checks on params. self._check_params(params) if self._sys_info.is_linux() or self._sys_info.is_macosx(): self._remove_make_env_vars() # Delayed construction to get the current log level at construction time of CMakeLauncher. self._cmake_launcher = cmksupp.CMakeLauncher() self._cmake_launcher.launch(params, cmake_argv)
def __call__(self): parser = argparse.ArgumentParser() util.app_args_add_log_level(parser) parser.add_argument( "-v", action="store", type=int, dest="verbosity_level", default=2, help= "change the default verbosity level of the python unit test framework." ) parser.add_argument("--with-android", action="store_true", dest="with_android", default=False, help="include android tests.") parser.add_argument("--with-cuda", action="store_true", dest="with_cuda", default=False, help="include android tests.") parser.add_argument("--with-vlc", action="store_true", dest="with_vlc", default=False, help="include VLC tests.") parser.add_argument("--with-all", action="store_true", dest="with_all", default=False, help="include all optional tests.") parser.add_argument( "unit_tests", action="store", nargs='*', help= "specify one or more unit tests to run. By default all tests will be run." ) args = parser.parse_args() # configure the python logger asap util.app_configure_logging(args.log_level) # print("verbosity_level:", args.verbosity_level) # get the workspace top_dir = util.get_top_dir() # change to top_dir os.chdir(top_dir) # get the boost build script directory script_dir = util.get_script_dir() test_loader = unittest.TestLoader() # All unit tests live in the package bb.test test_package_prefix = 'pyhhi.build.test' py_module_nm_list = [] if args.unit_tests: # One or more test modules are specified. for arg in args.unit_tests: if arg.startswith('test_'): py_module_nm_list.append(arg) else: py_module_nm_list.append('test_' + arg) else: # Construct the default test suite containing all test modules. # test_suite = test_loader.discover(test_package_prefix, 'test_*.py') for file in glob.glob( os.path.join(script_dir, 'pyhhi', 'build', 'test', 'test_*.py')): (py_module_nm, ext) = os.path.splitext(os.path.basename(file)) py_module_nm_list.append(py_module_nm) for file in glob.glob( os.path.join(script_dir, 'pyhhi', 'cmbuild', 'test', 'test_*.py')): (py_module_nm, ext) = os.path.splitext(os.path.basename(file)) py_module_nm_list.append(py_module_nm) py_module_nm_list = self._filter_module_list( args, py_module_nm_list) test_module_names = [] for prefix in ['pyhhi.build.test', 'pyhhi.cmbuild.test']: #prefix_path = os.path.join(script_dir, prefix.split('.')) prefix_path = os.path.join(script_dir, prefix.replace('.', os.sep)) for py_module_nm in py_module_nm_list: if os.path.exists( os.path.join(prefix_path, py_module_nm + '.py')): test_module_names.append(prefix + '.' + py_module_nm) #test_module_names = [test_package_prefix + '.' + x for x in py_module_nm_list] print("test module list: ", test_module_names) test_suite = test_loader.loadTestsFromNames(test_module_names) # and run tests ... test_runner = unittest.TextTestRunner(verbosity=args.verbosity_level) test_runner.run(test_suite)
def cmakebuild_update(self, params): initial_work_dir = os.getcwd() # (Re)create GitHelper in case the log level has been changed. self._git_helper = vcsutil.GitHelper() params = self._check_params(params) if params.top_dir is None: params.top_dir = util.get_top_dir() self._summary_lines = [] if params.update_prepare: print("{}: preparing CMakeBuild update ...".format(self._prog_name)) cmakebuild_version_current = self._get_current_cmakebuild_version(params.top_dir) if cmakebuild_version_current is None: print("{}: no existing CMakeBuild version found.".format(params.top_dir)) if not self._is_workspace_clean(params.top_dir): return if params.cmakebuild_tag is None: cmakebuild_tag = self._git_helper.get_latest_cmakebuild_tag(params.cmakebuild_repo) if cmakebuild_version_current and (ver.version_compare(cmakebuild_version_current, ver.version_tuple_from_str(cmakebuild_tag)) == 0): print("{}: CMakeBuild is up to date, nothing to be done.".format(params.top_dir)) return else: # Validate CMakeBuild tag cmakebuild_tags = self._git_helper.get_remote_tags(params.cmakebuild_repo) if params.cmakebuild_tag not in cmakebuild_tags: raise InvalidInputParameterError("requested tag {0} does not exists in {1}.".format(params.cmakebuild_tag, params.cmakebuild_repo)) cmakebuild_tag = params.cmakebuild_tag if cmakebuild_version_current and (ver.version_compare(ver.version_tuple_from_str(cmakebuild_tag), cmakebuild_version_current) <= 0): print("{}: CMakeBuild is up to date, nothing to be done.".format(params.top_dir)) return install_dir = os.path.join(params.top_dir, 'build', 'cmakebuild_update') self._install_self(install_dir) update_script = os.path.join(install_dir, self._prog_name) # Prepare execv argument vector to call self with different arguments using the current python executable. if self._sys_info.is_windows(): child_args = [self._sys_info.get_short_path(self._sys_info.get_python_executable())] else: child_args = [self._sys_info.get_python_executable()] child_args.extend([update_script, '--update']) if cmakebuild_tag: child_args.extend(['-t', cmakebuild_tag]) if params.cmakebuild_repo: child_args.extend(['--cmakebuild-repo', params.cmakebuild_repo]) # Add currrent log option to child_args[] to propagate the current log option to the child process. log_level = self._logger.getEffectiveLevel() log_level_str = None if log_level == logging.DEBUG: log_level_str = 'debug' elif log_level == logging.INFO: log_level_str = 'info' elif log_level == logging.WARNING: log_level_str = 'warning' elif log_level == logging.ERROR: log_level_str = 'error' elif log_level == logging.CRITICAL: log_level_str = 'critical' if log_level_str is not None: child_args.append('--log={}'.format(log_level_str)) child_args.append(params.top_dir) os.chdir(params.top_dir) if self._sys_info.is_windows(): # Unfortunately, there are issues with os.execv() on Windows and therefore a subprocess call is used instead. util.subproc_check_call_flushed(child_args) else: # execv() is preferred as the child is likely to remove python files just being executed # by the current python process. os.execv(child_args[0], child_args) else: try: print("{}: updating CMakeBuild in {} to {}".format(self._prog_name, params.top_dir, params.cmakebuild_tag)) os.chdir(params.top_dir) if not self._is_workspace_clean(): return self._append_item_to_summary("Git workspace:", params.top_dir) if self._list_summary: cmakebuild_version_current = self._get_current_cmakebuild_version(params.top_dir) if cmakebuild_version_current is not None: self._append_item_to_summary("Current CMakeBuild version:", "{}-{:d}".format(ver.version_tuple_to_str(cmakebuild_version_current[:3]), cmakebuild_version_current[-1])) self._append_item_to_summary("New CMakeBuild version:", params.cmakebuild_tag) # Inventory of CMakeBuild to remember existing directories to be removed later on. (git_cmakebuild_dirs, cmakebuild_dirs) = self._get_git_cmakebuild_dirs(params.top_dir) if params.cmakebuild_tag in git_cmakebuild_dirs: git_cmakebuild_dirs.remove(params.cmakebuild_tag) if params.cmakebuild_tag in cmakebuild_dirs: cmakebuild_dirs.remove(params.cmakebuild_tag) # print("found existing Git CMakeBuild subdirs:", git_cmakebuild_dirs) # print("found existing CMakeBuild subdirs:", cmakebuild_dirs) # Add new CMakeBuild subtree self._add_cmakebuild_to_git_repo(params.cmakebuild_tag, params.cmakebuild_repo) # Update .svnimportprops in case is does exist. svnimportprops_file = os.path.join(params.top_dir, '.svnimportprops') svnimportprops_modified = self._update_svnimportprops(svnimportprops_file, params.cmakebuild_tag) for dname in git_cmakebuild_dirs: git_argv = [self._git_executable, 'rm', '-r', os.path.join('CMakeBuild', dname)] util.subproc_check_call_flushed(git_argv) if svnimportprops_modified or git_cmakebuild_dirs: # Need a git commit if '.svnimportprops' has been updated or git rm -r has been launched. git_comment = [] if git_cmakebuild_dirs: git_comment.append("rm -r CMakeBuild/{}".format(','.join(git_cmakebuild_dirs))) if svnimportprops_modified: git_comment.append("modifying {}".format('.svnimportprops')) git_argv = [self._git_executable, 'commit', '-am', '{}: {}'.format(self._prog_name, ', '.join(git_comment))] util.subproc_check_call_flushed(git_argv) # Check again to get rid of any python cache files cmakebuild_dirs.extend(git_cmakebuild_dirs) for dname in cmakebuild_dirs: dname_path = os.path.join(params.top_dir, 'CMakeBuild', dname) if os.path.exists(dname_path): util.rmtree(dname_path) print("{}: finished updating CMakeBuild in {} to {}".format(self._prog_name, params.top_dir, params.cmakebuild_tag)) if self._list_summary: print("\n{0:^80}".format("Summary")) print("{0:^80}".format("=======")) for line in self._summary_lines: print(line) finally: pass os.chdir(initial_work_dir)
def build_boost(self, build_params): #print("BoostBuilder.build_boost() starting ...") # extract the boost version boost_version = get_boost_version(build_params.boost_dir) self._boost_version = boost_version # print("BoostBuilder: boost version:", boost_version) # check the boost version against the minimal version we support if ver.version_compare(boost_version, self._min_boost_version) < 0: raise Exception( "The boost version " + ver.version_tuple_to_str(boost_version) + " is not supported anymore, please contact technical support.") # construct a new toolset toolset = bldtools.Toolset(self._sys_info, build_params.toolset, build_params.cxx_runtime) self._toolset = toolset if toolset.get_toolset() == 'intel': if self._sys_info.is_windows(): # Update MSVC environment to be used with the Intel compiler if build_params.msvc_rt is None: # Use latest MSVC by default msvc_registry = bldtools.MsvcRegistry() msvc_version = msvc_registry.get_latest_version() build_params.msvc_rt = "msvc-%d.%d" % (msvc_version[0], msvc_version[1]) # self._intel_msvc_suffix = self._intel_msvc_suffix_dict[ build_params.msvc_rt] elif self._sys_info.is_macosx(): if ver.version_compare(boost_version, (1, 66, 0)) == 0: # Is intel-darwin.jam patched? intel_darwin_boost = os.path.join(build_params.boost_dir, 'tools', 'build', 'src', 'tools', 'intel-darwin.jam') intel_darwin_patched = os.path.join( util.get_top_dir(), 'CMakeBuild', 'patches', 'Boost', ver.version_tuple_to_str(boost_version), 'tools', 'build', 'src', 'tools', 'intel-darwin.jam') assert os.path.exists(intel_darwin_boost) assert os.path.exists(intel_darwin_patched) if not filecmp.cmp(intel_darwin_boost, intel_darwin_patched, shallow=False): raise Exception( """intel-darwin.jam requires a patch. Consider a manual update: cp %s %s or contact technical support. """ % (intel_darwin_patched, intel_darwin_boost)) platform_info = toolset.get_platform_info(build_params.platform_index) if (platform_info.get_target_os() == 'macosx') and (build_params.macosx_version_min is None): # At times Xcode ships with OSX SDK version > macosx version, this is not permitted by default. if ver.version_compare(platform_info.get_sdk_version(), self._sys_info.get_os_version()) > 0: build_params.macosx_version_min = self._sys_info.get_os_version( )[:2] # check the optional target if build_params.targets: for target in build_params.targets: if target not in platform_info.get_target_arch(): raise Exception( "The target " + target + " is not supported. Please check target and toolset.") else: # no target(s) specified, use the defaults if toolset.get_toolset() == 'msvc': build_params.targets = list(platform_info.get_target_arch()) elif platform_info.get_target_os() in [ 'iphone', 'iphonesimulator' ]: if build_params.macosx_version_min: target_os_version = build_params.macosx_version_min else: target_os_version = platform_info.get_target_os_version() if ver.version_compare(target_os_version, (11, 0)) >= 0: # No support for 32 bit IOS targets anymore. if platform_info.get_target_os() == 'iphone': build_params.targets = ['arm64'] elif platform_info.get_target_os() == 'iphonesimulator': build_params.targets = ['x86_64'] else: assert False else: if platform_info.get_target_os() == 'iphone': build_params.targets = ['arm64', 'armv7'] elif platform_info.get_target_os() == 'iphonesimulator': build_params.targets = ['x86_64', 'x86'] else: assert False else: build_params.targets = [platform_info.get_target_arch(0)] # update the build parameters given the attributes of the toolset. self._update_build_params(toolset, build_params) #print(build_params) #return boost_lib_files_missing = False lib_dir_list = [] if build_params.rebuild_all: boost_lib_files_missing = True if not build_params.dry_run: for target in build_params.targets: if platform_info.get_target_os() == 'windows': bin_dir = self.get_boost_bin_dir( build_params.boost_dir, toolset, build_params.platform_index, target) if os.path.exists(bin_dir): shutil.rmtree(bin_dir) lib_dir = self.get_boost_lib_dir( build_params.boost_dir, toolset, build_params.platform_index, target) lib_dir_list.append(lib_dir) if os.path.exists(lib_dir): shutil.rmtree(lib_dir) else: for target in build_params.targets: lib_dir = self.get_boost_lib_dir(build_params.boost_dir, toolset, build_params.platform_index, target) lib_dir_list.append(lib_dir) if not os.path.exists(lib_dir): boost_lib_files_missing = True if boost_lib_files_missing: self._build_libs(boost_version, toolset, build_params) if not build_params.dry_run: if self._sys_info.is_macosx(): if len(build_params.targets) > 1: # create a fat binary/universal library file fat_binary_tool = bldtools.FatBinaryTool() platform_info = toolset.get_platform_info( build_params.platform_index) assert ((platform_info.get_target_os() == 'iphone') or (platform_info.get_target_os() == 'iphonesimulator')) src_lib_dirs = [] for target in build_params.targets: lib_dir = self.get_boost_lib_dir( build_params.boost_dir, toolset, build_params.platform_index, target) src_lib_dirs.append(lib_dir) dst_lib_dir = self.get_boost_lib_dir( build_params.boost_dir, toolset, build_params.platform_index, 'combined') if os.path.exists(dst_lib_dir): shutil.rmtree(dst_lib_dir) fat_binary_tool.createLibs(src_lib_dirs, dst_lib_dir) # if ver.version_compare( (1, 59, 0), self._boost_version) > 0: platform_info = toolset.get_platform_info( build_params.platform_index) if platform_info.get_target_os() == 'macosx': lib_dir = self.get_boost_lib_dir( build_params.boost_dir, toolset, build_params.platform_index, build_params.targets[0]) print( "Checking install names and dependencies in " + lib_dir) dylib_list = glob.glob(lib_dir + '/*.dylib') inst_name_inspector = bldtools.DyLibInstallNameInfoInspector( ) for dylib in dylib_list: inst_name_info = inst_name_inspector.create_install_name_info( dylib) if not inst_name_info.inst_name.startswith( '@rpath/'): inst_name_inspector.modify_install_name( dylib, os.path.join('@rpath', inst_name_info.basename)) # Walk the dependency list and change all boost libraries from libboost_NNN.dylib to @rpath/libboost_NNN.dylib. depends_dict = {} for libname in inst_name_info.depends_list: if libname.startswith('libboost_'): depends_dict[ libname] = os.path.join( '@rpath', libname) if depends_dict: print("Changing dependencies of " + os.path.basename(dylib)) inst_name_inspector.modify_depends( dylib, depends_dict) print("\n") print( "-------------------- Post build phase --------------------" ) for lib_dir in lib_dir_list: self._list_boost_components(lib_dir) print( "----------------------------------------------------------" ) else: print( "No boost library directories are missing, skipping library build step." ) print("Use --rebuild if you intend to rebuild all libraries.")
def main(self, argv): (boost_build_params, boost_dir, cxx_std) = self._parse_command_line(argv) # Change the current working directory to the top level directory in case the caller has moved # into CMakeBuild or bin to invoke boost_install.py. top_dir = util.get_top_dir() os.chdir(top_dir) msg_list_summary = [] msg_list_summary.append('%-25s %s' % ('python version:', ver.version_tuple_to_str(self._sys_info.get_python_version()))) msg_list_summary.append('%-25s %s' % ('python executable:', self._sys_info.get_python_executable())) msg_list_summary.append('%-25s %s' % ('platform:', self._sys_info.get_platform_long())) msg_list_todo = [] self._sys_info.check_os_detection(msg_list_todo) if boost_dir is None: print("boost_install.py: no boost directory specified, use option --boost-dir.") sys.exit(1) else: boost_build_params.boost_dir = boost_dir if boost_build_params.boost_dir.startswith('/usr/include'): # system layout -> don't try to build the boost SDK and just extract the boost version msg_list_summary.append('%-25s %s' % ('boost version:', ver.version_tuple_to_str(boostbld.get_boost_version(boost_build_params.boost_dir)))) else: # create the BoostBuilder boost_builder = boostbld.BoostBuilder(self._sys_info) if cxx_std: boost_build_params.cxx_std = cxx_std else: re_match = re.match(r'.*-(c\+\+[0-9]+)$', boost_dir) if re_match: boost_build_params.cxx_std = re_match.group(1) else: boost_build_params.cxx_std = 'c++11' # launch Boost building with the current set of build options. boost_builder.build_boost(boost_build_params) # compose the summary msg_list_summary.append('%-25s %s' % ('boost root:', boost_dir)) msg_list_summary.append('%-25s %s' % ('boost version:', ver.version_tuple_to_str(boost_builder.get_boost_version()))) if boost_build_params.targets: msg_list_summary.append('%-25s %s' % ('boost toolset:', boost_builder.get_toolset().get_toolset_info_short(boost_build_params.targets[0]))) bjam_cmd_lines = boost_builder.get_bjam_cmd_lines() if bjam_cmd_lines: msg_list_summary.append('bjam command(s):') msg_list_summary.extend(boost_builder.get_bjam_cmd_lines()) if msg_list_summary: print() print(" SUMMARY ") print(" ======= ") print() for msg in msg_list_summary: print(msg) print() if msg_list_todo: print("\nTODO List:") for msg in msg_list_todo: print(msg) print() print("boost_install.py finished successfully.\n")