Skip to content

Instantly share code, notes, and snippets.

@miquelmassot
Created September 8, 2014 13:09
Show Gist options
  • Save miquelmassot/726041a856d2d71b4fbd to your computer and use it in GitHub Desktop.
Save miquelmassot/726041a856d2d71b4fbd to your computer and use it in GitHub Desktop.
Create a Sublime Text 2/3 project with all your workspace packages in it!
#!/usr/bin/env python
from __future__ import print_function
import argparse
import json
import os
import sys
from catkin_pkg.packages import find_packages
verbose = False
def log(*args, **kwargs):
global verbose
if verbose:
kwargs['file'] = sys.stderr
print(*args, **kwargs)
def get_cflags_from_buildspace(pkg_dict, buildspace):
cflags = []
for name in [p.name for p in pkg_dict.values()]:
context_path = os.path.join(buildspace, name, 'catkin_generated', 'pkg.develspace.context.pc.py')
if os.path.isfile(context_path):
loc = {}
with open(context_path, 'r') as f:
exec(f.read(), {}, loc)
if 'PROJECT_ABSOLUTE_INCLUDE_DIRS' in loc:
for inc in loc['PROJECT_ABSOLUTE_INCLUDE_DIRS'].split(';'):
if inc:
cflags.append('-I{0}'.format(inc))
return list(set(cflags))
def parse_cmakelists(cmakelist_path):
try:
from parse_cmake import parsing
except ImportError:
print("Failed to import parse_cmake, install it with `pip install parse_cmake`", file=sys.stderr)
sys.exit(1)
log("==> Processing {0}:".format(cmakelist_path))
with open(cmakelist_path, 'r') as f:
cmakelists = parsing.parse(f.read(), cmakelist_path)
cflags = []
dir_name = os.path.dirname(cmakelist_path)
for item in cmakelists:
if isinstance(item, parsing._Command) and item.name.lower() == 'include_directories':
for arg in item.body:
if arg.contents.startswith('/'):
arg_path = os.path.abspath(arg.contents)
else:
arg_path = os.path.join(os.path.abspath(dir_name), arg.contents)
if os.path.exists(arg_path):
cflags.append('-I{0}'.format(arg_path))
log("Adding cflag: -I{0}".format(arg_path), file=sys.stderr)
continue
else:
log("Could not find include path given: '{0}'".format(arg_path), file=sys.stderr)
if isinstance(item, parsing._Command) and item.name.lower() == 'add_subdirectory':
next_cmakelists_path = os.path.join(dir_name, item.body[0].contents, 'CMakeLists.txt')
if os.path.exists(next_cmakelists_path):
log("++ Recursing")
cflags.extend(parse_cmakelists(next_cmakelists_path) or [])
else:
log("Could not find subdir() CMakeLists.txt: '{0}'".format(next_cmakelists_path), file=sys.stderr)
if isinstance(item, parsing._Command) and item.name.lower() == 'include':
cmake_path = item.body[0].contents
if not cmake_path.startswith('/'):
cmake_path = os.path.join(dir_name, item.body[0].contents)
if os.path.exists(cmake_path):
log("++ Recursing")
cflags.extend(parse_cmakelists(cmake_path) or [])
else:
log("Could not find cmake include(): '{0}'".format(cmake_path), file=sys.stderr)
return list(set(cflags))
def get_cflags_from_cmakelists(pkg_dict):
cflags = []
for pkg_dir in pkg_dict.keys():
cmakelist_path = os.path.join(pkg_dir, 'CMakeLists.txt')
if os.path.exists(cmakelist_path):
cflags.extend(parse_cmakelists(cmakelist_path) or [])
return cflags
def main(sysargs=None):
parser = argparse.ArgumentParser(description="Creates a sublime text 2 project from a catkin workspace")
parser.add_argument('source_space', default=None, nargs='?')
parser.add_argument('--verbose', '-v', default=False, action='store_true')
parser.add_argument('--build-space', '-b', help="use the build space to gather flags (gets flags from ${..} too)")
parser.add_argument('--cflags-only', default=False, action='store_true')
args = parser.parse_args(sysargs)
global verbose
verbose = args.verbose
source_space = os.getcwd() if args.source_space is None else args.source_space
assert os.path.exists(source_space), "Source space does not exist '{0}'".format(source_space)
pkg_dict = find_packages(source_space)
assert pkg_dict, "No packages found for source space '{0}'".format(source_space)
if args.build_space:
assert os.path.exists(args.build_space), "Build space does not exist '{0}'".format(args.build_space)
cflags = get_cflags_from_buildspace(pkg_dict, args.build_space)
else:
cflags = get_cflags_from_cmakelists(pkg_dict)
cflags.append('-I/usr/local/include')
cflags = list(set(cflags))
if args.cflags_only:
for cflag in cflags:
print(cflag)
return
project = {
'word_wrap': 'on',
'wrap_width': 120,
'rulers': [79, 120],
'folders': [{'path': os.path.relpath(source_space, os.getcwd())}],
'settings': {'sublimeclang_options': cflags}
}
print(json.dumps(project, indent=8))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment