Lehks
Lehks

Reputation: 3166

CMake: Generate single header file

I am currently in the process of writing a Utility Library that will ship with a pre-compiled DLL file and the header files of the library. As of now, there are a whole bunch of header files, but I would like to compile all of them into a single header file (somewhat like pre-processing only the #include directives).

I was wondering, if and how such a generation would be possible using CMake.

Sincerely, Lehks

Upvotes: 9

Views: 2458

Answers (1)

Clare Macrae
Clare Macrae

Reputation: 3799

These tools are not specific to CMake, but can be invoked inside CMake.

I recently collected together some links to create a single-header release for ApprovalTests.cpp.

I initially recorded them in a comment on an issue in podsiadly/ImageApprovals: this answer is to make that info easier to share.

C++ - Single-header Release Scripts

Options:

  • Some of these tools only pull together header files, which is fine if your master source code is header-only.
  • Others also have a way to pull in .cpp files, either adding inline to the output, or putting all the code from .cpp files into one location in the output, this is compiled only once.
    • This is how Catch2's CATCH_CONFIG_MAIN works, for example.

Claiming to be general

  • quom
    • Uses Python
    • Does not mention adding inline
  • Heady
    • C++ program
    • Does specifically explain pulling in .cpp files
    • Does acknowledge need to add inline to some functions from .cpp: has a (customisable) convention for putting inline_t in your source code, for where inline should be included in the generated header
  • Corrade Acme
    • Uses Python
    • You create a kind of template file that contains #include lines, and various template mark-up, Pragmas and so-on
    • Does not mention pulling in .cpp files?
    • Does not mention adding inline

Library Specific

  • Catch2
  • ImageApprovals
    • single_header.py
    • Has tests: single_header_test.py
    • Should be reusable
    • The script:
      • goes over all headers/sources
      • removes include guards and relative #includes (in preprocess_file)
      • sorts files topologically (if a.hpp includes b.hpp then b.hpp will be processed first, SingleHeaderGen.generate)
      • and finally merges everything into a single header, with public headers first and implementation files inside #ifdef/#endif.
      • code from .cpp files will be compiled only once, when ImageApprovals_IMPLEMENT is defined
  • jfalcou/spy
    • embed.py
    • Removes comments
    • Removes extra include guards
    • Doesn't deal with .cpp files
  • ApprovalTests.cpp
    • Implemented in build/scripts/
    • Doesn't deal with .cpp files
    • Relevant scripts:
    • code_generation.py
    • single_header_file.py
    • embed.py
      • This is a modified version of the jfalcou/spy script above.
      • Retains comments
      • Has option to discard particular patterns of lines ("discardables")
      • Includes names of original files in comments

Upvotes: 3

Related Questions