8

the last few days i was messing with CMake, and everything worked fine, except that i can't find a way to link ImGUI with GLFW

Everything is build from source

Here is the error :

Consolidate compiler generated dependencies of target glad
[  2%] Built target glad
Consolidate compiler generated dependencies of target stb
[  5%] Built target stb
Consolidate compiler generated dependencies of target glfw
[ 29%] Built target glfw
Consolidate compiler generated dependencies of target imgui
[ 30%] Building CXX object CMakeFiles/imgui.dir/lib/imgui/imgui.cpp.o
[ 31%] Building CXX object CMakeFiles/imgui.dir/lib/imgui/imgui_demo.cpp.o
[ 33%] Building CXX object CMakeFiles/imgui.dir/lib/imgui/imgui_draw.cpp.o
[ 34%] Building CXX object CMakeFiles/imgui.dir/lib/imgui/imgui_tables.cpp.o
[ 36%] Building CXX object CMakeFiles/imgui.dir/lib/imgui/imgui_widgets.cpp.o
[ 37%] Building CXX object CMakeFiles/imgui.dir/lib/imgui/imgui_impl_glfw.cpp.o
/home/erik/Workspace/LearnOpenGL/lib/imgui/imgui_impl_glfw.cpp:45:10: fatal error: GLFW/glfw3.h: No such file or directory
   45 | #include <GLFW/glfw3.h>
      |          ^~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/imgui.dir/build.make:146: CMakeFiles/imgui.dir/lib/imgui/imgui_impl_glfw.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:228: CMakeFiles/imgui.dir/all] Error 2
make: *** [Makefile:156: all] Error 2

And here is my CMakeLists.txt :

cmake_minimum_required(VERSION 3.1)

project(LearnOpenGL)


set(SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/source")
set(LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib")

set(SOURCES "${SRC_DIR}/Main.cpp"
    )


add_executable(${PROJECT_NAME} ${SOURCES})

target_include_directories(${PROJECT_NAME} PRIVATE "${SRC_DIR}")

set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11)


# GLFW

set(GLFW_DIR "${LIB_DIR}/glfw")

set(GLFW_BUILD_EXAMPLES OFF CACHE INTERNAL "Build the GLFW example programs")
set(GLFW_BUILD_TESTS OFF CACHE INTERNAL "Build the GLFW test programs")
set(GLFW_BUILD_DOCS OFF CACHE INTERNAL "Build the GLFW documentation")
set(GLFW_INSTALL OFF CACHE INTERNAL "Generate installation target")

add_subdirectory("${GLFW_DIR}")

target_link_libraries(${PROJECT_NAME} "glfw" "${GLFW_LIBRARIES}")
target_include_directories(${PROJECT_NAME} PRIVATE "${GLFW_DIR}/include")
target_compile_definitions(${PROJECT_NAME} PRIVATE "GLFW_INCLUDE_NONE")


# Glad

set(GLAD_DIR "${LIB_DIR}/glad")

add_library("glad" "${GLAD_DIR}/src/glad.c")

target_include_directories("glad" PRIVATE "${GLAD_DIR}/include")
target_include_directories(${PROJECT_NAME} PRIVATE "${GLAD_DIR}/include")
target_link_libraries(${PROJECT_NAME} "glad" "${CMAKE_DL_LIBS}")


# GLM 

set(GLM_DIR "${LIB_DIR}/glm")

add_subdirectory(${GLM_DIR})

target_link_libraries(${PROJECT_NAME} "glm")


# STB

set(STB_DIR "${LIB_DIR}/stb")

add_library("stb" "${STB_DIR}/src/stb_image.cpp")

target_include_directories("stb" PRIVATE "${STB_DIR}/include")
target_include_directories(${PROJECT_NAME} PRIVATE "${STB_DIR}/include")
target_link_libraries(${PROJECT_NAME} "stb" "${CMAKE_DL_LIBS}")


# Freetype

set(FREETYPE_DIR "${LIB_DIR}/freetype")

add_subdirectory("${FREETYPE_DIR}")

target_link_libraries(${PROJECT_NAME} "${FREETYPE_LIBRARIES}")
target_include_directories(${PROJECT_NAME} PRIVATE "${FREETYPE_DIR}/include")


# ImGUI

set(IMGUI_DIR "${LIB_DIR}/imgui")

add_library("imgui" "${IMGUI_DIR}/imgui.cpp"
                  "${IMGUI_DIR}/imgui_demo.cpp"
                  "${IMGUI_DIR}/imgui_draw.cpp"
                  "${IMGUI_DIR}/imgui_tables.cpp"
                  "${IMGUI_DIR}/imgui_widgets.cpp"
                  
                  "${IMGUI_DIR}/imgui_impl_glfw.cpp"
                  "${IMGUI_DIR}/imgui_impl_opengl3.cpp")

target_include_directories("imgui" PRIVATE "${IMGUI_DIR}")
target_include_directories(${PROJECT_NAME} PRIVATE "${IMGUI_DIR}")
target_link_libraries(${PROJECT_NAME} "imgui" "${CMAKE_DL_LIBS}")

And here is my folder construction

 1. build
 2. lib
    -  freetype
    -  glad
    -  glfw
    -  glm
    -  imgui
    -  stb
 3. source
    -  Main.cpp
 4. CMakeLists.txt

Here is my question : How i can tell imgui that glfw is already here and he can use it?

Thanks in advance

Erik Tellier
  • 200
  • 1
  • 1
  • 13
  • Is there a GitHub repo with your code in it? This build is just _so_ far afield from anything you should reasonably do in CMake that I'm tempted to help you just re-write it, but I can't do that without being able to play with it myself. If you don't want to share your code with me, I _urge_ you to use [vcpkg](https://vcpkg.io/) and `find_package` to manage dependencies in CMake. – Alex Reinking Jun 17 '21 at 07:00
  • For example, calling `add_subdirectory` will not set `FREETYPE_LIBRARIES`. I think you've confused this with `find_package`. It looks like you're writing your own mini build systems for STB, Glad, and ImGUI. Maybe don't do that? – Alex Reinking Jun 17 '21 at 07:03
  • i'll create a github so u can see – Erik Tellier Jun 17 '21 at 07:14
  • https://github.com/real2k/LearnOpenGL here it is – Erik Tellier Jun 17 '21 at 07:22

1 Answers1

5

Your build should consist of nothing but the following:

cmake_minimum_required(VERSION 3.20)
project(LearnOpenGL)

## Find dependencies
find_package(glfw3 REQUIRED)
find_package(glad REQUIRED)
find_package(glm REQUIRED)
find_package(freetype REQUIRED)
find_package(imgui REQUIRED)

# stb does not have a CMake build, but is header-only
find_path(STB_INCLUDE_DIRS "stb.h") 

## Create main executable
add_executable(main source/Main.cpp)
target_include_directories(main 
  PRIVATE 
    ${STB_INCLUDE_DIRS}
    "${CMAKE_CURRENT_LIST_DIR}/source"
)
target_link_libraries(
  main
  PRIVATE
    freetype
    glfw
    glad::glad
    glm::glm
    imgui::imgui
)

If you aren't using CMake 3.20, (a) you should be, but (b) you can try with an earlier version. But never put a version below the one you test with. CMake is only backwards compatible, not forwards compatible.

If you only need freetype as a dependency of imgui, then you can remove the references to it in the CMakeLists.txt.

To build this, you'll want to use vcpkg. To that end, create a file called vcpkg.json next to your CMakeLists.txt with the following contents:

{
  "name": "learn-opengl",
  "version": "0.1.0",
  "dependencies": [
    "glfw3",
    "glad",
    "glm",
    "freetype",
    "stb",
    {
      "name": "imgui",
      "features": ["freetype", "glfw-binding", "opengl3-glad-binding"]
    }
  ]
}

This is just telling vcpkg which dependencies you want, and that you want imgui built with freetype support and the glfw bindings.

Then you just need to run three commands.

$ git clone https://github.com/microsoft/vcpkg.git
$ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_TOOLCHAIN_FILE=$PWD/vcpkg/scripts/buildsystems/vcpkg.cmake
$ cmake --build build

The only thing here that might be unexpected is setting CMAKE_TOOLCHAIN_FILE, this is just telling CMake to use vcpkg. The first time this runs, vcpkg will download your dependencies, build them, cache them in ~/.cache/vcpkg and install them into your build folder. Subsequent runs will build just your code.

This sequence successfully built your code for me on my Ubuntu 20.04 LTS machine.


To make this easier, consider creating a CMakePresets.json file, also in your root directory, with the following contents:

{
  "version": 2,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 20,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "default",
      "displayName": "Default Config",
      "description": "Default build using Make and vcpkg",
      "generator": "Unix Makefiles",
      "binaryDir": "${sourceDir}/build",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Release",
        "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake"
      }
    },
    {
      "name": "default-msvc",
      "displayName": "Default MSVC",
      "description": "Default build using Visual Studio and vcpkg",
      "generator": "Visual Studio 16 2019",
      "binaryDir": "${sourceDir}/build",
      "cacheVariables": {
        "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake"
      }
    }
  ]
}

Then you can just run cmake --preset=default instead of the longer command above.

Alex Reinking
  • 16,724
  • 5
  • 52
  • 86
  • 2
    i do like your answer but at the same time not, when i created my project the first things i wanted to do is building everything from source, to avoid installing libs and libs. And Glad & ImGUI don't have a cmake implementation. Thanks anyway – Erik Tellier Jun 17 '21 at 07:57
  • vcpkg does compile from source. The way you're trying to compile from source will not work because that's just architecturally not how CMake operates. – Alex Reinking Jun 17 '21 at 07:58
  • i'll try then and comeback to u when i manage to make it work – Erik Tellier Jun 17 '21 at 07:58
  • Look, CMake is turing complete, so there's probably some way to make it work. It isn't worth your (or anyone's) time to do so. Insisting on the _worst possible process_ will not get you very far. If you don't want to use vcpkg you can do what it does: download each dependency and install them all to a common prefix, then call with build (the exact same CMakeLists as above) with `CMAKE_PREFIX_PATH` set. – Alex Reinking Jun 17 '21 at 08:00
  • i followed your answer but i got an error saying : CMake Error at CMakeLists.txt:5 (find_package): By not providing "Findglfw3.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "glfw3", but CMake did not find one. Could not find a package configuration file provided by "glfw3" with any of the following names: glfw3Config.cmake glfw3-config.cmake – Erik Tellier Jun 17 '21 at 08:04
  • Add the installation prefix of "glfw3" to CMAKE_PREFIX_PATH or set "glfw3_DIR" to a directory containing one of the above files. If "glfw3" provides a separate development package or SDK, be sure it has been installed. – Erik Tellier Jun 17 '21 at 08:04
  • It sounds like you either didn't create the `vcpkg.json` or you didn't set the toolchain file. – Alex Reinking Jun 17 '21 at 08:05
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/233876/discussion-between-erik-tellier-and-alex-reinking). – Erik Tellier Jun 17 '21 at 08:06
  • How can i properly adapt that configuration to windows10 without visual studio? And getting both preset for my project so i can easily work on both os? – Erik Tellier Jun 17 '21 at 16:28
  • It should be as easy as creating a `windows` preset with the `Visual Studio 16 2019` generator. I can try it myself later. Vcpkg works on major platforms. – Alex Reinking Jun 17 '21 at 16:34
  • if u can explain to me how to do it when u got time I would be grateful. – Erik Tellier Jun 17 '21 at 16:49
  • @ErikTellier - I updated my answer to work on Windows with your latest code. – Alex Reinking Jun 17 '21 at 17:05
  • Hey if you still read the comment here, mister. Do you have an answer for that question using vcpkg and mingw – Erik Tellier Jun 26 '21 at 18:01
  • https://stackoverflow.com/questions/68144821/vcpkg-isnt-working-on-windows-with-mingw – Erik Tellier Jun 26 '21 at 18:01
  • @ErikTellier @AlexReinking any chance one of you would be able to please help me out? At the moment I am following the process suggested by Alex above and running into the same error that Erik ran into where find_package is unable to find glfw3. I was able to successfully run the commands and I have tried deleting my build directory and re-running the commands which worked for Erik to solve that issue. Still running into the same problem after doing this. I've pushed my code to this branch `https://github.com/Blargian/min_span_tree_visualizer/tree/EM-44-Integrate-SFML-and-a-graphing-library ` – Blargian Feb 12 '23 at 07:47
  • @Blargian - please [ask a new question](https://stackoverflow.com/questions/ask) – Alex Reinking Feb 12 '23 at 15:05