Example #1
0
 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))]
Example #2
0
 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))]
Example #3
0
    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
Example #4
0
    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
Example #5
0
    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)
Example #6
0
    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)
Example #7
0
    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')
Example #8
0
    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
Example #9
0
    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
Example #10
0
 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 []
Example #11
0
 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)
Example #13
0
    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
Example #14
0
    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
Example #15
0
    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
Example #16
0
    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)
Example #17
0
    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)
Example #18
0
    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
Example #19
0
    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
Example #20
0
    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