def env(self, root): logger.info('env request for %s' % root) path = root if basename(root) == "install": path = dirname(dirname(root)) + '/python2/install' try: path2 = get_python2_path(path) except EnvironmentError as e: print(e) logger.info('trying %s' % path) return ['PYTHONPATH={0}'.format(get_python2_path(path))]
def env(self, root): # This is until we figure out how to get pip to download only # and then build in the build step or split out pulling # stage-packages in an internal private step. env = [ 'CPPFLAGS="-I{} -I{} $CPPFLAGS"'.format( os.path.join(root, 'usr', 'include'), os.path.join(root, 'usr', 'include', 'python2.7')), 'CFLAGS="-I{} -I{} $CFLAGS"'.format( os.path.join(root, 'usr', 'include'), os.path.join(root, 'usr', 'include', 'python2.7')), 'ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future', 'LIBRARY_PATH={}'.format( os.path.join(root, 'usr', 'include', 'python2.7')), 'LDFLAGS="-shared"', ] # 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: env.append('PYTHONPATH={0}'.format(common.get_python2_path(root))) except EnvironmentError as e: logger.debug(e) return env
def env(self, root): """Runtime environment for ROS binaries and services.""" 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/ros", # This environment variable points to where the setup.sh and # _setup_util.py files are located. This is required at both build- # and run-time. "_CATKIN_SETUP_DIR={}".format(os.path.join(root, "opt", "ros", self.options.rosdistro)), # FIXME: Nasty hack to source ROS's setup.sh (since each of these # lines is prepended with "export"). There's got to be a better way # to do this. "echo FOO=BAR\nif `test -e {0}` ; then\n. {0} ;\nfi\n".format( os.path.join(root, "opt", "ros", self.options.rosdistro, "setup.sh") ), ] # 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) return env
def _pip(self, setup): site_packages_dir = os.path.join( os.path.dirname(common.get_python2_path(self.installdir)), 'site-packages') # If site-packages doesn't exist, make sure it points to the # dist-packages in the same directory (this is a relative link so that # it's still valid when the .snap is installed). if not os.path.exists(site_packages_dir): os.symlink('dist-packages', site_packages_dir) self._setup_pip() pip_install = self._get_pip_command(site_packages_dir) if self.options.requirements: self.run(pip_install + [ '--requirement', os.path.join(self.sourcedir, self.options.requirements), ]) if self.options.python_packages: self.run(pip_install + ['--upgrade'] + self.options.python_packages) if os.path.exists(setup): self.run(pip_install + ['.', ], cwd=self.sourcedir)
def build(self): super().build() # If setuptools is used, it tries to create files in the # dist-packages dir and import from there, so it needs to exist # and be in the PYTHONPATH. It's harmless if setuptools isn't # used. setup_file = os.path.join(self.builddir, 'setup.py') if not os.path.exists(setup_file): return os.makedirs(common.get_python2_path(self.installdir), exist_ok=True) self.run([ 'python2', setup_file, 'build_ext', '-I{}'.format(_get_python2_include(self.installdir)), 'install', '--install-layout=deb', '--prefix={}/usr'.format(self.installdir), ], cwd=self.builddir) # Fix all shebangs to use the in-snap python. common.replace_in_file(self.installdir, re.compile(r''), re.compile(r'#!.*python'), r'#!/usr/bin/env python')
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 env(self, root): # 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: return ['PYTHONPATH={0}'.format(common.get_python2_path(root))] except EnvironmentError as e: logger.debug(e) return []
def _pip(self): setup = 'setup.py' if os.listdir(self.sourcedir): setup = os.path.join(self.sourcedir, 'setup.py') if self.options.requirements: requirements = os.path.join(os.getcwd(), self.options.requirements) if not os.path.exists(setup) and not \ (self.options.requirements or self.options.python_packages): return easy_install = os.path.join(self.installdir, 'usr', 'bin', 'easy_install') prefix = os.path.join(self.installdir, 'usr') site_packages_dir = os.path.join( os.path.dirname(common.get_python2_path(self.installdir)), 'site-packages') # If site-packages doesn't exist, make sure it points to the # dist-packages in the same directory (this is a relative link so that # it's still valid when the .snap is installed). if not os.path.exists(site_packages_dir): os.symlink('dist-packages', site_packages_dir) self.run(['python2', easy_install, '--prefix', prefix, 'pip']) pip2 = os.path.join(self.installdir, 'usr', 'bin', 'pip2') pip_install = [ 'python2', pip2, 'install', # '--global-option=build_ext', # '--global-option=-I{}'.format( # _get_python2_include(self.installdir)), # '--no-clean', '--target', site_packages_dir ] if self.options.requirements: self.run(pip_install + ['--requirement', requirements]) if self.options.python_packages: self.run(pip_install + ['--upgrade'] + self.options.python_packages) if os.path.exists(setup): self.run(pip_install + [ '.', ], cwd=self.sourcedir)
def env(self, root): """Runtime environment for ROS binaries and services.""" 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/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', # This environment variable points to where the setup.sh and # _setup_util.py files are located. This is required at both build- # and run-time. '_CATKIN_SETUP_DIR={}'.format( os.path.join(root, 'opt', 'ros', self.options.rosdistro)), ] # 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)) # FIXME: Nasty hack to source ROS's setup.sh (since each of these # lines is prepended with "export"). There's got to be a better way # to do this. env.append( 'echo FOO=BAR\nif `test -e {0}` ; then\n. {0} ;\nfi\n'.format( os.path.join(root, 'opt', 'ros', self.options.rosdistro, 'setup.sh'))) return env
def env(self, root): """Runtime environment for ROS binaries and services.""" 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/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', # This environment variable points to where the setup.sh and # _setup_util.py files are located. This is required at both build- # and run-time. '_CATKIN_SETUP_DIR={}'.format(os.path.join( root, 'opt', 'ros', self.options.rosdistro)), ] # 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)) # FIXME: Nasty hack to source ROS's setup.sh (since each of these # lines is prepended with "export"). There's got to be a better way # to do this. env.append( 'echo FOO=BAR\nif `test -e {0}` ; then\n. {0} ;\nfi\n'.format( os.path.join( root, 'opt', 'ros', self.options.rosdistro, 'setup.sh'))) return env
def env(self, root): """Runtime environment for ROS binaries and services.""" 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/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', ] # 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(self): super().build() # If setuptools is used, it tries to create files in the # dist-packages dir and import from there, so it needs to exist # and be in the PYTHONPATH. It's harmless if setuptools isn't # used. setup_file = os.path.join(self.builddir, 'setup.py') if not os.path.exists(setup_file): return os.makedirs(common.get_python2_path(self.installdir), exist_ok=True) self.run( ['python2', setup_file, 'build_ext', '-I{}'.format(_get_python2_include(self.installdir)), 'install', '--install-layout=deb', '--prefix={}/usr'.format(self.installdir), ], cwd=self.builddir)
def _pip(self): setup = 'setup.py' if os.listdir(self.sourcedir): setup = os.path.join(self.sourcedir, 'setup.py') if self.options.requirements: requirements = os.path.join(self.sourcedir, self.options.requirements) if not os.path.exists(setup) and not \ (self.options.requirements or self.options.python_packages): return easy_install = os.path.join( self.installdir, 'usr', 'bin', 'easy_install') prefix = os.path.join(self.installdir, 'usr') site_packages_dir = os.path.join( os.path.dirname(common.get_python2_path(self.installdir)), 'site-packages') # If site-packages doesn't exist, make sure it points to the # dist-packages in the same directory (this is a relative link so that # it's still valid when the .snap is installed). if not os.path.exists(site_packages_dir): os.symlink('dist-packages', site_packages_dir) self.run(['python2', easy_install, '--prefix', prefix, 'pip']) pip2 = os.path.join(self.installdir, 'usr', 'bin', 'pip2') pip_install = ['python2', pip2, 'install', '--global-option=build_ext', '--global-option=-I{}'.format( _get_python2_include(self.installdir)), '--target', site_packages_dir] if self.options.requirements: self.run(pip_install + ['--requirement', requirements]) if self.options.python_packages: self.run(pip_install + ['--upgrade'] + self.options.python_packages) if os.path.exists(setup): self.run(pip_install + ['.', ], cwd=self.sourcedir)
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.""" 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/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', # This environment variable points to where the setup.sh and # _setup_util.py files are located. This is required at both build- # and run-time. '_CATKIN_SETUP_DIR={}'.format(os.path.join( root, 'opt', 'ros', self.options.rosdistro)), ] # 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)) # We need to source ROS's setup.sh at this point. However, it accepts # arguments (thus will parse $@), and we really don't want it to, since # $@ in this context will be meant for the app being launched # (LP: #1660852). So we'll backup all args, source the setup.sh, then # restore all args for the wrapper's `exec` line. script = textwrap.dedent(''' if [ -e {0} ]; then # Shell quote arbitrary string by replacing every occurrence of ' # with '\\'', then put ' at the beginning and end of the string. # Prepare yourself, fun regex ahead. quote() {{ for i; do printf %s\\\\n "$i" | sed "s/\'/\'\\\\\\\\\'\'/g;1s/^/\'/;\$s/\$/\' \\\\\\\\/" done echo " " }} BACKUP_ARGS=$(quote "$@") set -- . {0} eval "set -- $BACKUP_ARGS" fi '''.format(os.path.join( # noqa root, 'opt', 'ros', self.options.rosdistro, 'setup.sh'))) # 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 in the # environment. FIXME: There should be a better way to do this. env[-1] = env[-1] + 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