diff --git a/cmake/catkin_python_setup.cmake b/cmake/catkin_python_setup.cmake index c0520c5c5..98d6396a2 100644 --- a/cmake/catkin_python_setup.cmake +++ b/cmake/catkin_python_setup.cmake @@ -103,6 +103,37 @@ function(catkin_python_setup) endforeach() endif() + # generate relay-script for each python module (and __init__.py files) if available + if(${PROJECT_NAME}_SETUP_PY_MODULES) + list(LENGTH ${PROJECT_NAME}_SETUP_PY_MODULES modules_count) + math(EXPR modules_range "${modules_count} - 1") + foreach(index RANGE ${modules_range}) + list(GET ${PROJECT_NAME}_SETUP_PY_MODULES ${index} module) + list(GET ${PROJECT_NAME}_SETUP_PY_MODULE_DIRS ${index} module_dir) + set(PYTHON_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/${module_dir}/${module}) + if(EXISTS ${PYTHON_SCRIPT}) + get_filename_component(path ${module} PATH) + file(MAKE_DIRECTORY "${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_PYTHON_DESTINATION}/${path}") + configure_file(${catkin_EXTRAS_DIR}/templates/relay.py.in + ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_PYTHON_DESTINATION}/${module} + @ONLY) + # relay parent __init__.py files if they exist + while(NOT "${path}" STREQUAL "") + set(PYTHON_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/${module_dir}/${path}/__init__.py) + if(EXISTS ${PYTHON_SCRIPT}) + file(MAKE_DIRECTORY "${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_PYTHON_DESTINATION}/${path}") + configure_file(${catkin_EXTRAS_DIR}/templates/relay.py.in + ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_PYTHON_DESTINATION}/${path}/__init__.py + @ONLY) + else() + message(WARNING "The module '${module_dir}/${module}' lacks an '__init__.py' file in the parent folder '${module_dir}/${path}' in project '${PROJECT_NAME}'") + endif() + get_filename_component(path ${path} PATH) + endwhile() + endif() + endforeach() + endif() + # generate relay-script for each python script foreach(script ${${PROJECT_NAME}_SETUP_PY_SCRIPTS}) get_filename_component(name ${script} NAME) diff --git a/cmake/interrogate_setup_dot_py.py b/cmake/interrogate_setup_dot_py.py index 8a3c2344b..26882f02a 100644 --- a/cmake/interrogate_setup_dot_py.py +++ b/cmake/interrogate_setup_dot_py.py @@ -83,7 +83,7 @@ def _get_locations(pkgs, package_dir): return locations -def generate_cmake_file(package_name, version, scripts, package_dir, pkgs): +def generate_cmake_file(package_name, version, scripts, package_dir, pkgs, modules): """ Generates lines to add to a cmake file which will set variables @@ -91,6 +91,7 @@ def generate_cmake_file(package_name, version, scripts, package_dir, pkgs): :param scripts: [list of str]: relative paths to scripts :param package_dir: {modulename: path} :pkgs: [list of str] python_packages declared in catkin package + :modules: [list of str] python modules """ prefix = '%s_SETUP_PY' % package_name result = [] @@ -129,6 +130,21 @@ def generate_cmake_file(package_name, version, scripts, package_dir, pkgs): result.append(r'set(%s_PACKAGES "%s")' % (prefix, ';'.join(pkgs))) result.append(r'set(%s_PACKAGE_DIRS "%s")' % (prefix, ';'.join(resolved_pkgs).replace("\\", "/"))) + + # skip modules which collide with package names + filtered_modules = [] + for modname in modules: + splits = modname.split('.') + # check all parents too + equals_package = [('.'.join(splits[:-i]) in locations) for i in range(len(splits))] + if any(equals_package): + continue + filtered_modules.append(modname) + module_locations = _get_locations(filtered_modules, package_dir) + + result.append(r'set(%s_MODULES "%s")' % (prefix, ';'.join(['%s.py' % m.replace('.', '/') for m in filtered_modules]))) + result.append(r'set(%s_MODULE_DIRS "%s")' % (prefix, ';'.join([module_locations[m] for m in filtered_modules]).replace("\\", "/"))) + return result @@ -155,6 +171,7 @@ def setup(*args, **kwargs): pkgs = kwargs.get('packages', []) scripts = kwargs.get('scripts', []) + modules = kwargs.get('py_modules', []) unsupported_args = [ 'entry_points', @@ -163,7 +180,6 @@ def setup(*args, **kwargs): 'ext_package', 'include_package_data', 'namespace_packages', - 'py_modules', 'setup_requires', 'use_2to3', 'zip_safe'] @@ -175,7 +191,8 @@ def setup(*args, **kwargs): version=version, scripts=scripts, package_dir=package_dir, - pkgs=pkgs) + pkgs=pkgs, + modules=modules) with open(outfile, 'w') as out: out.write('\n'.join(result)) diff --git a/cmake/templates/relay.py.in b/cmake/templates/relay.py.in new file mode 100644 index 000000000..5221f48dc --- /dev/null +++ b/cmake/templates/relay.py.in @@ -0,0 +1,4 @@ +# creates a relay to a python script source file, acting as that file. +# The purpose is that of a symlink +with open("@PYTHON_SCRIPT@", 'r') as fh: + exec(fh.read())