Compile error: undefined reference to class constructor even though it is included

Hey there!
I am a beginner learning how to use CMake in my VSCode C++ projects and I’m having some issues getting my code to compile properly. Intellisense doesn’t give me any errors.

When using CMake to build my project, it throws the following error: D:/Code/Projects/LearnOpenGL/src/main.cpp:34: undefined reference to `Shader::Shader(char const*, char const*)' This Shader class is declared in shader.h and defined in shader.cpp

After searching online, I found that including shader.cpp allows me to compile the file without issue. Is there something wrong with my CMakeLists.txt file to make it unable to be compiled?

Here is my project file structure:

TestProject
||.vscode
||build
||||autogenerated stuff here
||include
||||glad
||||||glad.h
||||GLFW
||||||glfw3.h
||||headers
||||||data.h
||||||func.h
||||||shader.h
||src
||main.cpp
||glad.c
||funcs
||||data.cpp
||||func.cpp
||||shader.cpp
||CMakeLists.txt

Here is my main.cpp

#include <iostream>
#include <fstream>
#include <streambuf>
#include <cmath>
#include <glad\glad.h>
#include <GLFW\glfw3.h>
#include "headers/func.h"
#include "headers/data.h"
#include "headers/shader.h"

int main(){

    ......
    Shader myShader("./shaders/vertexShader1.vert","./shaders/fragmentShader1.frag");

    while(!glfwWindowShouldClose(window)){
        ......
        myShader.use();
    }
    ......
    return 0; 
}

Here is my shader.h

#pragma once

#include <glad/glad.h> // include glad to get all the required OpenGL headers
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>

class Shader
{
public:
    // the program ID
    unsigned int ID;
  
    // constructor reads and builds the shader
    Shader(const char* vertexPath, const char* fragmentPath);
    // use/activate the shader
    void use();
    // utility uniform functions
    void setBool(const std::string &name, bool value) const;  
    void setInt(const std::string &name, int value) const;   
    void setFloat(const std::string &name, float value) const;
};
  

Here is my shader.cpp

#include <glad/glad.h> // include glad to get all the required OpenGL headers
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
class Shader
{
public:
    unsigned int ID;

    Shader(const char* vertexPath, const char* fragmentPath){
        ......
        //generates shaders from text here
    }

    void use(){
        ......
    }

    void setBool(const std::string &name, bool value) const{         
        ......
    }
    void setInt(const std::string &name, int value) const{ 
        ......
    }
    void setFloat(const std::string &name, float value) const{ 
        ......
    } 
};

Here is my CMakeLists.txt

cmake_minimum_required(VERSION 3.0.0)
project(rendering VERSION 0.1.0)

include_directories("${CMAKE_SOURCE_DIR}\\include")
set(CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}")

set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libgcc -static-libstdc++ -lwsock32 -lws2_32 ${CMAKE_CXX_STANDARD_LIBRARIES}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive")

set(HEADER_FILES 
include/headers/data.h
include/headers/func.h
include/headers/shader.h
include/glad/glad.h
)

set(SOURCE 
src/main.cpp
src/funcs/func.cpp
src/funcs/data.cpp
src/funcs/shader.cpp
)

set(LIBRARY 
OpenGL::GL
glad
glfw
)

find_package(OpenGL REQUIRED)
find_package(glfw3 REQUIRED)

add_library(glad STATIC src/glad.c)
add_executable(rendering "${SOURCE}")
#//target_include_directories(rendering PUBLIC "${CMAKE_SOURCE_DIR}\\include") #UNSURE WHETHER NEEDED
target_link_libraries(rendering "${LIBRARY}")

Thanks very much for reading!

You are redeclaring Shader in this file. You define declared class members with Shader:: in this instance:

Shader::Shader(const char*, const char*)
{
    // …
}
1 Like

Oh my, that’s a silly mistake I made.

Thank you very much for your help!