docs: def build_stack_docs(root_project_dir, skippedNames=None):
      """Build stack Sphinx documentation (main entrypoint).
  
      Parameters
      ----------
      root_project_dir : `str`
          Path to the root directory of the main documentation project. This
          is the directory containing the ``conf.py`` file.
      skippedNames : `list`, optional
          Optional list of packages to skip while creating symlinks.
      """
      logger = logging.getLogger(__name__)
  
      # Create the directory where module content is symlinked
      # NOTE: this path is hard-wired in for pipelines.lsst.io, but could be
      # refactored as a configuration.
      root_modules_dir = os.path.join(root_project_dir, 'modules')
      if os.path.isdir(root_modules_dir):
          logger.info('Deleting any existing modules/ symlinks')
          remove_existing_links(root_modules_dir)
      else:
          logger.info('Creating modules/ dir at {0}'.format(root_modules_dir))
          os.makedirs(root_modules_dir)
  
      # Create directory for package content
      root_packages_dir = os.path.join(root_project_dir, 'packages')
      if os.path.isdir(root_packages_dir):
          # Clear out existing module links
          logger.info('Deleting any existing packages/ symlinks')
          remove_existing_links(root_packages_dir)
      else:
          logger.info('Creating packages/ dir at {0}'.format(root_packages_dir))
          os.makedirs(root_packages_dir)
  
      # Ensure _static directory exists (but do not delete any existing
      # directory contents)
      root_static_dir = os.path.join(root_project_dir, '_static')
      if os.path.isdir(root_static_dir):
          # Clear out existing directory links
          logger.info('Deleting any existing _static/ symlinks')
          remove_existing_links(root_static_dir)
      else:
          logger.info('Creating _static/ at {0}'.format(root_static_dir))
          os.makedirs(root_static_dir)
  
      # Find package setup by EUPS
      packages = discover_setup_packages()
  
      # Get packages explicitly required in the table file to filter out
      # implicit dependencies later.
      table_path = find_table_file(root_project_dir)
      with open(table_path) as fp:
          table_data = fp.read()
      listed_packages = list_packages_in_eups_table(table_data)
  
      # Link to documentation directories of packages from the root project
      for package_name, package_info in packages.items():
          if package_name not in listed_packages:
              logger.debug(
                  'Filtering %s from build since it is not explictly '
                  'required by the %s table file.',
                  package_name, table_path)
              continue
          try:
              package_docs = find_package_docs(
                  package_info['dir'],
                  skippedNames=skippedNames)
          except NoPackageDocs as e:
              logger.debug(
                  'Skipping {0} doc linking. {1}'.format(package_name,
                                                         str(e)))
              continue
  
          link_directories(root_modules_dir, package_docs.module_dirs)
          link_directories(root_packages_dir, package_docs.package_dirs)
          link_directories(root_static_dir, package_docs.static_dirs)
  
      # Trigger the Sphinx build
      return_code = run_sphinx(root_project_dir)
      return return_code