Skip to content

Implement CMake support - #115

Open
ednolan wants to merge 1 commit into
mpark:masterfrom
ednolan:enolan_cmake8
Open

Implement CMake support#115
ednolan wants to merge 1 commit into
mpark:masterfrom
ednolan:enolan_cmake8

Conversation

@ednolan

@ednolan ednolan commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

This use case comes out of the Beman project. So far most users of mpark/wg21 maintain their papers in separate repositories from those papers' reference implementations. For the Beman project, I wanted to make it possible to update the paper and reference implementation in lockstep by keeping them in the same repository.

The issue is that the C++ reference implementations use CMake for their build system and mpark/wg21 currently hard depends on Make. At first, I attempted to work around this by pulling in mpark/wg21 via FetchContent and adding a custom command that called out to Make for building:

FetchContent_Declare(
    wg21
    GIT_REPOSITORY https://github.com/mpark/wg21.git
    GIT_TAG 49c655869c14d80645962b6fceb503249f69bc9e
    EXCLUDE_FROM_ALL
)
FetchContent_MakeAvailable(wg21)

add_custom_command(
    OUTPUT P2728.html
    COMMAND
        ${CMAKE_COMMAND} -E env SRCDIR=${CMAKE_CURRENT_SOURCE_DIR}
        OUTDIR=${CMAKE_CURRENT_BINARY_DIR} make -f ${wg21_SOURCE_DIR}/Makefile
        html
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/P2728.md
    VERBATIM
)
add_custom_target(p2728 ALL DEPENDS P2728.html)

But this has various disadvantages. Although the CMake best practice is to handle dependencies in terms of packages, and rely on the user to configure their environment such that those packages are made available to CMake, by unconditionally using FetchContent here we bypass CMake's package system and just pull mpark/wg21 down as a subdirectory. Then, the mpark/wg21 Makefile pulls down its own dependencies-- pandoc and the Python packages via venv-- also invisibly to CMake and against best practices. Both the dependencies that mpark/wg21 downloads and the reference data files it generates are added to subdirectories of the mpark/wg21 checkout instead of a separate build tree directory. And the custom command and target are easy to get wrong.

This commit adds CMake machinery to mpark/wg21 as a pure addition; existing users of the Makefile aren't affected. The updated CMake corresponding to the excerpt above is now simply:

find_package(MparkWg21 REQUIRED)

wg21_add_paper(P2728 ALL)

You can either satisfy the find_package call by cmake --install-ing mpark/wg21 into your environment, or replace the find_package call with FetchContent; both are supported.

The following files are added:

  • CMakeLists.txt: Defines the project and configures installation and add_subdirectory/FetchContent support

  • cmake/FindMparkWg21.cmake: Implements the MparkWg21 CMake package discovery logic and loads the wg21_add_paper API

  • cmake/MparkWg21Config.cmake: Makes installed copies findable via CMAKE_PREFIX_PATH

  • cmake/FindPandoc.cmake: Helper to detect the pandoc executable in the environment (since pandoc, as a Haskell package, doesn't ship CMake package-config files)

  • cmake/MparkWg21Helpers.cmake: Defines wg21_add_paper, runs dependency checks, and implements logic for invoking refs.py/srefs.py/srefs-md.py

  • cmake/render.cmake: Script for wrapping invocations of toc-depth.py and pandoc

Full disclosure: this change was produced using AI assistance, but I've gone over it closely. I've also verified that rendering tests/*.md with wg21_add_paper produces identical results to what the Makefile produces.

This use case comes out of the Beman project. So far most users of
mpark/wg21 maintain their papers in separate repositories from those
papers' reference implementations. For the Beman project, I wanted to
make it possible to update the paper and reference implementation in
lockstep by keeping them in the same repository.

The issue is that the C++ reference implementations use CMake for their
build system and mpark/wg21 currently hard depends on Make. At first, I
attempted to work around this by pulling in mpark/wg21 via FetchContent
and adding a custom command that called out to Make for building:

```
FetchContent_Declare(
    wg21
    GIT_REPOSITORY https://github.com/mpark/wg21.git
    GIT_TAG 49c6558
    EXCLUDE_FROM_ALL
)
FetchContent_MakeAvailable(wg21)

add_custom_command(
    OUTPUT P2728.html
    COMMAND
        ${CMAKE_COMMAND} -E env SRCDIR=${CMAKE_CURRENT_SOURCE_DIR}
        OUTDIR=${CMAKE_CURRENT_BINARY_DIR} make -f ${wg21_SOURCE_DIR}/Makefile
        html
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/P2728.md
    VERBATIM
)
add_custom_target(p2728 ALL DEPENDS P2728.html)
```

But this has various disadvantages. Although the CMake best practice is
to handle dependencies in terms of packages, and rely on the user to
configure their environment such that those packages are made available
to CMake, by unconditionally using FetchContent here we bypass CMake's
package system and just pull mpark/wg21 down as a subdirectory. Then,
the mpark/wg21 Makefile pulls down its own dependencies-- pandoc and the
Python packages via venv-- also invisibly to CMake and against best
practices. Both the dependencies that mpark/wg21 downloads and the
reference data files it generates are added to subdirectories of the
mpark/wg21 checkout instead of a separate build tree directory. And the
custom command and target are easy to get wrong.

This commit adds CMake machinery to mpark/wg21 as a pure addition;
existing users of the Makefile aren't affected. The updated CMake
corresponding to the excerpt above is now simply:

```
find_package(MparkWg21 REQUIRED)

wg21_add_paper(P2728 ALL)
```

You can either satisfy the `find_package` call by `cmake --install`-ing
mpark/wg21 into your environment, or replace the `find_package` call
with `FetchContent`; both are supported.

The following files are added:

- CMakeLists.txt: Defines the project and configures installation and
  add_subdirectory/FetchContent support

- cmake/FindMparkWg21.cmake: Implements the MparkWg21 CMake package
  discovery logic and loads the wg21_add_paper API

- cmake/MparkWg21Config.cmake: Makes installed copies findable via
  CMAKE_PREFIX_PATH

- cmake/FindPandoc.cmake: Helper to detect the pandoc executable in the
  environment (since pandoc, as a Haskell package, doesn't ship CMake
  package-config files)

- cmake/MparkWg21Helpers.cmake: Defines wg21_add_paper, runs dependency
  checks, and implements logic for invoking refs.py/srefs.py/srefs-md.py

- cmake/render.cmake: Script for wrapping invocations of toc-depth.py
  and pandoc

Full disclosure: this change was produced using AI assistance, but I've
gone over it closely. I've also verified that rendering tests/*.md with
wg21_add_paper produces identical results to what the Makefile produces.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant