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.

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