Issue Including SDL2 and SDL2_image With CMake - c

The Problem
SDL2_image is unable to locate SDL.h from SDL2.
References to SDL2 within the project files are able to locate SDL2 and SDL2_image.
CMakeLists.txt
# Minimum CMAKE Version Requirement
cmake_minimum_required(VERSION 3.20.3)
# Find Modules - SDL2
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# Project Fields - TEST PLATFORM
project(library_test
LANGUAGES C
VERSION 0.1.0
)
set(SDL2_LIBRARY "C:/lib/SDL2-2.0.14/i686-w64-mingw32/bin")
set(SDL2_INCLUDE_DIR "C:/lib/SDL2-2.0.14/i686-w64-mingw32/include")
set(SDL2_IMAGE_LIBRARY "C:/lib/SDL2_image-2.0.5/i686-w64-mingw32/bin")
set(SDL2_IMAGE_INCLUDE_DIR "C:/lib/SDL2_image-2.0.5/i686-w64-mingw32/include")
find_package(SDL2 REQUIRED)
find_package(SDL2_image 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 SDL2::Main SDL2::Image)
target_include_directories(reset PUBLIC include/reset)
add_subdirectory(src)
# Test Platform Content
add_executable(test_platform test_platform/test_platform.c)
target_link_libraries(test_platform STATIC reset)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lmingw32 -lSDL2main -lSDL2 -lSDL2_image -ggdb")
CMake Build Output
See the full output here:
[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] Consolidate compiler generated dependencies of target reset
[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/internal/rsetup.c.obj
[build] [ 40%] Building C object CMakeFiles/reset.dir/src/spatial/rlevelmap.c.obj
[build] [ 50%] Building C object CMakeFiles/reset.dir/src/spatial/rtilemap.c.obj
[build] [ 60%] Building C object CMakeFiles/reset.dir/src/visual/rfocus.c.obj
[build] In file included from C:/C99/reset/include/reset/depn.h:12:0,
[build] from C:/C99/reset/include/reset/provider.h:13,
[build] from C:\C99\reset\src\data\provider.c:2:
[build] C:/lib/SDL2_image-2.0.5/i686-w64-mingw32/include/SDL2/SDL_image.h:27:17: fatal error: SDL.h: No such file or directory
[build] #include "SDL.h"
[build] ^
[build] compilation terminated.
[build] In file included from C:/C99/reset/include/reset/depn.h:12:0,
[build] from C:/C99/reset/include/reset/rrcon.h:15,
[build] from C:\C99\reset\src\data\rrcon.c:4:
[build] C:/lib/SDL2_image-2.0.5/i686-w64-mingw32/include/SDL2/SDL_image.h:27:17: fatal error: SDL.h: No such file or directory
[build] #include "SDL.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] 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] In file included from C:/C99/reset/include/reset/depn.h:12:0,
[build] from C:/C99/reset/include/reset/rsetup.h:11,
[build] from C:\C99\reset\src\internal\rsetup.c:2:
[build] C:/lib/SDL2_image-2.0.5/i686-w64-mingw32/include/SDL2/SDL_image.h:27:17: fatal error: SDL.h: No such file or directory
[build] #include "SDL.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] In file included from C:/C99/reset/include/reset/depn.h:12:0,
[build] from C:/C99/reset/include/reset/rlevelmap.h:5,
[build] from C:\C99\reset\src\spatial\rlevelmap.c:2:
[build] C:/lib/SDL2_image-2.0.5/i686-w64-mingw32/include/SDL2/SDL_image.h:27:17: fatal error: SDL.h: No such file or directory
[build] #include "SDL.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] In file included from C:/C99/reset/include/reset/depn.h:12:0,
[build] from C:/C99/reset/include/reset/rtilemap.h:9,
[build] from C:\C99\reset\src\spatial\rtilemap.c:2:
[build] C:/lib/SDL2_image-2.0.5/i686-w64-mingw32/include/SDL2/SDL_image.h:27:17: fatal error: SDL.h: No such file or directory
[build] #include "SDL.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] In file included from C:/C99/reset/include/reset/depn.h:12:0,
[build] from C:/C99/reset/include/reset/rfocus.h:11,
[build] from C:\C99\reset\src\visual\rfocus.c:2:
[build] C:/lib/SDL2_image-2.0.5/i686-w64-mingw32/include/SDL2/SDL_image.h:27:17: fatal error: SDL.h: No such file or directory
[build] #include "SDL.h"
[build] ^
[build] compilation terminated.
[build] CMakeFiles\reset.dir\build.make:165: recipe for target 'CMakeFiles/reset.dir/src/visual/rfocus.c.obj' failed
[build] mingw32-make.exe[2]: *** [CMakeFiles/reset.dir/src/visual/rfocus.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:89: recipe for target 'all' failed
[build] mingw32-make.exe: *** [all] Error 2
[build] Build finished with exit code 2
The current CMake setup resolved previous issues I had with #include <SDL.h> causing a file not found error, but now this occurs within SDL_image as it tries to access SDL. Note that the source of the errors is SDL_image.h as it attempts to #include "SDL.h".
Currently, the SDL packages are found using some FindSDL2 cmake files that I found on this page: https://edgarluque.com/blog/sdl2-cmake
This is also the first page I found that actually resolved any of the previous errors I have had. I am on windows instead of linux so there are naturally issues.
I did try adding -l compiler arguments for the SDL components but these seemingly had no effect.
Attempted Solutions
I tried changing the last line in the CMake_lists.txt file (compiler flags):
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lmingw32 -lSDL2main -lSDL2 -lSDL2_image -ggdb -IC:/lib/SDL2-2.0.14/i686-w64-mingw32/include/SDL2")
and this produced a different error:
[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] Consolidate compiler generated dependencies of target reset
[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] Consolidate compiler generated dependencies of target test_platform
[build] [ 90%] Building C object CMakeFiles/test_platform.dir/test_platform/test_platform.c.obj
[build] [100%] Linking C executable test_platform.exe
[build] c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find -lSDL2main
[build] c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find -lSDL2
[build] c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find -lSDL2_image
[build] CMakeFiles\test_platform.dir/objects.a(test_platform.c.obj): In function `main':
[build] C:/C99/reset/test_platform/test_platform.c:18: multiple definition of `main'
[build] c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../libmingw32.a(main.o):(.text.startup+0x0): first defined here
[build] c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find -lSTATIC
[build] c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find C:/lib/SDL2_image-2.0.5/i686-w64-mingw32/bin: Permission denied
[build] c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find C:/lib/SDL2-2.0.14/i686-w64-mingw32/bin: Permission denied
[build] collect2.exe: error: ld returned 1 exit status
[build] CMakeFiles\test_platform.dir\build.make:101: recipe for target 'test_platform.exe' failed
[build] mingw32-make.exe[2]: *** [test_platform.exe] 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:89: recipe for target 'all' failed
[build] mingw32-make.exe: *** [all] Error 2
[build] Build finished with exit code 2
Here is also the test_platform.c file, because it is relevant to the new error:
//#define SDL_MAIN_HANDLED
#include "depn.h"
#include "rsetup.h"
#include "rrcon.h"
#include "provider.h"
#include "rfocus.h"
#include "rvector.h"
#include "rtilemap.h"
#include "rlevelmap.h"
#undef main
/// Main Function
int main ( int argc, char ** argv )
{
fprintf ( stderr, "Received %d argument%s:\n", argc, argc == 1 ? "" : "s" );
forsi ( argc ) fprintf ( stderr, "\t%s\n", argv [ ix ] );
CFG_WIN cfg =
{
1920, 1080,
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
"Reset"
};
r_sdlset(); // SDL2 module init
DATA_WIN display = r_dispset ( cfg );
RRCON rrcon = rrcon_inst ( display.renderer, TEXTURE );
register_directory ( "tile" );
rrcon_import ( rrcon, "grass", "grass.png" );
RTILEMAP tilemap = rtilemap_static ( );
// RTILEMAP tilemap = rtilemap_dynamic ( 72, 72 );
RTILE tile = rtile_inst ( "grass" );
VEC2U pos = { 0, 0 };
VEC2U pos2 = { 63, 31 };
rtilemap_set ( tilemap, tile, pos );
rtilemap_set ( tilemap, tile, pos2 );
// RFOCUS focus = rfocus_inst ( F_FLAT_TILEMAP );
//
// focus -> tilemap = tilemap;
VEC2I tilemap_start = { 30, 0 };
SDL_Event ev;
while ( 1 )
{
if ( SDL_WaitEvent ( &ev ) )
{
if ( ev.type == SDL_QUIT )
{
rrcon_clr ( rrcon );
SDL_DestroyRenderer ( display.renderer );
SDL_DestroyWindow ( display.window );
SDL_Quit ();
IMG_Quit ();
return EXIT_SUCCESS;
}
}
// SDL_SetRenderDrawColor ( display.renderer, 0, 0, 0, 255 );
SDL_RenderClear ( display.renderer );
rtilemap_render_tiles ( tilemap, rrcon, tilemap_start, 1.0 );
SDL_RenderPresent ( display.renderer );
}
return 0;
}

After looking over your information and the modules' documentation, here are the issues I'm seeing:
CMAKE_C_FLAGS:
Avoiding direct manipulation of this in modern CMake solutions is strongly encouraged. CMake provides specialized functions for defining things like compiler flags, linker libraries, etc. and their relationships to specific targets in your project, which allow it to manage things more carefully.
SDL2_ variables:
According to the documentation at https://github.com/aminosbh/sdl2-cmake-modules these should be cache variables rather than local ones. I'm not sure if this actually matters, but it may be worth noting for troubleshooting purposes. It's also just a good idea in general to use cache variables for this kind of thing, because then people can override them on the CMake command line or in cmake-gui.
Note that cache variable values get stored in a CMakeCache.txt file in your build directory, which will likely need to be deleted if you want to use different values.
I should also point out here that the modules' documentation suggests that you should be able to just set SDL2_PATH and SDL2_IMAGE_PATH. However, this apparently requires that the libraries be under lib/ in your installation, rather than under bin/.
SDL2_LIBRARY/SDL2_IMAGE_LIBRARY:
If you choose to stick with defining these directly, I think you may need to point them at the full path and filename of the actual library file, and not just the containing directory.
SDL2_INCLUDE_DIR/SDL2_IMAGE_INCLUDE_DIR:
It appears that these are meant to point to the SDL2 directories containing the actual library headers (e.g. SDL.h), and not to the parent directory containing the SDL2 directory. This is likely why SDL2_image is failing to find SDL.h during compile time.
This also means you are expected to omit SDL2/ path prefixes from the #include directives in your own code; however, you could use target_include_directories to add ${SDL2_INCLUDE_DIR}/.. etc. to each dependent target that you're building in order to end up with both directory levels in the compiler's header search paths.
SDL::Core and SDL::Main:
The module documentation suggests that any SDL-dependent libraries you're building (e.g. reset) must link against SDL::Core, not SDL::Main.
Only SDL-dependent executables (e.g. test_platform) that you're building should link against SDL::Main, as this represents the library that wraps your main() (or similar OS-specific) function with SDL's main function.
Note that if you were only to build an application and not a library, you would only need to link SDL::Main because the module defines an internal dependency on SDL::Core.

Related

CMake: Library and Executable with External Dependencies

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

CMakeLists reports error: ld:cannot find -l

Here is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.14)
project(testlib C)
set(CMAKE_C_STANDARD 99)
include_directories(/usr/local/include/)
find_library(iconv_lib iconv)
add_executable(testlib library.c)
target_link_libraries(testlib libiconv.a)
In this folder /usr/local/include/ are the files:
iconv.h localcharset.h
The CMake reports the error:
====================[ Build | testlib | Debug ]=================================
D:\.CLion2019.2\system\cygwin_cmake\bin\cmake.exe --build /cygdrive/d/project/c/testlib/cmake-build-debug --target testlib -- -j 4
Scanning dependencies of target testlib
[ 50%] Building C object CMakeFiles/testlib.dir/library.c.o
[100%] Linking C executable testlib.exe
/usr/lib/gcc/x86_64-pc-cygwin/7.4.0/../../../../x86_64-pc-cygwin/bin/ld: cannot find -liconv
collect2: error: ld returned 1 exit status
make[3]: *** [CMakeFiles/testlib.dir/build.make:84: testlib.exe] Error 1
make[2]: *** [CMakeFiles/Makefile2:76: CMakeFiles/testlib.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/testlib.dir/rule] Error 2
make: *** [Makefile:118: testlib] Error 2
It seems like you are not using the library located by find_library(), if it is actually found. If the library is not found, you can add search paths to tell CMake where to find this library:
find_library(iconv_lib
NAMES iconv
PATHS /path/containing/your/iconv/lib
)
Finally, use the iconv_lib variable you defined when calling target_link_libraries(), like this:
target_link_libraries(testlib PUBLIC ${iconv_lib})

Using Graphviz with Clion in Windows

I'm new to using external libraries in C so this could be a very silly mistake. I get reference errors when I try to run the below program using the provided CMakeLists.txt. Can anyone see what the issue is?
CMAKELists.txt
cmake_minimum_required(VERSION 3.6)
project(Learning)
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
set(GRAPHVIZ_INCLUDE_DIR "C:\\Program Files (x86)\\Graphviz2.38\\include\\graphviz")
set(SOURCE_FILES main.c)
include_directories("${GRAPHVIZ_INCLUDE_DIR}")
add_executable(Learning ${SOURCE_FILES})
main.c
#include <gvc.h>
#include <cgraph.h>
int main() {
Agraph_t *graph;
Agnode_t *nodeA, *nodeB;
Agedge_t *edge1;
Agsym_t *symbol1;
GVC_t *gvc;
gvc = gvContext();
graph = agopen( "graph", Agdirected, NULL);
nodeA = agnode(graph, "nodeA", 1);
nodeB = agnode(graph, "nodeB", 1);
edge1 = agedge(graph, nodeA, nodeB, 0, 1);
agsafeset(nodeA, "color", "red", "");
gvLayoutJobs(gvc, graph);
gvRenderJobs(gvc, graph);
gvFreeLayout(gvc, graph);
}
output
"C:\Program Files\JetBrains\CLion 2017.2.1\bin\cmake\bin\cmake.exe" --build E:\Development\C\Learning\cmake-build-debug --target Learning -- -j 2
Scanning dependencies of target Learning
[ 50%] Building C object CMakeFiles/Learning.dir/main.c.obj
[100%] Linking C executable Learning.exe
CMakeFiles\Learning.dir/objects.a(main.c.obj): In function `main':
E:/Development/C/Learning/main.c:38: undefined reference to `gvContext'
E:/Development/C/Learning/main.c:39: undefined reference to `_imp__Agdirected'
E:/Development/C/Learning/main.c:39: undefined reference to `agopen'
E:/Development/C/Learning/main.c:40: undefined reference to `agnode'
E:/Development/C/Learning/main.c:41: undefined reference to `agnode'
E:/Development/C/Learning/main.c:42: undefined reference to `agedge'
E:/Development/C/Learning/main.c:44: undefined reference to `agsafeset'
E:/Development/C/Learning/main.c:45: undefined reference to `gvLayoutJobs'
E:/Development/C/Learning/main.c:46: undefined reference to `gvRenderJobs'
E:/Development/C/Learning/main.c:47: undefined reference to `gvFreeLayout'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [Learning.exe] Error 1
CMakeFiles\Learning.dir\build.make:96: recipe for target 'Learning.exe' failed
mingw32-make.exe[2]: *** [CMakeFiles/Learning.dir/all] Error 2
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/Learning.dir/all' failed
CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/Learning.dir/rule' failed
mingw32-make.exe[1]: *** [CMakeFiles/Learning.dir/rule] Error 2
mingw32-make.exe: *** [Learning] Error 2
Makefile:117: recipe for target 'Learning' failed
Edit -- edited cmakeslists to add target_link_libraries but then I get the error below
cmake_minimum_required(VERSION 3.6)
project(Learning)
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
set(GRAPHVIZ_INCLUDE_DIR "C:\\Program Files (x86)\\Graphviz2.38\\include\\graphviz")
set(GRAPHVIZ_LIB_DIR "C:\\Program Files (x86)\\Graphviz2.38\\lib\\release\\lib")
target_link_libraries( "${GRAPHVIZ_LIB_DIR}" )
set(SOURCE_FILES main.c)
include_directories("${GRAPHVIZ_INCLUDE_DIR}")
add_executable(Learning ${SOURCE_FILES})
Results in this error
"C:\Program Files\JetBrains\CLion 2017.2.1\bin\cmake\bin\cmake.exe" -DCMAKE_BUILD_TYPE=Debug -G "CodeBlocks - MinGW Makefiles" E:\Development\C\Learning
CMake Error at CMakeLists.txt:8 (target_link_libraries):
Cannot specify link libraries for target "C:\Program Files
(x86)\Graphviz2.38\lib\release\lib" which is not built by this project.
-- Configuring incomplete, errors occurred!
See also "E:/Development/C/Learning/cmake-build-debug/CMakeFiles/CMakeOutput.log".
[Finished]
You need to link in graphviz library using target_link_libraries(Learning path/to/graphviz.so).

Error while compiling with cmake: cannot find -ldwmapi

Edit: Im using MinGW-x86_64 on windows
When Im trying to compile a gtk+ 3 c project with cmake, I have this error message on the log:
"C:\Program Files\JetBrains\CLion 2017.1.3\bin\cmake\bin\cmake.exe" --build C:\Users\Jonas\ClionProjects\tutorial\cmake-build-debug --target tutorial -- -j 4
[ 50%] Linking C executable tutorial.exe
c:/mingw/bin/../lib/gcc/mingw32/4.9.3/../../../../mingw32/bin/ld.exe: cannot find -ldwmapi
collect2.exe: error: ld returned 1 exit status
CMakeFiles\tutorial.dir\build.make:96: recipe for target 'tutorial.exe' failed
mingw32-make.exe[3]: *** [tutorial.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles/tutorial.dir/all] Error 2
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/tutorial.dir/all' failed
CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/tutorial.dir/rule' failed
mingw32-make.exe[1]: *** [CMakeFiles/tutorial.dir/rule] Error 2
mingw32-make.exe: *** [tutorial] Error 2
Makefile:117: recipe for target 'tutorial' failed
This is my CMakeLists.txt, in there I added gtk3 and its libraries, but when Im trying to compile, it has the errors mentioned before.
cmake_minimum_required(VERSION 3.7)
project(tutorial)
set(CMAKE_C_STANDARD 99)
set(SOURCE_FILES main.c)
set(PKG_CONFIG_EXECUTABLE "C:/msys64/mingw64/bin/pkg-config.exe")
FIND_PACKAGE(PkgConfig REQUIRED)
PKG_CHECK_MODULES(GTK3 REQUIRED gtk+-3.0)
INCLUDE_DIRECTORIES(${GTK3_INCLUDE_DIRS})
LINK_DIRECTORIES(${GTK3_LIBRARY_DIRS})
add_executable(tutorial ${SOURCE_FILES})
ADD_DEFINITIONS(${GTK3_CFLAGS_OTHER})
TARGET_LINK_LIBRARIES(tutorial ${GTK3_LIBRARIES})
dwmapi.dll is provided only for Vista. So I guess that it is a bug of package of gtk+-3.0. And -ldwmapi is not required for your OS. Below is a workaround to fix this issue. I don't make sure this will solve your issue. Note that this is self-responsibility.
make backup-copy of gdk-3.0.pc, gdk-broadway-3.0.pc, gdk-win32-3.0.pc in C:\msys64\mingw64\lib\pkgconfig
open those files in vim, remove -ldwmapi and :wq
UPDATE
Let's create libdwmapi.a
download def file from here
dlltool -d dwmapi.def -l libdwmapi.a

CMAKE no rule to make target for internal shared library

I wrote a cmake file that builds two shared library a vector3.c and a matrix4.c
The matrix4 depends on the vector3, if I run my cmake project and only build the vector3 shared library it builds just fine, when I add the matrix4 shared library I get a cmake error. No rule to make target.
The folder structure
core_math
------CMakeLists.txt
-common/
------common_structs.h
-matrix4/
------CMakeLists.txt
------matrix4/src/matrix4_scalar.c
------matrix4/headers/matrix4_scalar.h
-vector3/
-------CMakeLists.txt
-------vector3/src/vector3_scalar.c
-------vector3/headers/vector3_scalar.h
core_math/CMakeLists.txt
PROJECT(core_math)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
ADD_SUBDIRECTORY(vector3_scalar)
ADD_SUBDIRECTORY(matrix4_scalar)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY $(CMAKE_BINARY_DIR)/static_lib)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY $(CMAKE_BINARY_DIR)/shared_lib)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY $(CMAKE_BINARY_DIR)/bin)
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)
core_math/vector3/CMakeLists.txt
PROJECT(vector3_scalar)
SET(CMAKE_MACOSX_RPATH 1)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../common)
SET(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../common/common_structs.h)
SET(SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/vector3_scalar.c ${HEADER_FILES})
ADD_LIBRARY(vector3_scalar SHARED ${SRC_FILES})
core_math/matrix4_scalar/CMakeLists.txt
PROJECT(matrix4_scalar)
SET(CMAKE_MACOSX_RPATH 1)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../common
${CMAKE_CURRENT_SOURCE_DIR}/../vector3_scalar)
SET(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../common/common_structs.h
${CMAKE_CURRENT_SOURCE_DIR}/../vector3_scalar/headers/vector3_scalar.h
${CMAKE_CURRENT_SOURCE_DIR}/headers/matrix4_scalar.h)
SET(SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/matrix4_scalar.c ${HEADER_FILES})
ADD_LIBRARY(matrix4_scalar SHARED ${SRC_FILES})
TARGET_LINK_LIBRARIES(matrix4_scalar vector3_scalar)
build error
-- Build files have been written to: /Users/blubee/MATH/project/build
Scanning dependencies of target vector3_scalar
[ 25%] Building C object source/core_math/vector3_scalar/CMakeFiles/vector3_scalar.dir/sr
c/vector3_scalar.c.o
[ 50%] Linking C shared library $(CMAKE_BINARY_DIR)/lib/libvector3_scalar.dylib
[ 50%] Built target vector3_scalar
Scanning dependencies of target matrix4_scalar
[ 75%] Building C object source/core_math/matrix4_scalar/CMakeFiles/matrix4_scalar.dir/sr
c/matrix4_scalar.c.o
make[2]: *** No rule to make target `source/core_math/vector3_scalar//Users/blubee/MATH/pr
oject/build/lib/libvector3_scalar.dylib', needed by `source/core_math/matrix4_scalar//Use
rs/blubee/MATH/project/build/lib/libmatrix4_scalar.dylib'. Stop.
make[1]: *** [source/core_math/matrix4_scalar/CMakeFiles/matrix4_scalar.dir/all] Error 2
make: *** [all] Error 2
if I remove the target_link_libraries from the matrix4_scalar cmakelists.txt file then I get undefined symbols error instead.
Undefined symbols for architecture x86_64:
"_vec3_deg2rad", referenced from:
_mat4_rotate in matrix4_scalar.c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [source/core_math/matrix4_scalar//Users/blubee/MATH/project/build/lib/libmatr
ix4_scalar.dylib] Error 1
make[1]: *** [source/core_math/matrix4_scalar/CMakeFiles/matrix4_scalar.dir/all] Error 2
make: *** [all] Error 2
I have done some testing with your code and could reproduce the problem.
It's related to having used $(...) brackets for variable dereferencing in the SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ...) command. I've changed $(CMAKE_BINARY_DIR) to ${CMAKE_BINARY_DIR} and everything works fine:
> cmake --build .
-- Configuring done
-- Generating done
-- Build files have been written to: build
Scanning dependencies of target vector3_scalar
[ 25%] Building C object vector3_scalar/CMakeFiles/vector3_scalar.dir/src/vector3_scalar.c.o
[ 50%] Linking C shared library ../shared_lib/libvector3_scalar.dylib
[ 50%] Built target vector3_scalar
Scanning dependencies of target matrix4_scalar
[ 75%] Building C object matrix4_scalar/CMakeFiles/matrix4_scalar.dir/src/matrix4_scalar.c.o
[100%] Linking C shared library ../shared_lib/libmatrix4_scalar.dylib
[100%] Built target matrix4_scalar
References
CMake Error at CMakeLists.txt:30 (project): No CMAKE_C_COMPILER could be found
What's the CMake syntax to set and use variables?
[CMake] Trouble setting LIBRARY_OUTPUT_DIRECTORY
Custom Directory for CMake Library Output

Resources