def create_pkg_config_path_environment_hooks(basepath, pkg_name): """ Create hook scripts to prepend to the PKG_CONFIG_PATH. :param Path basepath: The path of the prefix :param str pkg_name: The package name :returns: The relative paths to the created hook scripts :rtype: list """ hooks = create_environment_hook('pkg_config_path', basepath, pkg_name, 'PKG_CONFIG_PATH', os.path.join('lib', 'pkgconfig'), mode='prepend') if platform.system() == 'Linux': multiarch = get_multiarch() if multiarch: hooks += create_environment_hook('pkg_config_path_multiarch', basepath, pkg_name, 'PKG_CONFIG_PATH', os.path.join( 'lib', multiarch, 'pkgconfig'), mode='prepend') return hooks
async def build(self): # noqa: D102 args = self.context.args logger.info( "Building ROS package in '{args.path}' with build type 'catkin'". format_map(locals())) # reuse CMake build task with additional logic extension = CmakeBuildTask() extension.set_context(context=self.context) # additional arguments if args.cmake_args is None: args.cmake_args = [] args.cmake_args += ['-DCATKIN_INSTALL_INTO_PREFIX_ROOT=0'] if args.test_result_base: # catkin appends the project name itself args.cmake_args.append('-DCATKIN_TEST_RESULTS_DIR=' + os.path.dirname(args.test_result_base)) if args.catkin_cmake_args: args.cmake_args += args.catkin_cmake_args # additional hooks additional_hooks = create_environment_hook('ros_package_path', Path(args.install_base), self.context.pkg.name, 'ROS_PACKAGE_PATH', 'share', mode='prepend') # for catkin packages add additional hooks after the package has # been built and installed depending on the installed files rc = await extension.build(skip_hook_creation=True) # add Python 2 specific path to PYTHONPATH if it exists if os.environ.get('ROS_PYTHON_VERSION', '2') == '2': for subdirectory in ('dist-packages', 'site-packages'): python_path = Path(args.install_base) / \ 'lib' / 'python2.7' / subdirectory logger.log(1, "checking '%s'" % python_path) if python_path.exists(): rel_python_path = python_path.relative_to( args.install_base) additional_hooks += create_environment_hook( 'python2path', Path(args.install_base), self.context.pkg.name, 'PYTHONPATH', str(rel_python_path), mode='prepend') create_environment_scripts(self.context.pkg, args, additional_hooks=additional_hooks) # ensure that the install base has the marker file # identifying it as a catkin workspace marker = Path(args.install_base) / '.catkin' marker.touch(exist_ok=True) return rc
async def build(self, *, additional_hooks=[], skip_hook_creation=False): # noqa: D102 pkg = self.context.pkg args = self.context.args logger.info("Building Cargo package in '{args.path}'".format_map( locals())) try: env = await get_command_environment('build', args.build_base, self.context.dependencies) except RuntimeError as e: logger.error(str(e)) return 1 rc = await self._build(args, env) if rc and rc.returncode: return rc.returncode additional_hooks += create_environment_hook( 'cargo_{}_path'.format(pkg.name), Path(args.install_base), pkg.name, 'PATH', os.path.join('lib', self.context.pkg.name, 'bin'), mode='prepend') if not skip_hook_creation: create_environment_scripts(pkg, args, additional_hooks=additional_hooks)
def create_environment_hooks(self, prefix_path, pkg_name): # noqa: D102 hooks = OrderedDict() logger.log(1, "checking '%s' for CMake module files" % prefix_path) for path in self._get_potential_cmake_module_paths( prefix_path, pkg_name): if not path.is_dir(): continue # skip paths which are the same but only differ in case if any(path.samefile(p) for p in hooks.keys()): continue for filename in path.iterdir(): if not filename.is_file(): continue if (filename.name.startswith('Find') and filename.name.endswith('.cmake')): hooks[path] = create_environment_hook( 'cmake_module_path' + (str(len(hooks)) if hooks else ''), prefix_path, pkg_name, 'CMAKE_MODULE_PATH', str(path.relative_to(prefix_path)), mode='prepend') return hooks.values()
async def test(self): # noqa: D102 args = self.context.args logger.info( "Testing ROS package in '{args.path}' with build type 'catkin'". format_map(locals())) # for catkin packages it is expected that the devel space # and not the install space is in the environment for testing self.context.dependencies[self.context.pkg.name] = \ os.path.join(self.context.args.build_base, 'devel') # additional hooks additional_hooks = create_environment_hook('ros_package_path', Path(args.build_base) / 'devel', self.context.pkg.name, 'ROS_PACKAGE_PATH', args.path, mode='prepend') additional_hooks += create_pythonpath_environment_hook( Path(args.build_base) / 'devel', self.context.pkg.name) # generate the necessary setup files for the devel space create_environment_scripts_only(Path(args.build_base) / 'devel', self.context.pkg, additional_hooks=additional_hooks) # reuse CMake test task extension = CmakeTestTask() extension.set_context(context=self.context) return await extension.test()
def create_environment_hooks(self, prefix_path, pkg_name): # noqa: D102 LibraryDescriptor = namedtuple( 'LibraryDescriptor', ['hook_name', 'subdirectory', 'extension', 'environment_variable']) if sys.platform == 'win32': library_descriptors = [ LibraryDescriptor('path_dll', 'bin', 'dll', 'PATH') ] elif platform.system() == 'Darwin': library_descriptors = [ LibraryDescriptor( 'dyld_library_path', 'lib', 'dylib', 'DYLD_LIBRARY_PATH')] else: library_descriptors = [ LibraryDescriptor( 'ld_library_path_{directory.name}'.format_map(locals()), directory.name, 'so', 'LD_LIBRARY_PATH') for directory in prefix_path.glob('lib*')] environment_hooks = [] for library_descriptor in library_descriptors: library_path = prefix_path / library_descriptor.subdirectory logger.log(1, "checking '%s'" % library_path) if any(library_path.glob('*.' + library_descriptor.extension)): environment_hooks += create_environment_hook( library_descriptor.hook_name, prefix_path, pkg_name, library_descriptor.environment_variable, library_descriptor.subdirectory, mode='prepend') return environment_hooks
async def build(self): # noqa: D102 args = self.context.args logger.info("Building ROS package in '{args.path}' with build type " "'ament_python'".format_map(locals())) # reuse Python build task with additional logic extension = PythonBuildTask() extension.set_context(context=self.context) # additional hooks additional_hooks = create_environment_hook('ament_prefix_path', Path(args.install_base), self.context.pkg.name, 'AMENT_PREFIX_PATH', '', mode='prepend') # create package marker in ament resource index create_file( args, 'share/ament_index/resource_index/packages/{self.context.pkg.name}' .format_map(locals())) # copy / symlink package manifest install( args, 'package.xml', 'share/{self.context.pkg.name}/package.xml'.format_map(locals())) return await extension.build(additional_hooks=additional_hooks)
def create_pythonpath_environment_hook(build_base, install_base, pkg_name): """ Create a hook script for each primary shell to prepend to the PYTHONPATH. :param str build_base: The path of the build directory :param Path install_base: The path of the install prefix :param str pkg_name: The package name :returns: The relative paths to the created hook scripts :rtype: list """ hooks = [] # catkin packages might use `--install-layout deb` # therefore getting the used install directory from the CMake cache # since it might not match distutils.sysconfig.get_python_lib() rel_python_path = get_variable_from_cmake_cache(build_base, 'PYTHON_INSTALL_DIR') # prepend Python specific path to PYTHONPATH if it exists if rel_python_path: abs_python_path = install_base / rel_python_path logger.log(1, "checking '%s'" % abs_python_path) if abs_python_path.exists(): hooks += create_environment_hook('catkin_pythonpath', install_base, pkg_name, 'PYTHONPATH', rel_python_path, mode='prepend') return hooks
def create_environment_hooks(self, prefix_path, pkg_name): # noqa: D102 subdirectory = Path('lib') / 'pkgconfig' pkg_config_file = prefix_path / subdirectory / (pkg_name + '.pc') logger.log(1, "checking '%s'" % pkg_config_file) if not pkg_config_file.is_file(): return [] return create_environment_hook('pkg_config', prefix_path, pkg_name, 'PKG_CONFIG_PATH', str(subdirectory), mode='prepend')
def create_environment_hooks(self, prefix_path, pkg_name): # noqa: D102 hooks = [] python_path = Path(get_python_lib(prefix=str(prefix_path))) logger.log(1, "checking '%s'" % python_path) if python_path.exists(): rel_python_path = python_path.relative_to(prefix_path) hooks += shell.create_environment_hook( 'pythonpath', prefix_path, pkg_name, 'PYTHONPATH', str(rel_python_path), mode='prepend') return hooks
def test_create_environment_hook(): with EntryPointContext(extension1=Extension1, extension2=Extension2): # no primary shell extension with pytest.raises(RuntimeError) as e: create_environment_hook(None, None, None, None, None) assert str(e.value).endswith( 'Could not find a primary shell extension for creating an ' 'environment hook') with EntryPointContext(extension3=Extension3, extension4=Extension4, extension5=Extension5): extensions = get_shell_extensions() # one invalid, two valid return values extensions[105]['extension3'].create_hook_prepend_value = Mock() extensions[101]['extension4'].create_hook_prepend_value = Mock( return_value=Path('/some/path/sub/hookA')) extensions[110]['extension5'].create_hook_prepend_value = Mock( return_value=Path('/some/path/sub/hookB')) with patch('colcon_core.shell.logger.error') as error: hooks = create_environment_hook(None, None, None, None, None) assert len(hooks) == 2 assert str(hooks[0]) == '/some/path/sub/hookB'.replace('/', os.sep) assert str(hooks[1]) == '/some/path/sub/hookA'.replace('/', os.sep) # the raised exception is catched and results in an error message assert error.call_count == 1 assert len(error.call_args[0]) == 1 assert error.call_args[0][0].startswith( "Exception in shell extension 'extension3': " 'create_hook_prepend_value() should return a Path object') # invalid mode with pytest.raises(NotImplementedError): create_environment_hook(None, None, None, None, None, mode='invalid')
def create_environment_hooks(self, prefix_path: Path, pkg_name: str): # noqa D102 hooks = [] dub_path = prefix_path / 'lib' / 'dub' / pkg_name dub_package = DubPackage.load(dub_path) logger.log(1, "checking '%s'" % dub_path) if dub_package: hooks += shell.create_environment_hook('dub_package_path', prefix_path, pkg_name, DUB_PACKAGE_PATH_ENV, str(dub_package.path), mode='prepend') return hooks
def create_environment_hooks(self, prefix_path, pkg_name): # noqa: D102 hooks = [] logger.log(1, "checking '%s' for CMake config files" % prefix_path) for _, _, filenames in os.walk(str(prefix_path)): for filename in filenames: if filename.endswith('-config.cmake') or \ filename.endswith('Config.cmake'): hooks += create_environment_hook( 'cmake_prefix_path', prefix_path, pkg_name, 'CMAKE_PREFIX_PATH', '', mode='prepend') break else: continue break return hooks
async def build(self, *, additional_hooks=[], skip_hook_creation=False): # noqa: D102 pkg = self.context.pkg args = self.context.args # TODO(jacobperron): This would be better handled by a more generic ament_java library additional_hooks += create_environment_hook('ament_prefix_path', Path(args.install_base), pkg.name, 'AMENT_PREFIX_PATH', args.install_base, mode='prepend') return await super(AmentGradleBuildTask, self).build(additional_hooks=additional_hooks, skip_hook_creation=skip_hook_creation)
async def build(self): # noqa: D102 args = self.context.args logger.info("Building ROS package in '{args.path}' with build type " "'ament_cmake'".format_map(locals())) # reuse CMake build task with additional logic extension = CmakeBuildTask() extension.set_context(context=self.context) # add a hook for each available shell additional_hooks = create_environment_hook('ament_current_prefix', Path(args.install_base), self.context.pkg.name, 'AMENT_CURRENT_PREFIX', '', mode='prepend') shell_extensions = get_shell_extensions() file_extensions = [] for shell_extensions_same_prio in shell_extensions.values(): for shell_extension in shell_extensions_same_prio.values(): file_extensions += shell_extension.get_file_extensions() for file_extension in sorted(file_extensions): additional_hooks.append( 'share/{self.context.pkg.name}/local_setup.{file_extension}'. format_map(locals())) # additional arguments if args.test_result_base: if args.cmake_args is None: args.cmake_args = [] # ament_cmake appends the project name itself args.cmake_args.append('-DAMENT_TEST_RESULTS_DIR=' + os.path.dirname(args.test_result_base)) if args.symlink_install: if args.cmake_args is None: args.cmake_args = [] args.cmake_args.append('-DAMENT_CMAKE_SYMLINK_INSTALL=1') if args.ament_cmake_args: if args.cmake_args is None: args.cmake_args = [] args.cmake_args += args.ament_cmake_args return await extension.build(environment_callback=add_app_to_cpp, additional_hooks=additional_hooks)
def _create_environment_hooks( self, prefix_path, pkg_name, subdirectory, suffix='' ): hooks = [] bin_path = prefix_path / subdirectory logger.log(1, "checking '%s'" % bin_path) try: names = os.listdir(str(bin_path)) except FileNotFoundError: pass else: for name in names: if not (bin_path / name).is_file(): continue hooks += shell.create_environment_hook( 'path' + suffix, prefix_path, pkg_name, 'PATH', subdirectory, mode='prepend') break return hooks
async def build(self, *, additional_hooks=None, skip_hook_creation=False): # noqa D102 args = self.context.args # BuildPackageArguments logger.info("Building ROS package in '{args.path}'" "with build type 'ros.ament_dub'".format_map(locals())) extension = DubBuildTask() extension.set_context(context=self.context) additional_hooks = create_environment_hook('ament_prefix_path', Path(args.install_base), self.context.pkg.name, 'AMENT_PREFIX_PATH', '', mode='prepend') rc = await extension.build(additional_hooks=additional_hooks, skip_hook_creation=skip_hook_creation) if rc: return rc
def create_pythonpath_environment_hook(basepath, pkg_name): """ Create a hook script for each primary shell to prepend to the PYTHONPATH. :param Path basepath: The path of the prefix :param str pkg_name: The package name :returns: The relative paths to the created hook scripts :rtype: list """ hooks = [] # prepend Python 2 specific path to PYTHONPATH if it exists if os.environ.get('ROS_PYTHON_VERSION', '2') == '2': for subdirectory in ('dist-packages', 'site-packages'): python_path = basepath / 'lib' / 'python2.7' / subdirectory logger.log(1, "checking '%s'" % python_path) if python_path.exists(): rel_python_path = python_path.relative_to(basepath) hooks += create_environment_hook('python2path', basepath, pkg_name, 'PYTHONPATH', str(rel_python_path), mode='prepend') return hooks
async def build(self): # noqa: D102 args = self.context.args logger.info( "Building ROS package in '{args.path}' with build type " "'ament_python'".format_map(locals())) # reuse Python build task with additional logic extension = PythonBuildTask() extension.set_context(context=self.context) # additional hooks additional_hooks = create_environment_hook( 'ament_prefix_path', Path(args.install_base), self.context.pkg.name, 'AMENT_PREFIX_PATH', '', mode='prepend') # get options from the Python manifest try: env = await get_command_environment( 'setup_py', args.build_base, self.context.dependencies) except RuntimeError as e: logger.error(str(e)) return 1 setup_py_data = get_setup_data(self.context.pkg, env) # check if the package index and manifest are being installed data_files = get_data_files_mapping( setup_py_data.get('data_files', [])) installs_package_index = False installs_package_manifest = False # check if package index and manifest are being installed for source, destination in data_files.items(): if sys.platform == 'win32': destination = Path(destination).as_posix() # work around data files incorrectly defined as not relative if os.path.isabs(source): source = os.path.relpath(source, args.path) if ( destination == 'share/ament_index/resource_index/packages/' + self.context.pkg.name ): installs_package_index = True elif ( source == 'package.xml' and destination == 'share/{self.context.pkg.name}/package.xml' .format_map(locals()) ): installs_package_manifest = True # warn about missing explicit installation # for now implicitly install the marker and the manifest if not installs_package_index: # TODO remove magic helper in the future logger.warn( "Package '{self.context.pkg.name}' doesn't explicitly install " 'a marker in the package index (colcon-ros currently does it ' 'implicitly but that fallback will be removed in the future)' .format_map(locals())) # create package marker in ament resource index create_file( args, 'share/ament_index/resource_index/packages/' '{self.context.pkg.name}'.format_map(locals())) if not installs_package_manifest: # TODO remove magic helper in the future logger.warn( "Package '{self.context.pkg.name}' doesn't explicitly install " "the 'package.xml' file (colcon-ros currently does it " 'implicitly but that fallback will be removed in the future)' .format_map(locals())) # copy / symlink package manifest install( args, 'package.xml', 'share/{self.context.pkg.name}/package.xml' .format_map(locals())) return await extension.build(additional_hooks=additional_hooks)
async def build(self, *, additional_hooks=None): # noqa: D102 pkg = self.context.pkg args = self.context.args logger.info( "Building Python package in '{args.path}'".format_map(locals())) try: env = await get_command_environment( 'setup_py', args.build_base, self.context.dependencies) except RuntimeError as e: logger.error(str(e)) return 1 setup_py_data = get_setup_data(self.context.pkg, env) # `setup.py egg_info` requires the --egg-base to exist os.makedirs(args.build_base, exist_ok=True) # `setup.py develop|install` requires the python lib path to exist python_lib = os.path.join( args.install_base, self._get_python_lib(args)) os.makedirs(python_lib, exist_ok=True) # and being in the PYTHONPATH env = dict(env) env['PYTHONPATH'] = python_lib + os.pathsep + \ env.get('PYTHONPATH', '') if not args.symlink_install: rc = await self._undo_develop(pkg, args, env) if rc and rc.returncode: return rc.returncode # invoke `setup.py install` step with lots of arguments # to avoid placing any files in the source space cmd = [ executable, 'setup.py', 'egg_info', '--egg-base', args.build_base, 'build', '--build-base', os.path.join( args.build_base, 'build'), 'install', '--prefix', args.install_base, '--record', os.path.join(args.build_base, 'install.log'), # prevent installation of dependencies specified in setup.py '--single-version-externally-managed', ] self._append_install_layout(args, cmd) rc = await check_call(self.context, cmd, cwd=args.path, env=env) if rc and rc.returncode: return rc.returncode else: self._undo_install(pkg, args, setup_py_data, python_lib) self._symlinks_in_build(args, setup_py_data) # invoke `setup.py develop` step in build space # to avoid placing any files in the source space # --editable causes this to skip creating/editing the # easy-install.pth file cmd = [ executable, 'setup.py', 'develop', '--prefix', args.install_base, '--editable', '--build-directory', os.path.join(args.build_base, 'build'), '--no-deps', ] if setup_py_data.get('data_files'): cmd += ['install_data', '--install-dir', args.install_base] self._append_install_layout(args, cmd) rc = await check_call( self.context, cmd, cwd=args.build_base, env=env) if rc and rc.returncode: return rc.returncode # explicitly add the build directory to the PYTHONPATH # to maintain the desired order if additional_hooks is None: additional_hooks = [] base_path = args.build_base # if the Python packages are in a subdirectory # that needs to be appended to the build directory package_dir = setup_py_data.get('package_dir') or {} if '' in package_dir: base_path = os.path.join(base_path, package_dir['']) additional_hooks += create_environment_hook( 'pythonpath_develop', Path(base_path), pkg.name, 'PYTHONPATH', base_path, mode='prepend') hooks = create_environment_hooks(args.install_base, pkg.name) create_environment_scripts( pkg, args, default_hooks=hooks, additional_hooks=additional_hooks)
async def build(self): # noqa: D102 args = self.context.args # get build type of package from manifest pkg, build_type = get_package_with_build_type(args.path) logger.info("Building ROS package in '{args.path}' with build type " "'{build_type}'".format_map(locals())) # choose the task extension and additional hooks and arguments additional_hooks = [] if build_type == 'ament_cmake': extension = CmakeBuildTask() additional_hooks += [ 'share/{pkg.name}/local_setup.bash'.format_map(locals()), 'share/{pkg.name}/local_setup.bat'.format_map(locals()), 'share/{pkg.name}/local_setup.ps1'.format_map(locals()), 'share/{pkg.name}/local_setup.sh'.format_map(locals()), ] if args.test_result_base: if args.cmake_args is None: args.cmake_args = [] # ament_cmake appends the project name itself args.cmake_args.append('-DAMENT_TEST_RESULTS_DIR=' + os.path.dirname(args.test_result_base)) if args.symlink_install: if args.cmake_args is None: args.cmake_args = [] args.cmake_args.append('-DAMENT_CMAKE_SYMLINK_INSTALL=1') if args.ament_cmake_args: if args.cmake_args is None: args.cmake_args = [] args.cmake_args += args.ament_cmake_args # extend CMAKE_PREFIX_PATH with AMENT_PREFIX_PATH ament_prefix_path = os.environ.get('AMENT_PREFIX_PATH') if ament_prefix_path: ament_prefix_path = ament_prefix_path.replace(os.pathsep, ';') if args.cmake_args is None: args.cmake_args = [] # check if the CMAKE_PREFIX_PATH is explicitly set prefix = '-DCMAKE_PREFIX_PATH=' for i, value in reversed(list(enumerate(args.cmake_args))): if not value.startswith(prefix): continue # extend the last existing entry existing = value[len(prefix):] if existing: existing = ';' + existing args.cmake_args[i] = \ '-DCMAKE_PREFIX_PATH={ament_prefix_path}{existing}' \ .format_map(locals()) break else: # otherwise extend the environment variable existing = os.environ.get('CMAKE_PREFIX_PATH', '') if existing: existing = ';' + existing.replace(os.pathsep, ';') args.cmake_args.append( '-DCMAKE_PREFIX_PATH={ament_prefix_path}{existing}'. format_map(locals())) elif build_type == 'ament_python': extension = PythonBuildTask() additional_hooks += create_environment_hook('ament_prefix_path', Path( args.install_base), pkg.name, 'AMENT_PREFIX_PATH', '', mode='prepend') # create package marker in ament resource index create_file( args, 'share/ament_index/resource_index/packages/{pkg.name}'. format_map(locals())) # copy / symlink package manifest install(args, 'package.xml', 'share/{pkg.name}/package.xml'.format_map(locals())) elif build_type == 'catkin': extension = CmakeBuildTask() if args.cmake_args is None: args.cmake_args = [] args.cmake_args += ['-DCATKIN_INSTALL_INTO_PREFIX_ROOT=0'] if args.test_result_base: # catkin appends the project name itself args.cmake_args.append('-DCATKIN_TEST_RESULTS_DIR=' + os.path.dirname(args.test_result_base)) if args.catkin_cmake_args: args.cmake_args += args.catkin_cmake_args additional_hooks += create_environment_hook('ros_package_path', Path( args.install_base), pkg.name, 'ROS_PACKAGE_PATH', 'share', mode='prepend') elif build_type == 'cmake': extension = CmakeBuildTask() elif build_type == 'cargo': extension = CargoBuildTask() additional_hooks += create_environment_hook('ament_prefix_path', Path( args.install_base), pkg.name, 'AMENT_PREFIX_PATH', '', mode='prepend') # create package marker in ament resource index create_file( args, 'share/ament_index/resource_index/packages/{pkg.name}'. format_map(locals())) # copy / symlink package manifest install(args, 'package.xml', 'share/{pkg.name}/package.xml'.format_map(locals())) else: assert False, 'Unknown build type: ' + build_type extension.set_context(context=self.context) if build_type != 'catkin': return await extension.build(additional_hooks=additional_hooks) else: # for catkin packages add additional hooks after the package has # been built and installed depending on the installed files rc = await extension.build(skip_hook_creation=True) # add Python 2 specific path to PYTHONPATH if it exists if os.environ.get('ROS_PYTHON_VERSION', '2') == '2': for subdirectory in ('dist-packages', 'site-packages'): python_path = Path(args.install_base) / \ 'lib' / 'python2.7' / subdirectory logger.log(1, "checking '%s'" % python_path) if python_path.exists(): rel_python_path = python_path.relative_to( args.install_base) additional_hooks += create_environment_hook( 'python2path', Path(args.install_base), pkg.name, 'PYTHONPATH', str(rel_python_path), mode='prepend') create_environment_scripts(self.context.pkg, args, additional_hooks=additional_hooks) # ensure that the install base has the marker file # identifying it as a catkin workspace marker = Path(args.install_base) / '.catkin' marker.touch(exist_ok=True) return rc
async def build(self): # noqa: D102 args = self.context.args logger.info( "Building ROS package in '{args.path}' with build type 'catkin'". format_map(locals())) # reuse CMake build task with additional logic extension = CmakeBuildTask() extension.set_context(context=self.context) # additional arguments if args.cmake_args is None: args.cmake_args = [] args.cmake_args += ['-DCATKIN_INSTALL_INTO_PREFIX_ROOT=0'] if args.test_result_base: # catkin appends the project name itself args.cmake_args.append('-DCATKIN_TEST_RESULTS_DIR=' + os.path.dirname(args.test_result_base)) if args.catkin_cmake_args: args.cmake_args += args.catkin_cmake_args # invoke the build additional_targets = [] # if no specific target is specified consider building the 'tests' # target and continue if such a target doesn't exist if args.cmake_target is None: if not args.catkin_skip_building_tests: additional_targets.append('tests') args.cmake_target_skip_unavailable = True rc = await extension.build(skip_hook_creation=True, additional_targets=additional_targets) # for catkin packages add additional hooks after the package has # been built and installed depending on the installed files additional_hooks = create_environment_hook('ros_package_path', Path(args.install_base), self.context.pkg.name, 'ROS_PACKAGE_PATH', 'share', mode='prepend') additional_hooks += create_pythonpath_environment_hook( Path(args.install_base), self.context.pkg.name) additional_hooks += create_pkg_config_path_environment_hooks( Path(args.install_base), self.context.pkg.name) # register hooks created via catkin_add_env_hooks shell_extensions = get_shell_extensions() file_extensions = OrderedDict() for shell_extensions_same_prio in shell_extensions.values(): for shell_extension in shell_extensions_same_prio.values(): for file_extension in shell_extension.get_file_extensions(): file_extensions[file_extension] = shell_extension custom_hooks_path = Path(args.install_base) / \ 'share' / self.context.pkg.name / 'catkin_env_hook' for file_extension, shell_extension in file_extensions.items(): file_extension_hooks = sorted( custom_hooks_path.glob('*.{file_extension}'.format_map( locals()))) if file_extension_hooks: try: # try to set CATKIN_ENV_HOOK_WORKSPACE explicitly before # sourcing these hooks additional_hooks.append( shell_extension.create_hook_set_value( 'catkin_env_hook_workspace', Path(args.install_base), self.context.pkg.name, 'CATKIN_ENV_HOOK_WORKSPACE', '$COLCON_CURRENT_PREFIX')) except NotImplementedError: # since not all shell extensions might implement this pass additional_hooks += file_extension_hooks create_environment_scripts(self.context.pkg, args, additional_hooks=additional_hooks) # ensure that the install base has the marker file # identifying it as a catkin workspace marker = Path(args.install_base) / '.catkin' marker.touch(exist_ok=True) return rc