1

I am writing a header-only library using C++17. I would like to include it in a "dummy" source file:

#include "my/library.h"
// EOF

The purpose is to ensure the library properly includes all of its dependencies. I also want to run static analyzers on it and compile it with as many compiler checks enabled as is practical.

To create a normal executable target I need to add the main() function, otherwise the linking stage will fail. I guess I can also create a static library target, which should work correctly, although it will create an artifact I do not need.

Is there any other alternative?

Krzysiek Karbowiak
  • 1,655
  • 1
  • 9
  • 17
  • 1
    Even if you create a library, you have to load it from a program that has a main (or loaded from another library which will be loaded by an exec who has a main function). I don't understand your question – Landstalker Mar 02 '20 at 09:28
  • Maybe just add unit tests, so library gets compiled as side effect. – R2RT Mar 02 '20 at 09:36
  • I need to verify that the code in the library: a) has no missing includes, b) compiles cleanly and without warnings, c) passes static analysis. None of these checks requires building an executable. – Krzysiek Karbowiak Mar 02 '20 at 09:36
  • I do have unit tests. In fact, I develop the library in TDD with tight red-green-refactor cycles. I do not want compilation as a side effect. I want it as a (almost) sole purpose and this is why I want a separate target. – Krzysiek Karbowiak Mar 02 '20 at 09:44
  • @KrzysiekKarbowiak But in this case, how about : linking errors ? If you don't link binaries, how are you going to check for link errors? – Landstalker Mar 02 '20 at 10:33
  • @Landstalker: thanks for your interest in this topic. Linking errors are things to check as well, but are different kind of issues and are out of scope of my question. I will tackle them separately. – Krzysiek Karbowiak Mar 02 '20 at 11:39
  • Why is this tagged with CMake? Are you using CMake to manage your buildsystem generation? Not sure how this fits in with the question.. – Kevin Mar 02 '20 at 12:55
  • @squareskittles: Yes, I am using CMake for buildsystem generation and build itself. For convenience, on all the platforms that I use (currently Linux and Windows) i just do: `cmake --build .`. – Krzysiek Karbowiak Mar 02 '20 at 12:59
  • 1
    You could tell CMake to build this into an [Object library](https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#object-libraries), essentially just the `.o` or `.obj` object file. Use this: `add_library(MyObj OBJECT library.cpp)`, where `library.cpp` is your dummy source file. – Kevin Mar 02 '20 at 13:23
  • @squareskittles: Thanks! I was not aware of the Object library and this looks like it might be it. – Krzysiek Karbowiak Mar 02 '20 at 13:35
  • Wrote up a quick answer showing the usage for `OBJECT` targets. The documentation has further examples as well. Hope that is helpful! – Kevin Mar 02 '20 at 13:43

2 Answers2

1

Most compilers allow you to override the default extension for input types. If you just pass my/library.h as the input file to the compiler, it can compile that into a library.o or library.obj.

Note that short of compiling an executable, you can't be sure that your library.h is complete. In particular, C++ requires that non-inline static const class members are defined exactly once per program if they're odr-used. So if you forget inline in your library.h, you might not notice this in your simple test. And even if you'd add an empty main(), that still wouldn't odr-use those members.

MSalters
  • 173,980
  • 10
  • 155
  • 350
1

CMake can create a simple Object library, which will only be a .o or .obj file:

The OBJECT library type defines a non-archival collection of object files resulting from compiling the given source files.

To do this, use the OBJECT keyword with the add_library() command:

add_library(MyObj OBJECT ${CMAKE_CURRENT_SOURCE_DIR}/library.cpp)
target_include_directories(MyObj PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

You can later reference the object file(s) to be compiled into other libraries or executables:

add_library(MyLibrary STATIC 
    $<TARGET_OBJECTS:MyObj> 
    MyOtherSource.cpp 
    HelpersFunctions.cpp
)
Kevin
  • 16,549
  • 8
  • 60
  • 74