Search code examples
pythoncmakeprotocol-buffers

How to generate __init__.py in all subdirectories of current directory in cmake?


I use an out-of-tree builds with CMake. I have a CMake custom command that generates *_pb2.py files from proto-files. Since proto-files may reside in an unknown number of subdirectories (package namespace), like $SRC/package1/package2/file.proto, then the build directory will contain something like $BLD/package1/package2/file_pb2.py.

I want to implicitly make packages from auto-generated *_pb2.py files and, thus, I want to automagically generate __init__.py files in all subfolders ($BLD/package1, $BLD/package1/package2, etc.) and then install them.

How can I do that?

P.S. I've tried macro from CMake : How to get the name of all subdirectories of a directory? (changed GLOB to GLOB_RECURSE) but it returns only subdirs that contain files. I can't get package1 subdir from example above.


Solution

  • The following should give you a list of directories as required in the variable AllPaths:

    # Get paths to all .py files (relative to build dir)
    file(GLOB_RECURSE SubDirs RELATIVE ${CMAKE_BINARY_DIR} "${CMAKE_BINARY_DIR}/*.py")
    # Clear the variable AllPaths ready to take the list of results
    set(AllPaths)
    foreach(SubDir ${SubDirs})
      # Strip the filename from the path
      get_filename_component(SubDir ${SubDir} PATH)
      # Change the path to a semi-colon separated list
      string(REPLACE "/" ";" PathParts ${SubDir})
      # Incrementally rebuild path, appending each partial path to list of results
      set(RebuiltPath ${CMAKE_BINARY_DIR})
      foreach(PathPart ${PathParts})
        set(RebuiltPath "${RebuiltPath}/${PathPart}")
        set(AllPaths ${AllPaths} ${RebuiltPath})
      endforeach()
    endforeach()
    # Remove duplicates
    list(REMOVE_DUPLICATES AllPaths)