I'd like to package a library I'm working on as a header-only library to make it easier for clients to use. (It's small and there's really no reason to put it into a separate translation unit) However, I cannot simply put my code in headers because this violates C++'s one definition rule. (Assuming that the library header is included in multiple translation units of a client project)
How does one modify a library to make it header-only?
Creating a Header-Only CMake TargetBy specifying INTERFACE as the second parameter to add_library , we are no longer allowed to provide source files since the library is not meant to generate any build output.
In the context of the C or C++ programming languages, a library is called header-only if the full definitions of all macros, functions and classes comprising the library are visible to the compiler in a header file form.
Having a header-only library also means you don't have to worry about different platforms where the library might be used. When you separate the implementation, you usually do so to hide implementation details, and distribute the library as a combination of headers and libraries ( lib , dll 's or . so files).
You can use the inline
keyword:
// header.hpp (included into multiple translation units)
void foo_bad() {} // multiple definitions, one in every translation unit :(
inline void foo_good() {} // ok :)
inline
allows the linker to simply pick one definition and discard the rest.
(As such, if those definitions don't actually match, you get a good dose of undefined behavior...!)
As an aside, member functions defined within a class-type, are implicitly marked inline
:
struct myclass
{
void i_am_inline_implicitly()
{
// because my definition is here
}
void but_i_am_not();
void neither_am_i();
};
inline void myclass::but_i_am_not()
{
// but that doesn't mean my definition cannot be explicitly inline
}
void myclass::neither_am_i()
{
// but in this case, no inline for me :(
}
Use header guards as Liz suggests and don't forget to put "inline" before your function methods.
ie
#ifndef MY_HEADER_H_
#define MY_HEADER_H_
inline RetType FunctionName( ParamType1 param1, ParamType2 param2 )
{
// Function body
return retType;
}
#endif
Also, I think you'll need to avoid any use of global variables or static variables in your header-only-library code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With