0

The Problem

  • I have never used CMake before, so I have no idea what I am doing.
  • Currently, building with CMake produces a ton of errors about my source files being unable to access headers they include. This will be clarified below.
  • There are probably a lot more problems with my current configuration that I am not aware of.

Goals

  • Configure a CMake project that can build a library and a separate dependent executable for testing.
  • Configure the CMake project such that source files within the library can include headers not in their same directories.
  • Configure the overall project with VSCode such that I can build, run, and debug the library and executable in a manner that is not overly complicated.
  • Include SDL2 and SDL2_Image as dependencies to the library, using vcpkg ideally.
  • Possibly include some additional arguments to the C compiler for error checking.

Project Structure

library_root
|---include/
|------<all library headers>
|---src/
|------CMakeLists.txt
|------subfolder/
|---------CMakeLists.txt
|---------<some library source files>
|------subfolder2/
|---------CMakeLists.txt
|---------<some more library source files>
|---test_src/
|------<all test source files>
|---CMakeLists.txt

In the end, every source file in src needs access to the headers in the include directory. The contents of include and src should be built into the library. The contents of test_src should be built into an executable such that they depend on the library.

The Current CMake Configuration

The highest level CMakeLists.txt:

# Minimum CMAKE Version Requirement
cmake_minimum_required(VERSION 3.20.3)

# VCPKG Locations
set(CMAKE_TOOLCHAIN_FILE "C:/vcpkg/scripts/buildsystems/vcpkg.cmake")
set(CMAKE_PREFIX_PATH "C:/vcpkg/installed/x64-windows/share")

# Project Fields - TEST PLATFORM
project(library_test
    LANGUAGES C
    VERSION 0.1.0
)

# SDL2
find_package(SDL2 REQUIRED)

# C99 Standard Requirement
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED YES)
set(CMAKE_C_EXTENSIONS OFF)

# RESET Library Content
add_library(reset STATIC)
target_link_libraries(reset PRIVATE SDL2::SDL2)
target_include_directories(reset PUBLIC include) # partial fix by changing include to include/reset - this is the correct directory
add_subdirectory(src)

# Test Platform Content
add_executable(test_platform test_platform/test_platform.c)
target_link_libraries(test_platform STATIC reset)

The CMakeLists.txt file immediately within the library src folder looks like this:

add_subdirectory(data)
add_subdirectory(internal)
add_subdirectory(spatial)
add_subdirectory(visual)

The CMakeLists.txt file in src/data looks like this:

target_sources(reset 
PRIVATE 
    provider.c
    rrcon.c
    rvector.c
)

Results From CMake Build

I am running the build through the CMake Tools VSCode extension, which uses this command:

C:\Program Files\CMake\bin\cmake.EXE" --build C:/.../library_root/build --config Debug --target all -j 6 --

For any given header in the library include directory, CMake produces the following error for any library source file that attempts to include it:

fatal error: header.h: No such file or directoryfatal error: header.h: No such file or directory

The error points to the include statement in the source file.

The complete error output:

[main] Building folder: reset 
[build] Starting build
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --build c:/C99/reset/build --config Debug --target all -j 6 --
[build] -- Configuring done
[build] -- Generating done
[build] -- Build files have been written to: C:/C99/reset/build
[build] [ 10%] Building C object CMakeFiles/reset.dir/src/data/provider.c.obj
[build] [ 20%] Building C object CMakeFiles/reset.dir/src/data/rrcon.c.obj
[build] [ 30%] Building C object CMakeFiles/reset.dir/src/data/rvector.c.obj
[build] [ 40%] Building C object CMakeFiles/reset.dir/src/internal/rsetup.c.obj
[build] [ 50%] Building C object CMakeFiles/reset.dir/src/spatial/rtilemap.c.obj
[build] [ 60%] Building C object CMakeFiles/reset.dir/src/spatial/rlevelmap.c.obj
[build] C:\C99\reset\src\data\provider.c:2:22: fatal error: provider.h: No such file or directory
[build]  #include "provider.h"
[build]                       ^
[build] compilation terminated.
[build] CMakeFiles\reset.dir\build.make:75: recipe for target 'CMakeFiles/reset.dir/src/data/provider.c.obj' failed
[build] mingw32-make.exe[2]: *** [CMakeFiles/reset.dir/src/data/provider.c.obj] Error 1
[build] mingw32-make.exe[2]: *** Waiting for unfinished jobs....
[build] C:\C99\reset\src\data\rrcon.c:4:19: fatal error: rrcon.h: No such file or directory
[build]  #include "rrcon.h"
[build]                    ^
[build] compilation terminated.
[build] CMakeFiles\reset.dir\build.make:90: recipe for target 'CMakeFiles/reset.dir/src/data/rrcon.c.obj' failed
[build] mingw32-make.exe[2]: *** [CMakeFiles/reset.dir/src/data/rrcon.c.obj] Error 1
[build] C:\C99\reset\src\data\rvector.c:2:21: fatal error: rvector.h: No such file or directory
[build]  #include "rvector.h"
[build]                      ^
[build] compilation terminated.
[build] CMakeFiles\reset.dir\build.make:105: recipe for target 'CMakeFiles/reset.dir/src/data/rvector.c.obj' failed
[build] mingw32-make.exe[2]: *** [CMakeFiles/reset.dir/src/data/rvector.c.obj] Error 1
[build] C:\C99\reset\src\internal\rsetup.c:2:20: fatal error: rsetup.h: No such file or directory
[build]  #include "rsetup.h"
[build]                     ^
[build] compilation terminated.
[build] CMakeFiles\reset.dir\build.make:120: recipe for target 'CMakeFiles/reset.dir/src/internal/rsetup.c.obj' failed
[build] mingw32-make.exe[2]: *** [CMakeFiles/reset.dir/src/internal/rsetup.c.obj] Error 1
[build] C:\C99\reset\src\spatial\rtilemap.c:2:22: fatal error: rtilemap.h: No such file or directory
[build]  #include "rtilemap.h"
[build]                       ^
[build] compilation terminated.
[build] CMakeFiles\reset.dir\build.make:150: recipe for target 'CMakeFiles/reset.dir/src/spatial/rtilemap.c.obj' failed
[build] mingw32-make.exe[2]: *** [CMakeFiles/reset.dir/src/spatial/rtilemap.c.obj] Error 1
[build] C:\C99\reset\src\spatial\rlevelmap.c:2:23: fatal error: rlevelmap.h: No such file or directory
[build]  #include "rlevelmap.h"
[build]                        ^
[build] compilation terminated.
[build] CMakeFiles\reset.dir\build.make:135: recipe for target 'CMakeFiles/reset.dir/src/spatial/rlevelmap.c.obj' failed
[build] mingw32-make.exe[2]: *** [CMakeFiles/reset.dir/src/spatial/rlevelmap.c.obj] Error 1
[build] CMakeFiles\Makefile2:169: recipe for target 'CMakeFiles/reset.dir/all' failed
[build] mingw32-make.exe[1]: *** [CMakeFiles/reset.dir/all] Error 2
[build] Makefile:109: recipe for target 'all' failed
[build] mingw32-make.exe: *** [all] Error 2
[build] Build finished with exit code 2

Along with the complete actual project file structure:

reset/
|---include/reset/
|------depn.h
|------provider.h
|------rconfig.h
|------rdata.h
|------reset.h
|------rfocus.h
|------rlevelmap.h
|------rrcon.h
|------rsetup.h
|------rtilemap.h
|------rvector.h
|------shorts.h
|---src/
|------data/
|---------provider.c
|---------rrcon.c
|---------rvector.c
|------internal/
|---------rsetup.c
|------spatial/
|---------rlevelmap.c
|---------rtilemap.c
|------visual/
|---------rfocus.c

The updated error ( after changing the target include directory from 'include' to 'include/reset' ):

[main] Building folder: reset 
[build] Starting build
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --build c:/C99/reset/build --config Debug --target all -j 6 --
[build] -- Configuring done
[build] -- Generating done
[build] -- Build files have been written to: C:/C99/reset/build
[build] [ 10%] Building C object CMakeFiles/reset.dir/src/data/provider.c.obj
[build] [ 20%] Building C object CMakeFiles/reset.dir/src/data/rrcon.c.obj
[build] [ 30%] Building C object CMakeFiles/reset.dir/src/data/rvector.c.obj
[build] [ 40%] Building C object CMakeFiles/reset.dir/src/internal/rsetup.c.obj
[build] [ 50%] Building C object CMakeFiles/reset.dir/src/spatial/rlevelmap.c.obj
[build] [ 60%] Building C object CMakeFiles/reset.dir/src/spatial/rtilemap.c.obj
[build] [ 70%] Building C object CMakeFiles/reset.dir/src/visual/rfocus.c.obj
[build] [ 80%] Linking C static library libreset.a
[build] [ 80%] Built target reset
[build] [ 90%] Building C object CMakeFiles/test_platform.dir/test_platform/test_platform.c.obj
[build] In file included from C:\C99\reset\test_platform\test_platform.c:4:0:
[build] C:/C99/reset/include/reset/depn.h:11:17: fatal error: SDL.h: No such file or directory
[build]  #include <SDL.h>
[build]                  ^
[build] compilation terminated.
[build] CMakeFiles\test_platform.dir\build.make:75: recipe for target 'CMakeFiles/test_platform.dir/test_platform/test_platform.c.obj' failed
[build] mingw32-make.exe[2]: *** [CMakeFiles/test_platform.dir/test_platform/test_platform.c.obj] Error 1
[build] CMakeFiles\Makefile2:195: recipe for target 'CMakeFiles/test_platform.dir/all' failed
[build] mingw32-make.exe[1]: *** [CMakeFiles/test_platform.dir/all] Error 2
[build] Makefile:109: recipe for target 'all' failed
[build] mingw32-make.exe: *** [all] Error 2
[build] Build finished with exit code 2
exokem
  • 21
  • 5
  • Please, show (add to the question post) **complete** error message, which describes not only file which is not found, but also the source file which is compiled. Refer to [that question](https://stackoverflow.com/questions/67999533/cmake-not-finding-the-includes-in-the-project-wrong-inclusion-of-multipele-fold) for example of that error message. – Tsyvarev Jun 16 '21 at 17:50
  • @Tsyvarev I have added the complete error along with the actual project structure for additional clarification. – exokem Jun 16 '21 at 18:09
  • According to the error message, it is about building the target `reset`. The `CMakeLists.txt` you show doesn't define that target (it defines only `lib_name` and `test` targets). Please, provide [mcve]. – Tsyvarev Jun 16 '21 at 18:19
  • Also, the error message tells about the header `provider.h` which is located under `include/reset` directory. No lines in your code adds this directory to the include directories list. E.g. the line `target_include_directories(lib_name PUBLIC include)` adds only `include` directory. – Tsyvarev Jun 16 '21 at 18:23
  • @Tsyvarev Updated the post again so the CMakeLists.txt files should all be accurate to the structure. Changing `include` to `include/reset` appears to resolve the issue with the library headers but produces a new error related to SDL. I will update the post to reflect this. – exokem Jun 16 '21 at 18:26
  • 1
    According to [that question](https://stackoverflow.com/questions/10488775/sdl-h-no-such-file-or-directory-found-when-compiling), proper way for include `SDL.h` header is `#include `. – Tsyvarev Jun 16 '21 at 18:49
  • @Tsyvarev The issue persists even with that adjustment. Also, is there anything I need to add to the CMakeLists.txt to also include SDL_image? – exokem Jun 16 '21 at 18:55
  • 1
    Have you searched(google) for your problem (using SDL_image with CMake)? Have you checked e.g. [that question](https://stackoverflow.com/questions/23850472/how-to-use-sdl2-and-sdl-image-with-cmake)? Note, that Stack Overflow is a collection of questions about particular problems. It is not about helping someone to fix **all** problems with the code. If you suspect that you have many unrelated problems, then try to search every problem separately. – Tsyvarev Jun 16 '21 at 19:04

0 Answers0