diff --git a/ros2pkg/ros2pkg/api/create.py b/ros2pkg/ros2pkg/api/create.py index 1bbecf8e2..7b3a3c6b1 100644 --- a/ros2pkg/ros2pkg/api/create.py +++ b/ros2pkg/ros2pkg/api/create.py @@ -98,7 +98,7 @@ def _create_template_file( _expand_template(template_path, template_config, output_file_path) -def create_package_environment(package, destination_directory): +def create_package_environment(package, destination_directory, template_name): package_directory = _create_folder(package.name, destination_directory) package_xml_config = { @@ -123,9 +123,14 @@ def create_package_environment(package, destination_directory): source_directory = None include_directory = None if package.get_build_type() == 'cmake' or package.get_build_type() == 'ament_cmake': - print('creating source and include folder') - source_directory = _create_folder('src', package_directory) - include_directory = _create_folder(package.name, package_directory + os.sep + 'include') + if template_name == 'cmake': + print('creating source and include folder') + source_directory = _create_folder('src', package_directory) + include_directory = _create_folder(package.name, + package_directory + os.sep + 'include') + elif template_name == 'python': + print('creating source and tests folder') + source_directory = _create_folder(package.name, package_directory) if package.get_build_type() == 'ament_python': print('creating source folder') source_directory = _create_folder(package.name, package_directory) @@ -265,6 +270,23 @@ def populate_ament_cmake(package, package_directory, cpp_node_name, cpp_library_ cmakelists_config) +def populate_ament_cmake_python(package, package_directory, cpp_node_name, cpp_library_name): + cmakelists_config = { + 'project_name': package.name, + 'dependencies': [str(dep) for dep in package.build_depends], + 'cpp_node_name': cpp_node_name, + 'cpp_library_name': cpp_library_name, + } + + _create_template_file( + 'ament_cmake_python', + 'CMakeLists.txt.em', + package_directory, + 'CMakeLists.txt', + cmakelists_config + ) + + def populate_cpp_node(package, source_directory, cpp_node_name): cpp_node_config = { 'package_name': package.name, diff --git a/ros2pkg/ros2pkg/resource/ament_cmake_python/CMakeLists.txt.em b/ros2pkg/ros2pkg/resource/ament_cmake_python/CMakeLists.txt.em new file mode 100644 index 000000000..e9f0d042c --- /dev/null +++ b/ros2pkg/ros2pkg/resource/ament_cmake_python/CMakeLists.txt.em @@ -0,0 +1,110 @@ +cmake_minimum_required(VERSION 3.8) +project(@(project_name)) + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +find_pacakge(ament_cmake_python REQUIRED) +@[if cpp_library_name]@ +find_package(ament_cmake_ros REQUIRED) +@[end if]@ +@[if dependencies]@ +@[ for dep in dependencies]@ +find_package(@dep REQUIRED) +@[ end for]@ +@[else]@ +# uncomment the following section in order to fill in +# further dependencies manually. +# find_package( REQUIRED) +@[end if]@ +@[if cpp_library_name]@ + +add_library(@(cpp_library_name) src/@(cpp_library_name).cpp) +add_library(@(project_name)::@(cpp_library_name) ALIAS @(cpp_library_name)) +target_compile_features(@(cpp_library_name) PUBLIC c_std_99 cxx_std_17) # Require C99 and C++17 +target_include_directories(@(cpp_library_name) PUBLIC + $ + $) +@[ if dependencies]@ +target_link_libraries( + @(cpp_library_name) PUBLIC +@[ for dep in dependencies]@ + ${@(dep)_TARGETS} +@[ end for]@ +) +@[ end if]@ + +# Causes the visibility macros to use dllexport rather than dllimport, +# which is appropriate when building the dll but not consuming it. +target_compile_definitions(@(cpp_library_name) PRIVATE "@(project_name.upper())_BUILDING_LIBRARY") + +install( + DIRECTORY include/ + DESTINATION include/${PROJECT_NAME} +) +install( + TARGETS @(cpp_library_name) + EXPORT export_${PROJECT_NAME} + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin +) +@[end if]@ +@[if cpp_node_name]@ + +add_executable(@(cpp_node_name) src/@(cpp_node_name).cpp) +target_include_directories(@(cpp_node_name) PUBLIC + $ + $) +@[ if cpp_library_name]@ +target_link_libraries(@(cpp_node_name) @(cpp_library_name)) +@[ else]@ +target_compile_features(@(cpp_node_name) PUBLIC c_std_99 cxx_std_17) # Require C99 and C++17 +@[ if dependencies]@ +target_link_libraries( + @(cpp_node_name) +@[ for dep in dependencies]@ + ${@(dep)_TARGETS} +@[ end for]@ +) +@[ end if]@ +@[ end if]@ + +install(TARGETS @(cpp_node_name) + DESTINATION lib/${PROJECT_NAME}) +@[end if]@ + +ament_python_install_package(${PROJECT_NAME}) + +if(BUILD_TESTING) + find_package(ament_cmake_pytest REQUIRED) + + # Automatically find all test_*.py files in the tests/ directory + file(GLOB _pytest_tests "tests/test_*.py") + + foreach(_test_path ${_pytest_tests}) + get_filename_component(_test_name ${_test_path} NAME_WE) + ament_add_pytest_test(${_test_name} ${_test_path} + APPEND_ENV PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR} + TIMEOUT 60 + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + endforeach() +endif() +@[if cpp_library_name]@ + +ament_export_include_directories( + "include/${PROJECT_NAME}" +) +ament_export_libraries( + @(cpp_library_name) +) +ament_export_targets( + export_${PROJECT_NAME} +) +@[end if]@ + +ament_package() diff --git a/ros2pkg/ros2pkg/resource/ament_cmake_python/__init__.py b/ros2pkg/ros2pkg/resource/ament_cmake_python/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ros2pkg/ros2pkg/verb/create.py b/ros2pkg/ros2pkg/verb/create.py index ef2df5ad9..af3a281ff 100644 --- a/ros2pkg/ros2pkg/verb/create.py +++ b/ros2pkg/ros2pkg/verb/create.py @@ -28,6 +28,7 @@ from ros2pkg.api.create import create_package_environment from ros2pkg.api.create import populate_ament_cmake +from ros2pkg.api.create import populate_ament_cmake_python from ros2pkg.api.create import populate_ament_python from ros2pkg.api.create import populate_cmake from ros2pkg.api.create import populate_cpp_library @@ -71,6 +72,12 @@ def add_arguments(self, parser, cli_name): default='ament_cmake', choices=['cmake', 'ament_cmake', 'ament_python'], help='The build type to process the package with') + parser.add_argument( + '--template-name', + default='cmake', + choices=['cmake', 'python'], + help='The template type to create the package with' + ) parser.add_argument( '--dependencies', nargs='+', @@ -136,14 +143,23 @@ def get_git_config(key: str) -> Optional[str]: buildtool_depends = [] if args.build_type == 'ament_cmake': - if args.library_name: - buildtool_depends = ['ament_cmake_ros'] - else: - buildtool_depends = ['ament_cmake'] + if args.template_name == 'cmake': + if args.library_name: + buildtool_depends = ['ament_cmake_ros'] + else: + buildtool_depends = ['ament_cmake'] + elif args.template_name == 'python': + if args.library_name: + buildtool_depends = ['ament_cmake_ros', 'ament_cmake_python'] + else: + buildtool_depends = ['ament_cmake', 'ament_cmake_python'] test_dependencies = [] if args.build_type == 'ament_cmake': - test_dependencies = ['ament_lint_auto', 'ament_lint_common'] + if args.template_name == 'cmake': + test_dependencies = ['ament_lint_auto', 'ament_lint_common'] + elif args.template_name == 'python': + test_dependencies = [] if args.build_type == 'ament_python': test_dependencies = ['ament_copyright', 'ament_flake8', 'ament_pep257', 'ament_xmllint', 'python3-pytest'] @@ -189,7 +205,7 @@ def get_git_config(key: str) -> Optional[str]: print('library_name:', library_name) package_directory, source_directory, include_directory = \ - create_package_environment(package, args.destination_directory) + create_package_environment(package, args.destination_directory, args.template_name) if not package_directory: return 'unable to create folder: ' + args.destination_directory @@ -197,7 +213,14 @@ def get_git_config(key: str) -> Optional[str]: populate_cmake(package, package_directory, node_name, library_name) if args.build_type == 'ament_cmake': - populate_ament_cmake(package, package_directory, node_name, library_name) + if args.template_name == 'cmake': + populate_ament_cmake(package, package_directory, node_name, library_name) + elif args.template_name == 'python': + populate_ament_cmake_python(package, + package_directory, + source_directory, + node_name + ) if args.build_type == 'ament_python': if not source_directory: