Reputation: 1797
I know this has been asked before, but I'm not satisfied with the answers I'm finding online, so hopefully someone can provide me with the right insights.
I'm trying to configure SDL2 with CLion on Windows and I'm having some problems. I downloaded the SDL2 sources on linux before, built them succesfully and installed them, so I know it works. However, I don't have access to that computer now and I'm trying to set things up on Windows.
I downloaded http://libsdl.org/release/SDL2-devel-2.0.7-mingw.tar.gz and extracted its contents to E:\SDL2\SDL2-2.0.7
(with E:\SDL2\SDL2-2.0.7\x86_64-w64-mingw32\bin
containing SDL2.dll
). None of the guides I've found say anything about running configure, cmake, make or whatever and since it contains a DLL, I assume everything is pre-built (?)
This is my CMakeList.txt
in my CLion project (named SDL_Project
) in E:\repository\SDL_Project
:
cmake_minimum_required(VERSION 3.6)
project(SDL_Project)
set(CMAKE_CXX_STANDARD 14)
add_executable(SDL_Project src/main.cpp)
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
find_package(SDL2_ttf REQUIRED)
include_directories(${SDL2_INCLUDE_DIR}
${SDL2_IMAGE_INCLUDE_DIR}
${SDL2_TTF_INCLUDE_DIR})
target_link_libraries(SDL_Project ${SDL2_LIBRARY}
${SDL2_IMAGE_LIBRARIES}
${SDL2_TTF_LIBRARIES})
This alone does not work since CMake does not know where to look for SDL2 (which differs from my Linux experience.)
I've found several versions of FindSDL2.cmake
online, which are enormous scripts that search for SDL2 in various locations, apparently.
Adding this script next to CMakeList.txt
does not work for me:
CMake Error at CMakeLists.txt:8 (find_package):
By not providing "FindSDL2.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "SDL2", but
CMake did not find one.
[...]
I have also added the SDL2 directory to PATH
in Windows system environment variables through the control panel.
Here is my compiler message (when I comment out the SDL2 lines in CMakeList.txt
which cause errors):
E:\repository\SDL_Project\src\main.cpp:1:17: fatal error: SDL.h: No such file or directory
#include <SDL.h>
^
compilation terminated.
I know this error is obvious, but I'm including it here anyway for completeness.
I have the following questions:
FindSDL2.cmake
file with a large list of hardcoded locations to search, doesn't seem nice to me either..So in other words; what is a nice, portable, minimal solution to this problem? Please motivate the answer where possible, I like to learn why this is a good solution as well as how to do it. Thanks!!
Upvotes: 1
Views: 1128
Reputation: 54589
Finding libraries is complicated, even though Unix tries very hard to trick you into thinking it's not.
In the end, a library is just a file on the filesystem (anywhere on the filesystem) and you need to somehow tell your build scripts where to look for that file. Unix comes with a number of reasonable defaults here (eg. /usr/lib/
), which Windows does not have, but the situation on Unix gets just as bad as on Windows as soon as you install your library to a non-standard location.
CMake has two answers to this problem, but in the case of SDL2 the more appropriate is arguably using find scripts.
The find script now is supposed to solve the problem of locating a library file that could be anywhere on your filesystem. There might be a few reasonable defaults, which it checks automatically for your convenience, but in the end, it can't get the job done without your help, because the file could be anywhere.
That's why, if we look at a typical find script, it will always provide you with a customization point to tell the build system where to find the library in question:
FIND_LIBRARY(SDL2_LIBRARY_TEMP
NAMES SDL2
HINTS
$ENV{SDL2DIR}
PATH_SUFFIXES lib64 lib
PATHS ${SDL2_SEARCH_PATHS} ${SDL2_INCLUDE_DIR}/../..
)
Note the HINTS $ENV{SDL2DIR}
here. This will make CMake search the directory specified in the environment variable SDL2DIR
, as well as the subdirectories lib
and lib64
in there, for a library file called SDL2
(in addition to the aforementioned default paths that are always searched)¹.
Note that this is a machine specific hint, so the directory is intentionally not hardcoded in any of the scripts, but instead retrieved from an environment variable. That way, the build script itself remains completely portable and it is the user's responsibility to configure the build environment accordingly.
So the setup process for you is: Obtain a binary of your favorite library (either by downloading the binary or by building it yourself), install it to a location of your choice and then make that library location somehow known the build, eg. by setting an environment variable in the build shell. Note that this process is always the same for all platforms, you may simply skip the last step if your library is already installed in a default location recognized by the find-mechanism, such as /usr/lib
on Unix, or the CMake package registry on Windows.
There is one more detail missing. Whether using an external find script or a package config file for finding the library, CMake must also be able to find that very script before it can go on to search for the library. Here again, CMake already ships with a bunch of preinstalled scripts available for your convenience, but SDL2 is not one of them. Fortunately, if you have to provide your own find script, you usually just place it in the source tree, so making its location known to CMake is not a problem. For example, if you place the FindSDL2.cmake
in a folder cmake
under your project source root, simply call list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
to have CMake use the find script from that location.
¹ Note that since CMake 3.12 find_package(Foo)
automatically considers the Foo_ROOT
environment variable as a search hint for all relevant find_*
calls, unless the script explicitly opts out of that behavior with the NO_PACKAGE_ROOT_PATH
option.
Upvotes: 3