# GLFW and CMake starter

**URL:** <https://discourse.glfw.org/t/glfw-and-cmake-starter/1489>\
**Category:** share\
**Created:** [February 10, 2020, 8:06pm UTC](https://discourse.glfw.org/t/glfw-and-cmake-starter/1489 "2020-02-10T20:06:32Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dougbinks](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/dougbinks/32/39_2.png) [@dougbinks](https://discourse.glfw.org/u/dougbinks)\
**Post date:** [February 10, 2020, 8:06pm UTC](https://discourse.glfw.org/t/glfw-and-cmake-starter/1489/1 "2020-02-10T20:06:33Z")

</div>

We’ve put together a CMake starter project for anyone who wants to use GLFW and needs help getting started / creating a project:

> **[juliettef/GLFW-CMake-starter](https://github.com/juliettef/GLFW-CMake-starter)**
>
> Use CMake to create a project with GLFW - Multi-platform Windows, Linux and MacOS. - juliettef/GLFW-CMake-starter

Thanks to everyone who supports us on Patreon / GitHub and made this possible!  
Patreon: [https://www.patreon.com/enkisoftware](https://www.patreon.com/enkisoftware)  
Github Sponsors: [https://github.com/sponsors/dougbinks](https://github.com/sponsors/dougbinks)

---

<div class="post-metadata">

**Author:** ![elSomewhere](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/elsomewhere/32/531_2.png) [@elSomewhere](https://discourse.glfw.org/u/elSomewhere)\
**Post date:** [June 2, 2021, 12:01pm UTC](https://discourse.glfw.org/t/glfw-and-cmake-starter/1489/2 "2021-06-02T12:01:53Z")

</div>

Hi,

This is a great kit. I can get the default repo easily to work and cmake is daunting for beginners.

I am however having trouble re-writing the main.cpp so that it runs the quick tutorial example:  
[https://www.glfw.org/docs/latest/quick.html](https://www.glfw.org/docs/latest/quick.html)

basically, these 2 includes from the quick example are not working:

#include \<glad/gl.h\>  
#include “linmath.h”

I’ve toyed around with the toplevel CMakeLists.txt, but to no avail. The "./glfw folder in the kit appears to however contain the necessary sources. I suppose its just a target\_link and include definition thats missing.

Can anyone provide the correct CMakeLists.txt so that GLFW-CMake-starter will run this simple example program?

(copy of the source from above link)

```auto
#include <glad/gl.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>

#include "linmath.h"

#include <stdlib.h>
#include <stdio.h>

static const struct
{
    float x, y;
    float r, g, b;
} vertices[3] =
        {
                { -0.6f, -0.4f, 1.f, 0.f, 0.f },
                { 0.6f, -0.4f, 0.f, 1.f, 0.f },
                { 0.f, 0.6f, 0.f, 0.f, 1.f }
        };

static const char* vertex_shader_text =
        "#version 110\n"
        "uniform mat4 MVP;\n"
        "attribute vec3 vCol;\n"
        "attribute vec2 vPos;\n"
        "varying vec3 color;\n"
        "void main()\n"
        "{\n"
        " gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n"
        " color = vCol;\n"
        "}\n";

static const char* fragment_shader_text =
        "#version 110\n"
        "varying vec3 color;\n"
        "void main()\n"
        "{\n"
        " gl_FragColor = vec4(color, 1.0);\n"
        "}\n";

static void error_callback(int error, const char* description)
{
    fprintf(stderr, "Error: %s\n", description);
}

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GLFW_TRUE);
}

int main(void)
{
    GLFWwindow* window;
    GLuint vertex_buffer, vertex_shader, fragment_shader, program;
    GLint mvp_location, vpos_location, vcol_location;

    glfwSetErrorCallback(error_callback);

    if (!glfwInit())
        exit(EXIT_FAILURE);

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);

    window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    glfwSetKeyCallback(window, key_callback);

    glfwMakeContextCurrent(window);
    gladLoadGL(glfwGetProcAddress);
    glfwSwapInterval(1);

    // NOTE: OpenGL error checks have been omitted for brevity

    glGenBuffers(1, &vertex_buffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL);
    glCompileShader(vertex_shader);

    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL);
    glCompileShader(fragment_shader);

    program = glCreateProgram();
    glAttachShader(program, vertex_shader);
    glAttachShader(program, fragment_shader);
    glLinkProgram(program);

    mvp_location = glGetUniformLocation(program, "MVP");
    vpos_location = glGetAttribLocation(program, "vPos");
    vcol_location = glGetAttribLocation(program, "vCol");

    glEnableVertexAttribArray(vpos_location);
    glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE,
                          sizeof(vertices[0]), (void*) 0);
    glEnableVertexAttribArray(vcol_location);
    glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE,
                          sizeof(vertices[0]), (void*) (sizeof(float) * 2));

    while (!glfwWindowShouldClose(window))
    {
        float ratio;
        int width, height;
        mat4x4 m, p, mvp;

        glfwGetFramebufferSize(window, &width, &height);
        ratio = width / (float) height;

        glViewport(0, 0, width, height);
        glClear(GL_COLOR_BUFFER_BIT);

        mat4x4_identity(m);
        mat4x4_rotate_Z(m, m, (float) glfwGetTime());
        mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f);
        mat4x4_mul(mvp, p, m);

        glUseProgram(program);
        glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp);
        glDrawArrays(GL_TRIANGLES, 0, 3);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwDestroyWindow(window);

    glfwTerminate();
    exit(EXIT_SUCCESS);
}

```

---

<div class="post-metadata">

**Author:** ![dougbinks](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.glfw.org/dougbinks/32/39_2.png) [@dougbinks](https://discourse.glfw.org/u/dougbinks)\
**Post date:** [June 2, 2021, 12:42pm UTC](https://discourse.glfw.org/t/glfw-and-cmake-starter/1489/3 "2021-06-02T12:42:32Z")

</div>

Hi @elSomewhere,

Welcome to the GLFW forum, glad you liked our starter example. The problem with adding includes is that the build needs to know where to find them. You can use the older cmake command `include_directories` or the more recent `target_include_directories` to do this.

Using GLAD also requires the source code `glad_gl.c` to compile.

If you look at the file [CMakeLists.txt in the GLFW example folder](https://github.com/glfw/glfw/blob/d973acc123826666ecc9e6fd475682e3d84c54a6/examples/CMakeLists.txt) you can see how this is done.

I’ve modified the starter to add this and got your code working. The CMakeLists.txt I used is below:

```auto
cmake_minimum_required( VERSION 3.1 )

project( GLFW-CMake-starter )

find_package( OpenGL REQUIRED )

include_directories( ${OPENGL_INCLUDE_DIRS} )

set( GLFW_BUILD_DOCS OFF CACHE BOOL "GLFW lib only" )
set( GLFW_INSTALL OFF CACHE BOOL "GLFW lib only" )

add_subdirectory( glfw )

if( MSVC )
    SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:mainCRTStartup" )
endif()

set(GLAD_GL "${GLFW_SOURCE_DIR}/deps/glad/gl.h"
            "${GLFW_SOURCE_DIR}/deps/glad_gl.c")

set( GLFW-CMAKE-STARTER-SRC
     main.cpp
     ${GLAD_GL}
     )
     
add_executable( GLFW-CMake-starter WIN32 ${GLFW-CMAKE-STARTER-SRC} )
target_link_libraries( GLFW-CMake-starter ${OPENGL_LIBRARIES} glfw )
target_include_directories(GLFW-CMake-starter PRIVATE ${GLFW_SOURCE_DIR}/deps)
if( MSVC )
    if(${CMAKE_VERSION} VERSION_LESS "3.6.0") 
        message( "\n\t[WARNING]\n\n\tCMake version lower than 3.6.\n\n\t - Please update CMake and rerun; OR\n\t - Manually set 'GLFW-CMake-starter' as StartUp Project in Visual Studio.\n" )
    else()
        set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT GLFW-CMake-starter )
    endif()
endif()

```
