Skip to content

Add CMake configuration files, meant for VC-devel/SDL2.framework#5721

Merged
madebr merged 12 commits intolibsdl-org:mainfrom
madebr:vcdist
May 30, 2022
Merged

Add CMake configuration files, meant for VC-devel/SDL2.framework#5721
madebr merged 12 commits intolibsdl-org:mainfrom
madebr:vcdist

Conversation

@madebr
Copy link
Copy Markdown
Contributor

@madebr madebr commented May 25, 2022

This PR adds 2 files that are specifically written for the Visual Studio development release.
(=the SDL2-devel-2.x.y-VC.zip files)
These files are meant to be put in the root folder (SDL2-2.x.y).

RFC for #5713, for distribution along the Visual Studio devel files.

It also has component support.
It supports the components: SDL2, SDL2main and SDL2test.
For simplicity, these are the latter part of the SDL2::SDL2, SDL2::SDL2main and SDL2::SDL2test targets.

Description

Visual Studio development releases ship with no CMake configuration files.
Because of this, all CMake based consumers need to write (or steal) a FindSDL2.cmake module.
By shipping a SDL2 configuration module along binary releases,
consumers don't need a FindSDL2.cmake anymore (if we ship one for all configurations).
They can then simply add-DSDL2_dir=path/to/extracted/SDL2-2.x.y or -DCMAKE_PREFIX_PATH=path/to/extracted/SDL2-2.x.y to the cmake invocation. Or set the SDL2_DIR environment variable.

As an example, consider the following cmake build script:

cmake_minimum_required(VERSION 3.22)
project(sdl_test C)
find_package(SDL2 2.0.30 REQUIRED COMPONENTS SDL2 SDL2main SDL2test)
message(STATUS "Found SDL2 ${SDL2_VERSION}")
add_executable(sdl_test main.c)
target_link_libraries(sdl_test PRIVATE SDL2::SDL2 SDL2::SDL2main SDL2::SDL2test)

It fails when executing CMake as:

cmake .. -DCMAKE_PREFIX_PATH="C:\sdl_releases\SDL2-2.0.9;C:\sdl_releases\SDL2-2.0.14;C:\sdl_releases\SDL2-2.0.22"

The message is:

CMake Error at CMakeLists.txt:4 (find_package):
  Could not find a configuration file for package "SDL2" that is compatible
  with requested version "2.0.30".

  The following configuration files were considered but not accepted:

    C:/sdl_releases/SDL2-2.0.9/sdl2-config.cmake, version: 2.0.9
    C:/sdl_releases/SDL2-2.0.14/sdl2-config.cmake, version: 2.0.14
    C:/sdl_releases/SDL2-2.0.22/sdl2-config.cmake, version: 2.0.22

Replacing the non-existing version 2.0.30 with e.g. 2.0.15 will let CMake pick the first matching version. In my case 2.0.14:

-- Found SDL2 2.0.14

Existing Issue(s)

This PR addresses the Visual Studio +Macos aspect of #5713.

Questions/More work needed

  • @slouken : You will need to modify your release scripts to include these files
  • Is cmake/vcdist a good location to store these files? These files are not meant to be used by SDL2's cmake build system.
    As long as this location is not added to CMAKE_MODULE_PATH, I don't see an issue.
  • Would it be useful for the configuration scripts to have COMPONENT support?
    COMPONENT support would be useful because the Visual Studio (and macos) don't ship a static library.
    By e.g. adding STATIC, SHARED, TEST and MAIN components we can easily catch the absence of the SDL2::SDL2-static target.
    update: added COMPONENT support.

@madebr madebr marked this pull request as draft May 25, 2022 23:31
@slouken
Copy link
Copy Markdown
Collaborator

slouken commented May 25, 2022

How about a new standalone cmake directory for each platform?
e.g.:
cmake is used for building SDL
cmake-VisualC is used for Visual Studio development package
cmake-Xcode is used for Xcode development package
etc.

Then everything in the appropriate directory will get copied into the release development package. Does that make sense?

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented May 25, 2022

Would it be useful for the configuration scripts to have COMPONENT support?

Is there a reason not to have it?

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented May 25, 2022

How about a new standalone cmake directory for each platform?

Then everything in the appropriate directory will get copied into the release development package. Does that make sense?

Alternatively we could put them in the subdirectories for the associated projects, e.g.
VisualC/cmake
Xcode/SDL/cmake

But would that confuse people, thinking that the files were needed or used for building SDL?

@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented May 25, 2022

These files are distribution-only files, so perhaps put them in VisualC/dist.
Inside the SDL repo, these are text files.
It's only when they are distributed that they become cmake files.
So I wouldn't put them in a folder with cmake in its name.

@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented May 25, 2022

Would it be useful for the configuration scripts to have COMPONENT support?

Is there a reason not to have it?

Added complexity.
The current files are small and easily understandable.
But I think in the long run, adding COMPONENT support to SDL (and its satellite libraries) might pay off.
I'll look into it.

@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented May 26, 2022

By keeping it KISS, I was able to add COMPONENT support.
There are still holes when a user has created e.g. a SDL2::SDL2-static target before doing find_package(SDL2), but imho then he already shot in his own foot.

@madebr madebr force-pushed the vcdist branch 2 times, most recently from a342ca7 to 61582a7 Compare May 26, 2022 14:29
@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented May 26, 2022

Can somebody with an Apple test the SDL2 framework CMake files?

The CMake folder should be added to the Resources folder (SDL2.framework/versions/A/Resources).

I've attached a little CMakeLists.txt script that should test it (only tested on MSVC).

Download link: CMakeLists.txt

The cmake script needs to be run as:

cmake -S /path/to/the/cmake/script -B /some/temporary/build/folder -DCMAKE_PREFIX_PATH="path1_to_folder_containing_the_framework;path2_to_folder_containing_the_framework;path3_to_folder_containing_the_framework" -DCMAKE_BUILD_TYPE=Release
cmake --build /some/temporary/build/folder --config Release

The search procedure of find_package is documented here.
You need to add the folder containing the SDL2.framework folder to the prefix path, not the path of the framework itself.

@madebr madebr changed the title Add CMake configuration files, meant for VC devel package Add CMake configuration files, meant for VC-devel/SDL2.framework May 26, 2022
@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented May 26, 2022

But would that confuse people, thinking that the files were needed or used for building SDL?

I've, once again, moved the files.
Both the Xcode and VC cmake files are placed in a pkg-support subfolder.
The release scripts can then simply copy all files in there to the root of the VC-devel zip or SDL2.framework.
I think the pkg-support folder should make it clear to people that these are support files, not build files.

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented May 27, 2022

Can somebody with an Apple test the SDL2 framework CMake files?

The CMake folder should be added to the Resources folder (SDL2.framework/versions/A/Resources).

I've attached a little CMakeLists.txt script that should test it (only tested on MSVC).

Download link: CMakeLists.txt

The cmake script needs to be run as:

cmake -S /path/to/the/cmake/script -B /some/temporary/build/folder -DCMAKE_PREFIX_PATH="path1_to_folder_containing_the_framework;path2_to_folder_containing_the_framework;path3_to_folder_containing_the_framework" -DCMAKE_BUILD_TYPE=Release
cmake --build /some/temporary/build/folder --config Release

The search procedure of find_package is documented here. You need to add the folder containing the SDL2.framework folder to the prefix path, not the path of the framework itself.

Testing this now:

/Applications/CMake.app/Contents/bin/cmake -S . -B build -DCMAKE_PREFIX_PATH=. -DCMAKE_BUILD_TYPE=Release
-- The C compiler identification is AppleClang 13.1.6.13160021
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
CMake Warning at CMakeLists.txt:22 (find_package):
  Could not find a configuration file for package "SDL2" that is compatible
  with requested version "2.90.0".

  The following configuration files were considered but not accepted:

    /Users/slouken/Desktop/SDL2.framework/Resources/CMake/sdl2-config.cmake, version: 2.23.0
    /Users/slouken/Desktop/SDL2.framework/Versions/A/Resources/CMake/sdl2-config.cmake, version: 2.23.0
    /Users/slouken/Desktop/SDL2.framework/Versions/Current/Resources/CMake/sdl2-config.cmake, version: 2.23.0
    /usr/local/lib/cmake/SDL2/sdl2-config.cmake, version: 2.23.0



CMake Warning at SDL2.framework/Resources/CMake/sdl2-config.cmake:23 (message):
  SDL2: following component(s) are not available: SDL2test
Call Stack (most recent call first):
  CMakeLists.txt:34 (find_package)


CMake Warning at CMakeLists.txt:34 (find_package):
  Found package configuration file:

    /Users/slouken/Desktop/SDL2.framework/Resources/CMake/sdl2-config.cmake

  but it set SDL2_FOUND to FALSE so package "SDL2" is considered to be NOT
  FOUND.


-- Found SDL2 2.23.0
-- Configuring done
CMake Error at CMakeLists.txt:78 (add_executable):
  Target "sdl_test" links to target "SDL2::SDL2test" but the target was not
  found.  Perhaps a find_package() call is missing for an IMPORTED target, or
  an ALIAS target is missing?


-- Generating done
CMake Generate step failed.  Build files cannot be regenerated correctly.

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented May 27, 2022

If I make SDL2test optional, I get:

/Applications/CMake.app/Contents/bin/cmake -S . -B build -DCMAKE_PREFIX_PATH=. -DCMAKE_BUILD_TYPE=Release
CMake Warning at CMakeLists.txt:22 (find_package):
  Could not find a configuration file for package "SDL2" that is compatible
  with requested version "2.90.0".

  The following configuration files were considered but not accepted:

    /Users/slouken/Desktop/SDL2.framework/Resources/CMake/sdl2-config.cmake, version: 2.23.0
    /Users/slouken/Desktop/SDL2.framework/Versions/A/Resources/CMake/sdl2-config.cmake, version: 2.23.0
    /Users/slouken/Desktop/SDL2.framework/Versions/Current/Resources/CMake/sdl2-config.cmake, version: 2.23.0
    /usr/local/lib/cmake/SDL2/sdl2-config.cmake, version: 2.23.0



CMake Warning at SDL2.framework/Resources/CMake/sdl2-config.cmake:23 (message):
  SDL2: following component(s) are not available: SDL2test
Call Stack (most recent call first):
  CMakeLists.txt:34 (find_package)


CMake Warning at CMakeLists.txt:34 (find_package):
  Found package configuration file:

    /Users/slouken/Desktop/SDL2.framework/Resources/CMake/sdl2-config.cmake

  but it set SDL2_FOUND to FALSE so package "SDL2" is considered to be NOT
  FOUND.


-- Found SDL2 2.23.0
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/slouken/Desktop/build

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented May 27, 2022

Building fails to find SDL.h, possibly because SDL2_INCLUDE_DIRS isn't used anywhere?

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented May 27, 2022

The Visual Studio support files worked great.

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented May 27, 2022

Building fails to find SDL.h, possibly because SDL2_INCLUDE_DIRS isn't used anywhere?

If I change these lines in sdl2-config.cmake:

#set(SDL2_INCLUDE_DIR    "${CMAKE_CURRENT_LIST_DIR}/../../Headers")
#set(SDL2_INCLUDE_DIRS   "${SDL2_INCLUDE_DIR}")
#set(SDL2_LIBRARY        "${CMAKE_CURRENT_LIST_DIR}/../../SDL2")
FIND_PATH(SDL2_INCLUDE_DIR SDL.h)
set(SDL2_INCLUDE_DIRS   "${SDL2_INCLUDE_DIR}")
FIND_LIBRARY(SDL2_LIBRARY SDL2)

Then CMakeCache.txt gets these variables:

./CMakeCache.txt:SDL2_DIR:PATH=/Users/slouken/Desktop/SDL2.framework/Resources/CMake
./CMakeCache.txt:SDL2_INCLUDE_DIR:PATH=/Users/slouken/Desktop/SDL2.framework/Headers
./CMakeCache.txt:SDL2_LIBRARY:FILEPATH=/Users/slouken/Desktop/SDL2.framework

But the build still fails because SDL2_INCLUDE_DIR isn't used anywhere.

@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented May 27, 2022

Building fails to find SDL.h, possibly because SDL2_INCLUDE_DIRS isn't used anywhere?

Yeah, I forgot to use SDL2_INCLUDE_DIR in the SDL2::SDL2 target.

FIND_PATH(SDL2_INCLUDE_DIR SDL.h)
set(SDL2_INCLUDE_DIRS   "${SDL2_INCLUDE_DIR}")
FIND_LIBRARY(SDL2_LIBRARY SDL2)

We don't want to use cache variables in a cmake configuration file.
sdl2-config.cmake will be shipped along a sdl sdk, so it knows the location of the headers. Therefore we simply set the variables.

In find modules (e.g. FindSDL2.cmake) a "heavy" file system search is performed when looking for header + library.
These variables are then cached to speed up subsequent find's (e.g. when re-configuring).

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented May 27, 2022

FIND_LIBRARY(SDL2_LIBRARY SDL2)

There's a difference between FIND_LIBRARY(SDL2_LIBRARY SDL2) and explicitly linking to the SDL2 dynamic library. The former adds SDL2 as a framework and the latter as a dylib. On Apple platforms we want to link to the framework, not the dylib inside it.

@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented May 27, 2022

Thanks, I think I understand frameworks a bit better now.
I changed the behavior to do -F /path/to/folder/containing/the/framework -I SDL2.framework/Headers when compiling
and do -F /path/to/folder/containing/the/framework -framework SDL2 when linking.

Google searches learned me that I need to pass the folder containing the SDL2.framework folder to -F, not the path of the framework itself. Is that correct?

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented May 27, 2022

That's working much better! I had to fix the include path, and then it worked great.

I also removed the other variables, since we need the Framework setup on Apple platforms. I did that as a separate commit though, in case we really need them and you want to drop it.

@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented May 27, 2022

It makes sense to remove the (now unused) variables.
In modern CMake, people should not rely on variables but think in targets.

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented May 27, 2022

Should we add some documentation to pkg-support on how to use the new CMake support?

@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented May 27, 2022

Perhaps add a short example to its ReadMe.txt?

Something along the lines of:

SDL2.framework can be used in CMake projects using the following pattern:

find_package(SDL2 REQUIRED COMPONENTS SDL2)

target_link_libraries(your_awesome_game PRIVATE SDL2::SDL2)

If SDL2.framework is installed in a non-standard location,
please refer to [1] for ways to configure CMake.

[1] https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure

My native language is not English, so you might want to rephrase things.

@ericoporto
Copy link
Copy Markdown
Contributor

hey, I don't understand much of the MacOS Framework stuff, but just to check, if I make my game executable target using set_target_properties(mygame PROPERTIES MACOSX_BUNDLE TRUE ...), where in ... is all my bundle information stuff, the resulting app will include the SDL2 framework inside of it, and have rpath or something correctly link to it?

Just checking because I am really used to ${SDL2_LIBRARY} and static linking and it looks like maybe this is not a thing that is going to be supported.

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented May 28, 2022

Just checking because I am really used to ${SDL2_LIBRARY} and static linking and it looks like maybe this is not a thing that is going to be supported.

This is just the CMake support bundled with the official release framework. We're not changing SDL if you're building it yourself.

@madebr madebr marked this pull request as ready for review May 30, 2022 22:10
@madebr madebr merged commit 3c3c025 into libsdl-org:main May 30, 2022
@madebr madebr deleted the vcdist branch May 30, 2022 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants