Search code examples
c++cmakecompilationlinkerinclude

Compilation order and effect of unused files in C++


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"):

  1. Can I ensure compilation order somehow to avoid problems in the future?
  2. 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 to ThirdPartySetup.txt "feels" wrong.
  3. 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.