I am working on a project in Visual Studio and I decided to reorganize a lot of my code. Unfortunately, I am running into problems with linking different headers and their cpp files.
I have one header file that contains the libraries which get passed down a chain of header files. I have no idea how this works, but I am able to get the contents to populate throughout all of the headers:
/* vkInstance.h */
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
/* code used other header files */
/* vkGraphicsPipeline.h */
#include "vkInstance.h" // gains access to <GLFW/glfw3.h> within "vkInstance.h"
#include "component.h" // gets access to <GLFW/glfw3.h> through #include "vkInstance.h"
/* other headers similar to component.h */
When the component header's content definitions are within the header file, elements of the <GLFW/glfw3.h>
file are defined. The component header also has some macro definitions:
/* component.h */
#ifndef hComponent
#define hComponent
struct exampleStruct {
exampleStruct(/* args */) {
/* constructor code containing <GLFW/glfw3.h> items */
}
void exampleFunc(/* args */) {
/* func code containing <GLFW/glfw3.h> items */
}
}
#endif
While the above usage of <GLFW/glfw3.h>
items is defined, I would like to move a lot of the definitions from my various header files to their cpp files, and that's where I start to run into problems:
/* component.h */
#ifndef hComponent
#define hComponent
struct exampleStruct {
exampleStruct(/* args */);
void exampleFunc(/* args */) {
/* func code containing <GLFW/glfw3.h> items */
}
}
#endif
/* component.cpp */
#include "component.h"
exampleStruct::exampleStruct(/* args */) {
/* constructor code containing <GLFW/glfw3.h> items */
}
void exampleStruct::exampleFunc(/* args */) {
/* func code containing <GLFW/glfw3.h> items */
}
Whereas I had access to <GLFW/glfw3.h>
definitions in the header file, I lose access to them in the cpp file, and the program fails to build.
I feel like I have a decent grasp on C++, but I am far from an expert, so please forgive me if I am missing an obvious solution. How can I avoid this problem and/or better organize my file structure?
Edit: Sorry for the delayed response, I've been able to figure out how to replicate the linking errors (LNK2005, LNK2001, and LNK2019) with a minimally reproducible program. This is a github page for it and here is a printout of the program contents:
/* main.cpp */
#include "Header2.h"
int main() {
library::object obj;
library::object1 obj1;
library::object2 obj2;
return 0;
}
/* Header.h */
#pragma once // tried with and without, no difference
#include <iostream>
namespace library {
template<typename T>
void print(T input);
void test()
{// definition in the header rather than cpp causes LNK2005,
// but I'm not sure why it does this.
std::cout << "This is a test." << std::endl;
}
struct object {
static inline int i = 1;
object();
~object() = default;
// if I place 'void test()' and it's definition here,
// then I don't get LNK2005
};
}
/* Header.cpp */
#include "Header.h"
library::object::object()
{
std::cout << "I am object!" << std::endl;
}
template<typename T>
void library::print(T input)
{
std::cout << "This is the input: " << input << std::endl;
}
/* Header1.h */
#include "Header.h"
namespace library {
struct object1 {
object1();
~object1() = default;
};
}
/* Header1.cpp */
#include "Header1.h"
#include <iostream>
library::object1::object1()
{
std::cout << "I am object1!\n";
library::print(object::i);
}
/* Header2.h */
#include "Header1.h"
namespace library {
struct object2 {
object2();
~object2() = default;
};
}
/* Header2.cpp */
#include "Header2.h"
// including "Header.h" did not fix LNK2001 or LNK2019
#include <iostream>
library::object2::object2()
{
std::cout << "I am object2!\n";
library::print(object::i);
}