In my project I use a bit of third party code like Vulkan Memory Allocator or STB, which require to put a define before the first include of their header file. The VMA docu suggests to create an extra file for this purpose, and since I have several such demands, I decided to create a ThirdPartySetup.cpp
file:
#define VOLK_IMPLEMENTATION
#define VK_NO_PROTOTYPES
#include "volk.h"
#define VMA_IMPLEMENTATION
#include "vk_mem_alloc.h"
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define TINYOBJLOADER_IMPLEMENTATION
#include "tiny_obj_loader.h"
Now I obviously want to use this. I have a Renderer
class, which should be what any user uses to start up my project. Also, my project uses CMake.
I have now added my ThirdPartySetup.cpp
to the CMakeLists.txt
, such that it also appears in my project when creating a Visual Studio solution, and I’ve included the ThirdPartySetup.cpp
in my Renderer.cpp
(right after the class’s own header include, but the order probably doesn’t matter for my problem):
#include "Renderer.h"
#include "ThirdPartySetup.cpp"
// ... more includes
Renderer::Renderer(){...}
When compiling this, I get LNK 2005 linker errors for ThirdPartySetup.cpp about third party stuff already being defined in Renderer.obj. My assumption therefore is: Visual Studio compiles Renderer first, and then ThirdPartySetup. If I were to not use these defines (i.e. delete the ThirdPartySetup.cpp
file, I get a compilation error from VMA about having to put the defines before including vulkan.
However, if I simply let the ThirdPartySetup.cpp
file exist in the project without ever using it anywhere, it gets compiled without errors.
I’d be satisfied with that, but I doubt this is safe to do as the compilation error is (afaik) not guaranteed to always compile ThirdPartySetup before anything else.
Therefore my questions are (apart from the obvious "How to fix this"):
- Can I ensure compilation order somehow to avoid problems in the future?
- Can I use a file like my
ThirdPartySetup.cpp
as an include without it being compiled at all? I read somewhere (TM) that CMake only compiles files that have some sort of c++ extension, but just renaming my file toThirdPartySetup.txt
"feels" wrong. - What effects do files have that are compiled but not used anyway? It looks like the
#define
macros are used even though the file is not
>Solution :
The file you created is used both a source and a header file, at the same time. That will not work, all source files (translation units) that include it will have the definitions and implementations, as well as the source file itself if you try to build it as a source file.
Instead build it as a normal source file, and do not include it anywhere. Only include the actual header files, when and where they are needed.