16

I have been trying to follow the vendor's tutorial here: CMake-Tutorial, look over the documentation here: Cmake-Documentation, and educate myself as best as possible with sources on YouTube, but I am really struggling with getting the environment set up for working with OpenGL. Having tinkered with the Glitter boilerplate and the tutorials on open.gl and learnopengl.com, I've decided that understanding the build process is too important not to investigate.

In my investigation, I have come across the CMake error "cannot find source file" which is shown below in more detail. The problem seems to be arising from "add_executable".

A similar question was asked here: CMake - Cannot find file. The solution involved ensuring that the ${PROJECT_SOURCE_DIR} was set properly for each variable, which I believe I have done.

My file structure:

+ infuriating_project
    + bin // post compile results
    + src // my humble code
    + deps // external code
        +glew
            + include
            + src
        +glfw
            + include
            + src
        +glm
        +soil
            + lib
            + src

My CMakeLists.txt:

cmake_minimum_required (VERSION 3.0)


# Version Information ---------------------------------------------------------
project (openGL-practice)
SET (VERSION_MAJOR 1)
SET (VERSION_MINOR 0)
SET (VERSION_FEATURE 0)
SET (VERSION_PATCH 0)
SET (VERSION "${VERSION_MAJOR}.${VERSION_MINOR}")
SET (VERSION "${VERSION}.${VERSION_FEATURE}.${VERSION_PATCH}")
MESSAGE ("Version: ${VERSION}")

# Configure Source & Binary Directories ---------------------------------------
SET (PROJECT_ROOT "${PROJECT_SOURCE_DIR}")
SET (PROJECT_SOURCE_DIR "${PROJECT_SOURCE_DIR}/src")
SET (PROJECT_BINARY_DIR "${PROJECT_BINARY_DIR}/bin")
MESSAGE ("Source path: ${PROJECT_SOURCE_DIR}")
MESSAGE ("Binary path: ${PROJECT_BINARY_DIR}")

# Configure Depenency Directories ---------------------------------------------
SET (PROJECT_DEPS "${PROJECT_ROOT}/deps")
SET (glew_inc "${PROJECT_DEPS}/glew/include/GL/")
SET (glew_src "${PROJECT_DEPS}/glew/src/")
SET (glfw_inc "${PROJECT_DEPS}/glfw/include/GLFW/")
SET (glfw_src "${PROJECT_DEPS}/glfw/src/")
SET (glm "${PROJECT_DEPS}/glm/glm/")
SET (soil_lib "${PROJECT_DEPS}/lib/")
SET (soil_src "${PROJECT_DEPS}/src/")

# Include directories ---------------------------------------------------------
include_directories("
    ${PROJECT_SOURCE_DIR}
    ${PROJECT_BINARY_DIR}
    ${glew_inc}
    ${glew_src}
    ${glfw_inc}
    ${glfw_src}
    ${glm}
    ${soil_lib}
    ${soil_src}
    ${PROJECT_ROOT}
    ")

# Add executable --------------------------------------------------------------
add_executable(main main.cpp)

The following error is provided:

CMake Error at CMakeLists.txt:46 (add_executable):
  Cannot find source file:

    main.cpp

  Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
  .hxx .in .txx


CMake Error: CMake can not determine linker language for target: main
CMake Error: Cannot determine link language for target "main".

Any and all help would be very much appreciated.

Community
  • 1
  • 1
assemblyDruid
  • 363
  • 1
  • 3
  • 13
  • +1 for accurately describing the Cmake idiocy as "infuriating". When you're spending more than half your time fighting the framework instead of doing useful programming, it's a BAD FRAMEWORK. In my case, merely adding some source files produced this intractable behavior. – UserX Dec 21 '22 at 04:22
  • really? you needed "infuriating" to reach that conclusion? I see it more like: You had me at "it's NOT python"! (As in, *** do we constantly need new languages to achieve what python was designed for and is very good at and widely supported with tons of libraries/support, just to force everyone to keep learning new syntax??). Ideally someone would develop "PMake" as a replacement. – mo FEAR Jan 08 '23 at 11:57

3 Answers3

25

There are some points I'd like to mention.

  1. include_directories helps for finding header files. Source files must always have a complete relative path.

    Assuming that your main.cpp is within src, the correct syntax is

    add_executable(main ${PROJECT_SOURCE_DIR}/main.cpp)
    
  2. Including ${PROJECT_BINARY_DIR} does not make sense.

  3. Overwriting CMake default variables like ${PROJECT_SOURCE_DIR} is no good practice. In future you will always remember that you have done such a thing and for another programmer it is quite unexpected.

Hope it helps.

Roland Sarrazin
  • 1,203
  • 11
  • 29
guenni_90
  • 511
  • 5
  • 11
  • Hi guenni_90, thank you for your response. That did solve the issue with CMake and the "Cannot find source file" error, so I have marked your solution as accepted. Unfortunately I am still getting an error after running make, but I will try to solve this independently before posting a new question. – assemblyDruid Apr 14 '17 at 15:07
7

In add_executable() call relative paths are always interpreted relative to variables CMAKE_CURRENT_SOURCE_DIR or CMAKE_CURRENT_BINARY_DIR.

If you have source files in subdirectories of these dirs, you should explicitely specify these subdirectories:

add_executable(main src/main.cpp)

Also, variables like PROJECT_SOURCE_DIR should be treated as readonly: while changing them isn't detected by CMake as an error, it breaks some things.

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
1

in my case, I'm using esp-idf in vscode. Turns out, after renaming main.c into main.cpp, vscode goes into the cmakelists.txt file and adds main.cpp as a source, but fails to remove main.c. So the build continues to unnecessarily look for a file that doesn't exist anymore.

mo FEAR
  • 552
  • 4
  • 8