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