def get_snapcraft_build_environment(part: "PluginHandler") -> Dict[str, str]: """Return Snapcraft provided build environment.""" part_environment = get_snapcraft_global_environment(part._project) part_environment.update(get_snapcraft_part_environment(part)) paths = [part.part_install_dir, part._project.stage_dir] include_paths = list() for path in paths: include_paths.extend( common.get_include_paths(path, part._project.arch_triplet)) if include_paths: for envvar in ["CPPFLAGS", "CFLAGS", "CXXFLAGS"]: part_environment[envvar] = formatting_utils.combine_paths( paths=include_paths, prepend="-isystem", separator=" ") library_paths = list() for path in paths: library_paths.extend( common.get_library_paths(path, part._project.arch_triplet)) if library_paths: part_environment["LDFLAGS"] = formatting_utils.combine_paths( paths=library_paths, prepend="-L", separator=" ") pkg_config_paths = common.get_pkg_config_paths(path, part._project.arch_triplet) if pkg_config_paths: part_environment["PKG_CONFIG_PATH"] = formatting_utils.combine_paths( pkg_config_paths, prepend="", separator=":") return part_environment
def cxxflags(self): paths = set( common.get_include_paths(self._compilers_install_path, self._project.arch_triplet)) try: paths.add( _get_highest_version_path( os.path.join(self._compilers_install_path, "usr", "include", "c++"))) paths.add( _get_highest_version_path( os.path.join( self._compilers_install_path, "usr", "include", self._project.arch_triplet, "c++", ))) except CatkinNoHighestVersionPathError as e: raise CatkinGccVersionError(str(e)) return formatting_utils.combine_paths(paths, prepend="-I", separator=" ")
def cxxflags(self): paths = set( common.get_include_paths( self._compilers_install_path, self._project.arch_triplet ) ) try: paths.add( _get_highest_version_path( os.path.join(self._compilers_install_path, "usr", "include", "c++") ) ) paths.add( _get_highest_version_path( os.path.join( self._compilers_install_path, "usr", "include", self._project.arch_triplet, "c++", ) ) ) except RuntimeError as e: raise RuntimeError("Unable to determine gcc version: {}".format(str(e))) return formatting_utils.combine_paths(paths, prepend="-I", separator=" ")
def cxxflags(self): paths = set( common.get_include_paths(self._compilers_install_path, self._project.arch_triplet)) try: paths.add( _get_highest_version_path( os.path.join(self._compilers_install_path, "usr", "include", "c++"))) paths.add( _get_highest_version_path( os.path.join( self._compilers_install_path, "usr", "include", self._project.arch_triplet, "c++", ))) except RuntimeError as e: raise RuntimeError("Unable to determine gcc version: {}".format( str(e))) return formatting_utils.combine_paths(paths, prepend="-I", separator=" ")
def get_snapcraft_part_environment( part: "PluginHandler", *, step: steps.Step ) -> Dict[str, str]: """Return Snapcraft provided part environment.""" part_environment = get_snapcraft_global_environment( part._project, include_prime=step == steps.PRIME ) part_environment.update(get_snapcraft_part_directory_environment(part, step=step)) paths = [part.part_install_dir, part._project.stage_dir] bin_paths = list() for path in paths: bin_paths.extend(common.get_bin_paths(root=path, existing_only=True)) if bin_paths: bin_paths.append("$PATH") part_environment["PATH"] = formatting_utils.combine_paths( paths=bin_paths, prepend="", separator=":" ) include_paths = list() for path in paths: include_paths.extend(common.get_include_paths(path, part._project.arch_triplet)) if include_paths: for envvar in ["CPPFLAGS", "CFLAGS", "CXXFLAGS"]: part_environment[envvar] = formatting_utils.combine_paths( paths=include_paths, prepend="-isystem", separator=" " ) library_paths = list() for path in paths: library_paths.extend(common.get_library_paths(path, part._project.arch_triplet)) if library_paths: part_environment["LDFLAGS"] = formatting_utils.combine_paths( paths=library_paths, prepend="-L", separator=" " ) pkg_config_paths = common.get_pkg_config_paths(path, part._project.arch_triplet) if pkg_config_paths: part_environment["PKG_CONFIG_PATH"] = formatting_utils.combine_paths( pkg_config_paths, prepend="", separator=":" ) return part_environment
def env(self, root): """Runtime environment for ROS binaries and services.""" paths = common.get_library_paths(root, self.project.arch_triplet) ld_library_path = formatting_utils.combine_paths(paths, prepend='', separator=':') env = [ # This environment variable tells ROS nodes where to find ROS # master. It does not affect ROS master, however-- this is just the # default URI. 'ROS_MASTER_URI=http://localhost:11311', # Various ROS tools (e.g. rospack, roscore) keep a cache or a log, # and use $ROS_HOME to determine where to put them. 'ROS_HOME=${SNAP_USER_DATA:-/tmp}/ros', # FIXME: LP: #1576411 breaks ROS snaps on the desktop, so we'll # temporarily work around that bug by forcing the locale to # C.UTF-8. 'LC_ALL=C.UTF-8', # The Snapcraft Core will ensure that we get a good LD_LIBRARY_PATH # overall, but it defines it after this function runs. Some ROS # tools will cause binaries to be run when we source the setup.sh, # below, so we need to have a sensible LD_LIBRARY_PATH before then. 'LD_LIBRARY_PATH=$LD_LIBRARY_PATH:{}'.format(ld_library_path), ] # There's a chicken and egg problem here, everything run get's an # env built, even package installation, so the first runs for these # will likely fail. try: # The ROS packaging system tools (e.g. rospkg, etc.) don't go # into the ROS install path (/opt/ros/$distro), so we need the # PYTHONPATH to include the dist-packages in /usr/lib as well. env.append('PYTHONPATH={0}:$PYTHONPATH'.format( common.get_python2_path(root))) except EnvironmentError as e: logger.debug(e) # The setup.sh we source below requires the in-snap python. Here we # make sure it's in the PATH before it's run. env.append('PATH=$PATH:{}/usr/bin'.format(root)) if self.options.underlay: script = '. {}'.format( os.path.join(self.rosdir, 'snapcraft-setup.sh')) else: script = self._source_setup_sh(root, None) # Each of these lines is prepended with an `export` when the # environment is actually generated. In order to inject real shell code # we have to hack it in by appending it on the end of an item already # in the environment. FIXME: There should be a better way to do this. env[-1] = env[-1] + '\n\n' + script return env
def _build_env(root, snap_name, confinement, arch_triplet, core_dynamic_linker=None): """Set the environment variables required for building. This is required for the current parts installdir due to stage-packages and also to setup the stagedir. """ env = [] paths = common.get_include_paths(root, arch_triplet) if paths: for envvar in ['CPPFLAGS', 'CFLAGS', 'CXXFLAGS']: env.append(formatting_utils.format_path_variable( envvar, paths, prepend='-I', separator=' ')) if confinement == 'classic': if not core_dynamic_linker: raise EnvironmentError( 'classic confinement requires the core snap to be installed. ' 'Install it by running `snap install core`.') core_path = common.get_core_path() core_rpaths = common.get_library_paths(core_path, arch_triplet, existing_only=False) snap_path = os.path.join('/snap', snap_name, 'current') snap_rpaths = common.get_library_paths(snap_path, arch_triplet, existing_only=False) # snap_rpaths before core_rpaths to prefer libraries from the snap. rpaths = formatting_utils.combine_paths( snap_rpaths + core_rpaths, prepend='', separator=':') env.append('LDFLAGS="$LDFLAGS ' # Building tools to continue the build becomes problematic # with nodefaultlib. # '-Wl,-z,nodefaultlib ' '-Wl,--dynamic-linker={0} ' '-Wl,-rpath,{1}"'.format(core_dynamic_linker, rpaths)) paths = common.get_library_paths(root, arch_triplet) if paths: env.append(formatting_utils.format_path_variable( 'LDFLAGS', paths, prepend='-L', separator=' ')) paths = common.get_pkg_config_paths(root, arch_triplet) if paths: env.append(formatting_utils.format_path_variable( 'PKG_CONFIG_PATH', paths, prepend='', separator=':')) return env
def _build_env(root, snap_name, confinement, arch_triplet, core_dynamic_linker=None): """Set the environment variables required for building. This is required for the current parts installdir due to stage-packages and also to setup the stagedir. """ env = [] paths = common.get_include_paths(root, arch_triplet) if paths: for envvar in ['CPPFLAGS', 'CFLAGS', 'CXXFLAGS']: env.append(formatting_utils.format_path_variable( envvar, paths, prepend='-I', separator=' ')) if confinement == 'classic': if not core_dynamic_linker: raise EnvironmentError( 'classic confinement requires the core snap to be installed. ' 'Install it by running `snap install core`.') core_path = common.get_core_path() core_rpaths = common.get_library_paths(core_path, arch_triplet, existing_only=False) snap_path = os.path.join('/snap', snap_name, 'current') snap_rpaths = common.get_library_paths(snap_path, arch_triplet, existing_only=False) # snap_rpaths before core_rpaths to prefer libraries from the snap. rpaths = formatting_utils.combine_paths( snap_rpaths + core_rpaths, prepend='', separator=':') env.append('LDFLAGS="$LDFLAGS ' # Building tools to continue the build becomes problematic # with nodefaultlib. # '-Wl,-z,nodefaultlib ' '-Wl,--dynamic-linker={0} ' '-Wl,-rpath,{1}"'.format(core_dynamic_linker, rpaths)) paths = common.get_library_paths(root, arch_triplet) if paths: env.append(formatting_utils.format_path_variable( 'LDFLAGS', paths, prepend='-L', separator=' ')) paths = common.get_pkg_config_paths(root, arch_triplet) if paths: env.append(formatting_utils.format_path_variable( 'PKG_CONFIG_PATH', paths, prepend='', separator=':')) return env
def environment(self): env = os.environ.copy() paths = common.get_library_paths( self._compilers_install_path, self._project.arch_triplet) ld_library_path = formatting_utils.combine_paths( paths, prepend='', separator=':') env['LD_LIBRARY_PATH'] = ( env.get('LD_LIBRARY_PATH', '') + ':' + ld_library_path) env['PATH'] = env.get('PATH', '') + ':' + os.path.join( self._compilers_install_path, 'usr', 'bin') return env
def environment(self): env = os.environ.copy() paths = common.get_library_paths( self._compilers_install_path, self._project.arch_triplet) ld_library_path = formatting_utils.combine_paths( paths, prepend='', separator=':') env['LD_LIBRARY_PATH'] = ( env.get('LD_LIBRARY_PATH', '') + ':' + ld_library_path) env['PATH'] = env.get('PATH', '') + ':' + os.path.join( self._compilers_install_path, 'usr', 'bin') return env
def cxxflags(self): paths = set(common.get_include_paths( self._compilers_install_path, self._project.arch_triplet)) try: paths.add(_get_highest_version_path(os.path.join( self._compilers_install_path, 'usr', 'include', 'c++'))) paths.add(_get_highest_version_path(os.path.join( self._compilers_install_path, 'usr', 'include', self._project.arch_triplet, 'c++'))) except RuntimeError as e: raise RuntimeError('Unable to determine gcc version: {}'.format( str(e))) return formatting_utils.combine_paths( paths, prepend='-I', separator=' ')
def cxxflags(self): paths = set(common.get_include_paths( self._compilers_install_path, self._project.arch_triplet)) try: paths.add(_get_highest_version_path(os.path.join( self._compilers_install_path, 'usr', 'include', 'c++'))) paths.add(_get_highest_version_path(os.path.join( self._compilers_install_path, 'usr', 'include', self._project.arch_triplet, 'c++'))) except RuntimeError as e: raise RuntimeError('Unable to determine gcc version: {}'.format( str(e))) return formatting_utils.combine_paths( paths, prepend='-I', separator=' ')
def environment(self): env = os.environ.copy() paths = common.get_library_paths(self._compilers_install_path, self._project.arch_triplet) ld_library_path = formatting_utils.combine_paths(paths, prepend="", separator=":") env["LD_LIBRARY_PATH"] = env.get("LD_LIBRARY_PATH", "") + ":" + ld_library_path env["PATH"] = ( env.get("PATH", "") + ":" + os.path.join(self._compilers_install_path, "usr", "bin")) return env
def environment(self): env = os.environ.copy() paths = common.get_library_paths( self._compilers_install_path, self._project.arch_triplet ) ld_library_path = formatting_utils.combine_paths( paths, prepend="", separator=":" ) env["LD_LIBRARY_PATH"] = env.get("LD_LIBRARY_PATH", "") + ":" + ld_library_path env["PATH"] = ( env.get("PATH", "") + ":" + os.path.join(self._compilers_install_path, "usr", "bin") ) return env
def env(self, root): """Runtime environment for ROS binaries and services.""" env = [ # The Snapcraft Core will ensure that we get a good LD_LIBRARY_PATH # overall, but it defines it after this function runs. Some ROS # tools will cause binaries to be run when we source the setup.sh, # below, so we need to have a sensible LD_LIBRARY_PATH before then. 'LD_LIBRARY_PATH="$LD_LIBRARY_PATH:{}"'.format( formatting_utils.combine_paths( common.get_library_paths(root, self.project.arch_triplet), prepend="", separator=":", )) ] # Each of these lines is prepended with an `export` when the environment is # actually generated. In order to inject real shell code we have to hack it in # by appending it on the end of an item already in the environment. # FIXME: There should be a better way to do this. LP: #1792034 env[-1] = env[-1] + "\n\n" + self._source_setup_sh(root) return env
def env(self, root): """Runtime environment for ROS binaries and services.""" paths = common.get_library_paths(root, self.project.arch_triplet) ld_library_path = formatting_utils.combine_paths(paths, prepend="", separator=":") env = [ # This environment variable tells ROS nodes where to find ROS # master. It does not affect ROS master, however-- this is just the # URI. "ROS_MASTER_URI={}".format(self.options.catkin_ros_master_uri), # Various ROS tools (e.g. roscore) keep a cache or a log, # and use $ROS_HOME to determine where to put them. "ROS_HOME=${SNAP_USER_DATA:-/tmp}/ros", # FIXME: LP: #1576411 breaks ROS snaps on the desktop, so we'll # temporarily work around that bug by forcing the locale to # C.UTF-8. "LC_ALL=C.UTF-8", # The Snapcraft Core will ensure that we get a good LD_LIBRARY_PATH # overall, but it defines it after this function runs. Some ROS # tools will cause binaries to be run when we source the setup.sh, # below, so we need to have a sensible LD_LIBRARY_PATH before then. "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:{}".format(ld_library_path), ] # There's a chicken and egg problem here, everything run gets an # env built, even package installation, so the first runs for these # will likely fail. try: # The ROS packaging system tools (e.g. rospkg, etc.) don't go # into the ROS install path (/opt/ros/$distro), so we need the # PYTHONPATH to include the dist-packages in /usr/lib as well. # # Note: Empty segments in PYTHONPATH are interpreted as `.`, thus # adding the current working directory to the PYTHONPATH. That is # not desired in this situation, so take proper precautions when # expanding PYTHONPATH: only add it if it's not empty. env.append("PYTHONPATH={}${{PYTHONPATH:+:$PYTHONPATH}}".format( common.get_python2_path(root))) except errors.SnapcraftEnvironmentError as e: logger.debug(e) # The setup.sh we source below requires the in-snap python. Here we # make sure it's in the PATH before it's run. env.append("PATH=$PATH:{}/usr/bin".format(root)) if self.options.underlay: script = textwrap.dedent(""" if [ -f {snapcraft_setup} ]; then . {snapcraft_setup} fi """).format(snapcraft_setup=os.path.join(self.rosdir, "snapcraft-setup.sh")) else: script = self._source_setup_sh(root, None) # Each of these lines is prepended with an `export` when the # environment is actually generated. In order to inject real shell code # we have to hack it in by appending it on the end of an item already # in the environment. FIXME: There should be a better way to do this. # LP: #1792034 env[-1] = env[-1] + "\n\n" + script return env
def env(self, root): """Runtime environment for ROS binaries and services.""" paths = common.get_library_paths(root, self.project.arch_triplet) ld_library_path = formatting_utils.combine_paths( paths, prepend='', separator=':') env = [ # This environment variable tells ROS nodes where to find ROS # master. It does not affect ROS master, however-- this is just the # URI. 'ROS_MASTER_URI={}'.format(self.options.catkin_ros_master_uri), # Various ROS tools (e.g. rospack, roscore) keep a cache or a log, # and use $ROS_HOME to determine where to put them. 'ROS_HOME=${SNAP_USER_DATA:-/tmp}/ros', # FIXME: LP: #1576411 breaks ROS snaps on the desktop, so we'll # temporarily work around that bug by forcing the locale to # C.UTF-8. 'LC_ALL=C.UTF-8', # The Snapcraft Core will ensure that we get a good LD_LIBRARY_PATH # overall, but it defines it after this function runs. Some ROS # tools will cause binaries to be run when we source the setup.sh, # below, so we need to have a sensible LD_LIBRARY_PATH before then. 'LD_LIBRARY_PATH=$LD_LIBRARY_PATH:{}'.format(ld_library_path), ] # There's a chicken and egg problem here, everything run get's an # env built, even package installation, so the first runs for these # will likely fail. try: # The ROS packaging system tools (e.g. rospkg, etc.) don't go # into the ROS install path (/opt/ros/$distro), so we need the # PYTHONPATH to include the dist-packages in /usr/lib as well. # # Note: Empty segments in PYTHONPATH are interpreted as `.`, thus # adding the current working directory to the PYTHONPATH. That is # not desired in this situation, so take proper precautions when # expanding PYTHONPATH: only add it if it's not empty. env.append('PYTHONPATH={}${{PYTHONPATH:+:$PYTHONPATH}}'.format( common.get_python2_path(root))) except errors.SnapcraftEnvironmentError as e: logger.debug(e) # The setup.sh we source below requires the in-snap python. Here we # make sure it's in the PATH before it's run. env.append('PATH=$PATH:{}/usr/bin'.format(root)) if self.options.underlay: script = '. {}'.format(os.path.join( self.rosdir, 'snapcraft-setup.sh')) else: script = self._source_setup_sh(root, None) # Each of these lines is prepended with an `export` when the # environment is actually generated. In order to inject real shell code # we have to hack it in by appending it on the end of an item already # in the environment. FIXME: There should be a better way to do this. env[-1] = env[-1] + '\n\n' + script return env
def ldflags(self): paths = common.get_library_paths(self._compilers_install_path, self._project.arch_triplet) return formatting_utils.combine_paths(paths, prepend='-L', separator=' ')
def ldflags(self): paths = common.get_library_paths( self._compilers_install_path, self._project.arch_triplet) return formatting_utils.combine_paths( paths, prepend='-L', separator=' ')