Skip to content

Commit

Permalink
fix argument handling when cm / cmi is invoked in a symlinked folder (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
dirk-thomas committed May 29, 2014
1 parent 284bee3 commit e8f201a
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 58 deletions.
66 changes: 35 additions & 31 deletions bin/catkin_make
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ if os.path.exists(os.path.join(os.path.dirname(__file__), '..', 'python', 'catki
from catkin.init_workspace import init_workspace
from catkin.terminal_color import disable_ANSI_colors, fmt
from catkin.builder import cmake_input_changed
from catkin.builder import determine_path_argument
from catkin.builder import extract_cmake_and_make_arguments
from catkin.builder import get_package_names_with_recursive_dependencies
from catkin.builder import handle_make_arguments
Expand All @@ -34,56 +35,59 @@ def main():
if args.no_color:
disable_ANSI_colors()

# use PWD in order to work when being invoked in a symlinked location
cwd = os.getenv('PWD', '.')

# verify that the base path is known
# use PWD in order to work when bein invoked in a symlinked location
base_path = os.path.abspath(os.getenv('PWD', '.'))
if args.directory:
base_path = os.path.abspath(os.path.join(base_path, args.directory))
base_path = os.path.abspath(os.path.join(cwd, args.directory))
if not os.path.exists(base_path):
return fmt('@{rf}The specified base path @{boldon}"%s"@{boldoff} does not exist' % base_path)

# verify that the base path does not contain a CMakeLists.txt, except if base path equals source path
if (args.source is None or os.path.realpath(base_path) != os.path.realpath(args.source)) \
and os.path.exists(os.path.join(base_path, 'CMakeLists.txt')):
return fmt(('@{rf}The specified base path @{boldon}"%s"@{boldoff} ' % base_path) +
'contains a CMakeLists.txt but "catkin_make" must be invoked in the root of workspace')
return fmt('@{rf}The specified base path @{boldon}"%s"@{boldoff} '
'does not exist' % base_path)
print('Base path: %s' % base_path)

# verify that the base path does not contain a package.xml
if os.path.exists(os.path.join(base_path, 'package.xml')):
return fmt(('@{rf}The specified base path @{boldon}"%s"@{boldoff} ' % base_path) +
'contains a package but "catkin_make" must be invoked in the root of workspace')

print('Base path: %s' % base_path)
return fmt('@{rf}The specified base path @{boldon}"%s"@{boldoff} '
'contains a package but "catkin_make" must be invoked '
'in the root of workspace' % base_path)

# determine source space
source_path = os.path.join(base_path, 'src')
if args.source:
source_path = os.path.abspath(args.source)
source_path = determine_path_argument(cwd, base_path, args.source, 'src')
if not os.path.exists(source_path):
return fmt('@{rf}The specified source space @{boldon}"%s"@{boldoff} does not exist' % source_path)
return fmt('@{rf}The specified source space @{boldon}"%s"@{boldoff} '
'does not exist' % source_path)
print('Source space: %s' % source_path)

build_path = os.path.join(base_path, 'build')
if args.build:
build_path = os.path.abspath(args.build)
# verify that the base path does not contain a CMakeLists.txt
# except if base path equals source path
if (os.path.realpath(base_path) != os.path.realpath(source_path)) \
and os.path.exists(os.path.join(base_path, 'CMakeLists.txt')):
return fmt('@{rf}The specified base path @{boldon}"%s"@{boldoff} '
'contains a CMakeLists.txt but "catkin_make" must be '
'invoked in the root of workspace' % base_path)

build_path = determine_path_argument(cwd, base_path, args.build, 'build')
print('Build space: %s' % build_path)

# determine devel space
devel_path = os.path.join(base_path, 'devel')
devel_arg = None
prefix = '-DCATKIN_DEVEL_PREFIX='
devel_prefix = [a for a in cmake_args if a.startswith(prefix)]
if devel_prefix:
devel_path = os.path.abspath(devel_prefix[-1][len(prefix):])
devel_arg = devel_prefix[-1][len(prefix):]
cmake_args = [a for a in cmake_args if a not in devel_prefix]
devel_path = determine_path_argument(cwd, base_path, devel_arg, 'devel')
print('Devel space: %s' % devel_path)

# determine install space
install_path = os.path.join(base_path, 'install')
install_arg = None
prefix = '-DCMAKE_INSTALL_PREFIX='
install_prefix = [a for a in cmake_args if a.startswith(prefix)]
if install_prefix:
install_path = os.path.abspath(install_prefix[-1][len(prefix):])
install_arg = install_prefix[-1][len(prefix):]
cmake_args = [a for a in cmake_args if a not in install_prefix]
install_path = determine_path_argument(
cwd, base_path, install_arg, 'install')
print('Install space: %s' % install_path)

# ensure build folder exists
Expand Down Expand Up @@ -195,12 +199,12 @@ def _parse_args(args=sys.argv[1:]):
'If the number of CPU cores cannot be determined then no flags are given to make. '
'All other arguments (i.e. target names) are passed to the "make" invocation.')
add = parser.add_argument
add('-C', '--directory', default='.', help='The base path of the workspace (default ".")')
add('--source', help='The path to the source space (default "src")')
add('--build', help='The path to the build space (default "build")')
add('--force-cmake', action='store_true', help='Invoke "cmake" even if it has been executed before')
add('-C', '--directory', default='.', help="The base path of the workspace (default '.')")
add('--source', help="The path to the source space (default 'workspace_base/src')")
add('--build', help="The path to the build space (default 'workspace_base/build')")
add('--force-cmake', action='store_true', help="Invoke 'cmake' even if it has been executed before")
add('--no-color', action='store_true', help='Disables colored output (only for catkin_make and CMake)')
add('--pkg', nargs='+', help='Invoke "make" on specific packages only')
add('--pkg', nargs='+', help="Invoke 'make' on specific packages only")
add('--only-pkg-with-deps', nargs='+', help='Only consider the specific packages and their recursive dependencies and ignore all other packages in the workspace')
add('--cmake-args', dest='cmake_args', nargs='*', type=str,
help='Arbitrary arguments which are passes to CMake. '
Expand Down
46 changes: 27 additions & 19 deletions bin/catkin_make_isolated
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ if os.path.exists(os.path.join(os.path.dirname(__file__), '..', 'python', 'catki
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'python'))
from catkin.builder import build_workspace_isolated
from catkin.builder import colorize_line
from catkin.builder import determine_path_argument
from catkin.builder import extract_cmake_and_make_and_catkin_make_arguments
from catkin.builder import extract_jobs_flags

Expand All @@ -32,18 +33,18 @@ def parse_args(args=None):
'Make job flags (-j/-l) are handled just like catkin_make handles them.'
)
add = parser.add_argument
add('-C', '--directory', dest='workspace',
help='The base path of the workspace (default ".")')
add('-C', '--directory', dest='workspace', default='.',
help="The base path of the workspace (default '.')")
add('--source', '--source-space', default=None,
help='The path to the source space (default "src")')
help="The path to the source space (default 'workspace_base/src')")
add('--build', '--build-space', default=None,
help='The path to the build space (default "build_isolated")')
help="The path to the build space (default 'workspace_base/build_isolated')")
add('--devel', '--devel-space', default=None,
help='Sets the target devel space (default "devel_isolated")')
help="Sets the target devel space (default 'workspace_base/devel_isolated')")
add('--merge', action='store_true', default=False,
help='Build each catkin package into a common devel space.')
add('--install-space', dest='install_space', default=None,
help='Sets the target install space (default "install_isolated")')
add('--install-space', default=None,
help="Sets the target install space (default 'workspace_base/install_isolated')")
add('--install', action='store_true', default=False,
help='Causes each catkin package to be installed.')
add('--force-cmake', action='store_true', default=False,
Expand All @@ -52,19 +53,19 @@ def parse_args(args=None):
help='Disables colored output (only for catkin_make and CMake)')
pkg = parser.add_mutually_exclusive_group(required=False)
pkg.add_argument('--pkg', nargs='+', metavar='PKGNAME', dest='packages',
help='Invoke "make" on specific packages (only after catkin_make_isolated has been invoked before with the same install flag)')
help="Invoke 'make' on specific packages (only after catkin_make_isolated has been invoked before with the same install flag)")
pkg.add_argument('--from-pkg', metavar='PKGNAME', dest='from_package',
help='Restart catkin_make_isolated at the given package continuing from there (do not change CMake arguments, add/move/remove packages or toggle the install flag when using this option since this may result in an inconsistent workspace state).')
add('--only-pkg-with-deps', nargs='+', help='Only consider the specific packages and their recursive dependencies and ignore all other packages in the workspace (only works together with --merge or --install)')
add('-q', '--quiet', action='store_true', default=False,
help='Suppresses the cmake and make output until an error occurs.')
add('--cmake-args', dest='cmake_args', nargs='*', type=str,
add('--cmake-args', nargs='*', type=str,
help='Arbitrary arguments which are passes to CMake. '
'It must be passed after other arguments since it collects all following options.')
add('--make-args', dest='make_args', nargs='*', type=str,
add('--make-args', nargs='*', type=str,
help='Arbitrary arguments which are passes to make.'
'It must be passed after other arguments since it collects all following options.')
add('--catkin-make-args', dest='catkin_make_args', nargs='*', type=str,
add('--catkin-make-args', nargs='*', type=str,
help='Arbitrary arguments which are passes to make but only for catkin packages.'
'It must be passed after other arguments since it collects all following options.')
opts = parser.parse_args(args)
Expand Down Expand Up @@ -110,19 +111,26 @@ def main():
if not sys.stdout.isatty():
opts.no_color = True

# use PWD in order to work when bein invoked in a symlinked location
workspace = os.path.abspath(os.getenv('PWD', '.'))
if opts.workspace:
workspace = os.path.abspath(os.path.join(workspace, opts.workspace))
# use PWD in order to work when being invoked in a symlinked location
cwd = os.getenv('PWD', '.')

workspace = os.path.abspath(os.path.join(cwd, opts.workspace))
sourcespace = determine_path_argument(cwd, workspace, opts.source, 'src')
buildspace = determine_path_argument(
cwd, workspace, opts.build, 'build_isolated')
develspace = determine_path_argument(
cwd, workspace, opts.devel, 'devel_isolated')
installspace = determine_path_argument(
cwd, workspace, opts.install_space, 'install_isolated')

destdir = os.environ['DESTDIR'] if 'DESTDIR' in os.environ else None

build_workspace_isolated(
workspace=workspace,
sourcespace=opts.source,
buildspace=opts.build,
develspace=opts.devel,
installspace=opts.install_space,
sourcespace=sourcespace,
buildspace=buildspace,
develspace=develspace,
installspace=installspace,
merge=opts.merge,
install=opts.install,
force_cmake=opts.force_cmake,
Expand Down
21 changes: 13 additions & 8 deletions python/catkin/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@
from catkin_pkg.workspaces import ensure_workspace_marker


def determine_path_argument(cwd, base_path, argument, default):
if argument is None:
# if no argument is passed the default is relative to the base_path
path = os.path.join(base_path, default)
else:
# if an argument is passed it is relative to cwd (or absolute)
path = os.path.abspath(os.path.join(cwd, argument))
return path


def split_arguments(args, splitter_name, default=None):
if splitter_name not in args:
return args, default
Expand Down Expand Up @@ -732,32 +742,27 @@ def build_workspace_isolated(

# Check source space existance
if sourcespace is None:
ws_sourcespace = os.path.join(workspace, 'src')
if not os.path.exists(ws_sourcespace):
sys.exit("Could not find source space: {0}".format(sourcespace))
sourcespace = ws_sourcespace
sourcespace = os.path.abspath(sourcespace)
sourcespace = os.path.join(workspace, 'src')
if not os.path.exists(sourcespace):
sys.exit('Could not find source space: {0}'.format(sourcespace))
print('Base path: ' + str(workspace))
print('Source space: ' + str(sourcespace))

# Check build space
if buildspace is None:
buildspace = os.path.join(workspace, 'build_isolated')
buildspace = os.path.abspath(buildspace)
if not os.path.exists(buildspace):
os.mkdir(buildspace)
print('Build space: ' + str(buildspace))

# Check devel space
if develspace is None:
develspace = os.path.join(workspace, 'devel_isolated')
develspace = os.path.abspath(develspace)
print('Devel space: ' + str(develspace))

# Check install space
if installspace is None:
installspace = os.path.join(workspace, 'install_isolated')
installspace = os.path.abspath(installspace)
print('Install space: ' + str(installspace))

if cmake_args:
Expand Down

0 comments on commit e8f201a

Please sign in to comment.