Rosanswers logo

I have a python package and want to copy a folder "models", that have subfolders, to installation path. In setup.py file I have tried to do that including the following lines of code:

        ['resource/' + package_name]),
    ('share/' + package_name, ['package.xml']),
    (os.path.join('share', package_name, 'models'), glob('models/**', recursive=True)),]

But when I build the package I get this error: "error: can't copy 'models/': doesn't exist or not a regular file".

Please, could someone tell me how I can do it?

Thank you very much in advance for your help.

Originally posted by joseecm on ROS Answers with karma: 130 on 2022-03-09

Post score: 2

Original comments

Comment by scottie on 2023-05-18:
Are you trying to package this code with a wheel or debian? If you're using debian, you can use the install(DIRECTORY) command in CMakeLists.txt to copy folders.

Comment by joseecm on 2023-05-27:
Hello @scotie, thanks for your answer. My package is a python package, so It doesn't have a CMakeLists.txt.


2 Answers 2


Rosanswers logo

I have finally managed to solve the problem by creating a function that reads the directory tree and includes the information in DATA_FILES. Here is an example in case someone finds it useful. In the code the "models/" and "worlds/" folders contain subfolders. If anyone knows a simpler way to do this I would be very grateful if you would share the information.

import os
from glob import glob
from setuptools import setup

package_name = 'myrobot_gazebo'

            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),

def package_files(data_files, directory_list):

    paths_dict = {}

    for directory in directory_list:
        for (path, directories, filenames) in os.walk(directory):

            for filename in filenames:

                file_path = os.path.join(path, filename)
                install_path = os.path.join('share', package_name, path)
                if install_path in paths_dict.keys():
                    paths_dict[install_path] = [file_path]
    for key in paths_dict.keys():
        data_files.append((key, paths_dict[key]))

    return data_files

    data_files=package_files(data_files, ['models/', 'launch/', 'worlds/']),
    maintainer_email='[email protected]',
    description='TODO: Package description',
    license='TODO: License declaration',
        'console_scripts': [

Best regards.

Originally posted by joseecm with karma: 130 on 2022-03-11

This answer was ACCEPTED on the original site

Post score: 4


For anyone who stumbles upon this in 2023. You can also use the following list comprehension to generate the tuples:

[(os.path.join('share', package_name, os.path.split(path)[0]), [path]) for path in glob.glob('models/**', recursive=True)]

Then just concatinate it with the data files list.

Best regards.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.