Skip to content

cmake: install SDL2test + add component support + fix mingw#5727

Merged
slouken merged 10 commits intolibsdl-org:mainfrom
madebr:cmake-tweaks
Jun 3, 2022
Merged

cmake: install SDL2test + add component support + fix mingw#5727
slouken merged 10 commits intolibsdl-org:mainfrom
madebr:cmake-tweaks

Conversation

@madebr
Copy link
Copy Markdown
Contributor

@madebr madebr commented May 27, 2022

  1. Also install SDL2_test when building SDL2 with cmake (you need to configure cmake with -DSDL_TEST=ON)
  2. Export a SDL2::SDL2test target (same name as in Add CMake configuration files, meant for VC-devel/SDL2.framework #5721)
  3. For mingw and when using CMake 3.13+, fix mingw linking with SDL2::SDL2 by adding -lmingw32 to the link options of SDL2::SDL2.
  4. Add COMPONENTS support to the SDL2Config.cmake, installed by cmake. The name of the targets are the same as in Add CMake configuration files, meant for VC-devel/SDL2.framework #5721
  5. Fixes Inconsistent names for static libraries when built for windows with cmake. #2794: When building with MSVC, or targeting Windows/OS2 with Watcom and having enabled SDL_STATIC, the static library will always be called SDL2-static.lib.
  6. Do limited integration testing by using a just-created SDL2 install prefix to build a minimal application
  7. Create CMake configuration files for the MinGW redistributable
  8. Make the CMake configuration files, generated by autotools, relocatable

The following CMakeLists.txt builds fine when using an installation created by cmake.
Download link: CMakeLists.txt
Tested using mingw32@Linux + gcc11@Linux

The test cmake script should also work with the VC+Xcode cmake from #5721

@madebr madebr marked this pull request as draft May 27, 2022 11:49
@madebr madebr changed the title Cmake tweaks cmake: install SDL2test + add component support + fix mingw May 27, 2022
CMakeLists.txt Outdated
if(MINGW OR CYGWIN)
# FIXME: CMake 3.13 added target_link_options. This allows adding "-lmingw32" **before** -lSDL2
if(NOT CMAKE_VERSION VERSION_LESS "3.13")
target_link_options(SDL2 PUBLIC -lmingw32 -static-libgcc)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be -lcygwin on cygwin?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIR, SDL avoids cygwin runtime and builds as native windows (mingw) instead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

autotools does this:

SDL/configure.ac

Lines 4034 to 4039 in bef9f2b

AC_CHECK_LIB(mingw32, main, [have_mingw32=yes])
if test x$have_mingw32 = xyes; then
SDL_LIBS="-lmingw32 $SDL_LIBS"
else
SDL_LIBS="-lcygwin $SDL_LIBS"
fi

It gives priority to mingw32.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sam will know better, then.

Copy link
Copy Markdown
Contributor Author

@madebr madebr May 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tried adding -Wl,--undefined=WinMain to the linker options and that is even better.
Using that argument, it does not even matter if it is added before or after libSDL2.a/libSDL2.dll.a, or as first or last argument.

If deemed okay, it could greatly simplify the sdl2-config.cmake file, used by autotools, greatly.

What do you think?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's an interesting idea. Sam?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that seems fine in the gcc case.

Copy link
Copy Markdown
Contributor Author

@madebr madebr May 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just pushed a poc.
This CMakeLists.txt should be able to build against the Xcode framework, the VC development package, packages generated by cmake and packages generated by autotools.

@madebr madebr force-pushed the cmake-tweaks branch 2 times, most recently from a14b59e to 69ad450 Compare May 29, 2022 22:46
FtZPetruska added a commit to FtZPetruska/SDL_net that referenced this pull request May 30, 2022
- Set a different output name for static libraries on MSVC and WATCOM (cf. libsdl-org/SDL_image#275 and libsdl-org/SDL#5727)
- Fix `PKG_PREFIX` on Windows (cf. libsdl-org/SDL_image#274)

Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>
@madebr madebr force-pushed the cmake-tweaks branch 3 times, most recently from 79693ff to 3cdffe3 Compare June 1, 2022 00:36
@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented Jun 1, 2022

GitHub CI errors because of the following issues, for which I need guidance from domain experts:

  • the emscripten cmake integration test fails because of a missing symbol (emscripten_sync_run_in_main_runtime_thread_, defined here. I don't know how it got here in the first place since pthread is disabled for emscripten.
  • the riscos autotools->cmake integration fails because autotools does not install shared libraries, only static libraries. I think this is a autotools problem, because the CMake build system happily creates+installs a libSDL2.so shared library
  • the "MSVC + UWP" cmake integration test fails with a missing symbol error because I don't know what's special about a UWP application, and how to modify the test.

@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented Jun 2, 2022

@slouken
We're still missing a handcrafted sdl2-config.cmake file for the mingw development zip.
Where are those files stored? If there currently isn't one, can you please suggest a folder path?

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented Jun 2, 2022

@slouken We're still missing a handcrafted sdl2-config.cmake file for the mingw development zip. Where are those files stored? If there currently isn't one, can you please suggest a folder path?

That file is generated using the normal autotools process. Here are the files generated from the sources in main. Aside from the prefix in sdl2-config.cmake, is there anything that needs to be changed?

Is it possible to make the prefix relative so the package can be relocatable? I think we'd want to do that for the normal autotools support as well.

sdl2-config-version.cmake

# sdl2 cmake project-config-version input for ./configure scripts

set(PACKAGE_VERSION "2.23.0")

if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
  set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
  set(PACKAGE_VERSION_COMPATIBLE TRUE)
  if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
    set(PACKAGE_VERSION_EXACT TRUE)
  endif()
endif()

sdl2-config.cmake

# sdl2 cmake project-config input for ./configure scripts 

set(prefix "/opt/local/i686-w64-mingw32")
set(exec_prefix "${prefix}")
set(libdir "${exec_prefix}/lib")
set(includedir "${prefix}/include")
set(SDL2_PREFIX "${prefix}")
set(SDL2_EXEC_PREFIX "${exec_prefix}")
set(SDL2_LIBDIR "${libdir}")
set(SDL2_INCLUDE_DIRS "${includedir}/SDL2")
set(SDL2_LIBRARIES "-L${SDL2_LIBDIR}  -lmingw32 -lSDL2main -lSDL2 -mwindows")
string(STRIP "${SDL2_LIBRARIES}" SDL2_LIBRARIES)

if(NOT TARGET SDL2::SDL2)
  # provide SDL2::SDL2, SDL2::SDL2main and SDL2::SDL2-static targets, like SDL2Config.cmake does, for compatibility

  # Remove -lSDL2 as that is handled by CMake, note the space at the end so it does not replace e.g. -lSDL2main
  # This may require "libdir" beeing set (from above)
  string(REPLACE "-lSDL2 " "" SDL2_EXTRA_LINK_FLAGS " -lmingw32 -lSDL2main -lSDL2 -mwindows ")
  # also get rid of -lSDL2main, if you want to link against that use both SDL2::SDL2main and SDL2::SDL2 (in that order)
  # (SDL2Config.cmake has the same behavior)
  string(REPLACE "-lSDL2main" "" SDL2_EXTRA_LINK_FLAGS ${SDL2_EXTRA_LINK_FLAGS})
  string(STRIP "${SDL2_EXTRA_LINK_FLAGS}" SDL2_EXTRA_LINK_FLAGS)
  string(REPLACE "-lSDL2 " "" SDL2_EXTRA_LINK_FLAGS_STATIC " -Wl,--dynamicbase -Wl,--nxcompat -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid ")
  string(STRIP "${SDL2_EXTRA_LINK_FLAGS_STATIC}" SDL2_EXTRA_LINK_FLAGS_STATIC)

if(WIN32 AND NOT MSVC)
  # MINGW needs very special handling, because the link order must be exactly -lmingw32 -lSDL2main -lSDL2
  # for it to work at all (and -mwindows somewhere); a normal SHARED IMPORTED or STATIC IMPORTED library always puts itself first
  # so handle this like a header-only lib and put everything in INTERFACE_LINK_LIBRARIES

  add_library(SDL2::SDL2 INTERFACE IMPORTED)
  set_target_properties(SDL2::SDL2 PROPERTIES
    INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
    INTERFACE_LINK_LIBRARIES "-L${SDL2_LIBDIR} -lSDL2")

  add_library(SDL2::SDL2main INTERFACE IMPORTED)
  set_target_properties(SDL2::SDL2main PROPERTIES
    INTERFACE_LINK_LIBRARIES "-L${SDL2_LIBDIR} -lmingw32 -lSDL2main -mwindows")

else() # (not WIN32) or MSVC

  add_library(SDL2::SDL2 SHARED IMPORTED)
  set_target_properties(SDL2::SDL2 PROPERTIES
    INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
    IMPORTED_LINK_INTERFACE_LANGUAGES "C"
    IMPORTED_LOCATION "${SDL2_LIBDIR}/${CMAKE_SHARED_LIBRARY_PREFIX}SDL2${CMAKE_SHARED_LIBRARY_SUFFIX}")

  if(MSVC)
    # This file is generated when building SDL2 with autotools and MinGW, and MinGW/dlltool
    # isn't able to generate .lib files that are usable by recent MSVC versions
    # (something about "module unsafe for SAFESEH"; SAFESEH is enabled by default in MSVC).
    # The .lib file for SDL2.dll *could* be generated with `gendef SDL2.dll` and then
    # `lib.exe /machine:x86 /def:SDL2.def /out:SDL2.lib` (or /machine:amd64)
    # but that requires lib.exe from a Visual Studio installation - and that still doesn't
    # give you a static SDL2main.lib with SAFESEH support that you'll need (unless you don't use SDL2main)
    # Note that when building SDL2 with CMake and MSVC, the result works with both MinGW and MSVC.

    message(FATAL_ERROR, "This build of libSDL2 only supports MinGW, not MSVC (Visual C++), because it lacks .lib files!")
    # MSVC needs SDL2.lib set as IMPORTED_IMPLIB to link against (comment out message() call above if you added SDL2.lib yourself)
    set_target_properties(SDL2::SDL2 PROPERTIES IMPORTED_IMPLIB "${SDL2_LIBDIR}/SDL2.lib")
  else()
    # this mustn't be set for MSVC, so do it here in an extra call here
    set_target_properties(SDL2::SDL2 PROPERTIES INTERFACE_LINK_LIBRARIES  "${SDL2_EXTRA_LINK_FLAGS}")
  endif()

  add_library(SDL2::SDL2main STATIC IMPORTED)
  set_target_properties(SDL2::SDL2main PROPERTIES
    IMPORTED_LINK_INTERFACE_LANGUAGES "C"
    IMPORTED_LOCATION "${SDL2_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}SDL2main${CMAKE_STATIC_LIBRARY_SUFFIX}")

endif() # (not WIN32) or MSVC

  add_library(SDL2::SDL2-static STATIC IMPORTED)
  set_target_properties(SDL2::SDL2-static PROPERTIES
    INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
    IMPORTED_LINK_INTERFACE_LANGUAGES "C"
    IMPORTED_LOCATION "${SDL2_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}SDL2${CMAKE_STATIC_LIBRARY_SUFFIX}"
    INTERFACE_LINK_LIBRARIES "${SDL2_EXTRA_LINK_FLAGS_STATIC}")

endif() # NOT TARGET SDL2::SDL2

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented Jun 2, 2022

Another question, does the CMake support in the satellite libraries depend on these changes in the SDL library? If so, we should make an SDL 2.24.0 release and bump up our minimum required SDL version before we do final releases of those libraries.

@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented Jun 2, 2022

Another question, does the CMake support in the satellite libraries depend on these changes in the SDL library? If so, we should make an SDL 2.24.0 release and bump up our minimum required SDL version before we do final releases of those libraries.

No, I was careful to only use targets that were already available (SDL2::SDL2 and SDL2::SDL2-static).
I also added a fallback module to the satellite libraries in case SDL2 does not have any cmake modules (=current apple + VC-devel packages), which manually looks for these files.

@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented Jun 2, 2022

That file is generated using the normal autotools process. Here are the files generated from the sources in main. Aside from the prefix in sdl2-config.cmake, is there anything that needs to be changed?

The CMake helpers do the following to generate a relative paths:

get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)

After that, every use of a full path is converted to a relative one:

set(SDL2_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@/SDL2")

becomes

set(SDL2_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include/SDL2")

So in configure, we should calculate the relative path $(libdir)cmake/SDL2 and $(prefix) and append that to ${CMAKE_CURRENT_LIST_DIR}.

In addition, we might need to add 2 cmake script in the root folder of the mingw that forwards the call because CMake does not look in gnu triplet subdirectories.

@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented Jun 2, 2022

I disabled the failing tests, described in #5727 (comment).

I will open an issue for the emscripten and riscos issue. (UWP failing is because of my inexperience with the platform)

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented Jun 2, 2022

That file is generated using the normal autotools process. Here are the files generated from the sources in main. Aside from the prefix in sdl2-config.cmake, is there anything that needs to be changed?

The CMake helpers do the following to generate a relative paths:

get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)

After that, every use of a full path is converted to a relative one:

set(SDL2_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@/SDL2")

becomes

set(SDL2_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include/SDL2")

So in configure, we should calculate the relative path $(libdir)cmake/SDL2 and $(prefix) and append that to ${CMAKE_CURRENT_LIST_DIR}.

Can you add a commit that does this and I can test it out here?

In addition, we might need to add 2 cmake script in the root folder of the mingw that forwards the call because CMake does not look in gnu triplet subdirectories.

We can certainly add that. If you attach the files here, I can add them to our mingw packaging, which is not in the SDL repo.

Comment on lines +4691 to +4695
dnl Calculate the location of the prefix, relative to the cmake folder
eval pkg_prefix=$prefix
eval pkg_cmakedir=$libdir/cmake/SDL2
cmake_prefix_relpath="$(echo -n "$pkg_cmakedir" | sed -E "s#^$pkg_prefix##" - | sed -E "s#[A-Za-z0-9_ .-]+#..#g" -)"
AC_SUBST([cmake_prefix_relpath])
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could not use realpath --relative-to= because it expects folders/files to exist.

Also, I'm no shell wizard, so this code might not be compatible with other shells.
I only tested on my system bash 5.1.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

realpath isn't available on all supported platforms, so this is a good change.

Copy link
Copy Markdown
Contributor Author

@madebr madebr Jun 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like it fails on Macos:

sed: -: No such file or directory
sed: -: No such file or directory

I think we need to use a purpose built macro instead of the kludge I wrote.
e.g. ax_compute_relative_paths

But I don't know what's acceptable license- or dependency-wise.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just omit the '-', sed reads from standard input by default.

@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented Jun 2, 2022

In the latest commit, I added files in mingw/pkg-support that should be copied to the mingw development folder.
Like the VC SDK, the MinGW tarball should have a cmake subfolder.
All cmake files redirect to either their counterparts in the 32- or 64-bit MinGW prefixex.

@madebr madebr marked this pull request as ready for review June 2, 2022 18:26
@madebr madebr force-pushed the cmake-tweaks branch 3 times, most recently from 87d26c9 to 8358a54 Compare June 3, 2022 03:49
@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented Jun 3, 2022

I cleaned up the commit history, and think this pr is ready for review.

I added a little cmake integration test in cmake/test, which runs for all ci platforms.
It can also serve as an example for how to integrate SDL2 in your project.

@slouken slouken merged commit f858d13 into libsdl-org:main Jun 3, 2022
@slouken
Copy link
Copy Markdown
Collaborator

slouken commented Jun 3, 2022

Okay, the mingw development archive has the files:

SDL2-2.23.0/cmake/sdl2-config-version.cmake
SDL2-2.23.0/cmake/sdl2-config.cmake
SDL2-2.23.0/x86_64-w64-mingw32/lib/cmake/
SDL2-2.23.0/x86_64-w64-mingw32/lib/cmake/SDL2/
SDL2-2.23.0/x86_64-w64-mingw32/lib/cmake/SDL2/sdl2-config-version.cmake
SDL2-2.23.0/x86_64-w64-mingw32/lib/cmake/SDL2/sdl2-config.cmake
SDL2-2.23.0/i686-w64-mingw32/lib/cmake/
SDL2-2.23.0/i686-w64-mingw32/lib/cmake/SDL2/
SDL2-2.23.0/i686-w64-mingw32/lib/cmake/SDL2/sdl2-config-version.cmake
SDL2-2.23.0/i686-w64-mingw32/lib/cmake/SDL2/sdl2-config.cmake

and the Visual Studio development archive has the files:

SDL2-2.23.0/cmake/sdl2-config-version.cmake
SDL2-2.23.0/cmake/sdl2-config.cmake

The architecture specific mingw files look like this...

sdl2-config-version.cmake:

# sdl2 cmake project-config-version input for ./configure scripts

set(PACKAGE_VERSION "2.23.0")

if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
  set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
  set(PACKAGE_VERSION_COMPATIBLE TRUE)
  if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
    set(PACKAGE_VERSION_EXACT TRUE)
  endif()
endif()

sdl2-config.cmake:

# sdl2 cmake project-config input for ./configure script

include(FeatureSummary)
set_package_properties(SDL2 PROPERTIES
    URL "https://www.libsdl.org/"
    DESCRIPTION "low level access to audio, keyboard, mouse, joystick, and graphics hardware"
)

# Copied from `configure_package_config_file`
macro(set_and_check _var _file)
    set(${_var} "${_file}")
    if(NOT EXISTS "${_file}")
        message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
    endif()
endmacro()

# Copied from `configure_package_config_file`
macro(check_required_components _NAME)
    foreach(comp ${${_NAME}_FIND_COMPONENTS})
        if(NOT ${_NAME}_${comp}_FOUND)
            if(${_NAME}_FIND_REQUIRED_${comp})
                set(${_NAME}_FOUND FALSE)
            endif()
        endif()
    endforeach()
endmacro()

get_filename_component(prefix "${CMAKE_CURRENT_LIST_DIR}../../../.." ABSOLUTE)
set(exec_prefix "${prefix}")
set(bindir "${exec_prefix}/bin")
set(libdir "${exec_prefix}/lib")
set(includedir "${prefix}/include")

set_and_check(SDL2_PREFIX         "${prefix}")
set_and_check(SDL2_EXEC_PREFIX    "${exec_prefix}")
set_and_check(SDL2_BINDIR         "${bindir}")
set_and_check(SDL2_INCLUDE_DIR    "${includedir}/SDL2")
set_and_check(SDL2_LIBDIR         "${libdir}")
set(SDL2_INCLUDE_DIRS             "${includedir};${SDL2_INCLUDE_DIR}")

set(SDL2_LIBRARIES SDL2::SDL2)
set(SDL2_STATIC_LIBRARIES SDL2::SDL2-static)
set(SDL2MAIN_LIBRARY)
set(SDL2TEST_LIBRARY SDL2::SDL2test)

unset(prefix)
unset(exec_prefix)
unset(bindir)
unset(libdir)
unset(includedir)

set(_sdl2_libraries "-lmingw32 -lSDL2main -lSDL2 -mwindows")
set(_sdl2_static_private_libs " -Wl,--dynamicbase -Wl,--nxcompat -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid")

# Convert _sdl2_libraries to list and keep only libraries
string(REGEX MATCHALL "-[lm]([a-zA-Z0-9._]+)" _sdl2_libraries "${_sdl2_libraries}")
string(REGEX REPLACE "^-l" "" _sdl2_libraries "${_sdl2_libraries}")
string(REGEX REPLACE ";-l" ";" _sdl2_libraries "${_sdl2_libraries}")

# Convert _sdl2_static_private_libs to list and keep only libraries
string(REGEX MATCHALL "(-[lm]([a-zA-Z0-9._]+))|(-Wl,[^ ]*framework[^ ]*)" _sdl2_static_private_libs "${_sdl2_static_private_libs}")
string(REGEX REPLACE "^-l" "" _sdl2_static_private_libs "${_sdl2_static_private_libs}")
string(REGEX REPLACE ";-l" ";" _sdl2_static_private_libs "${_sdl2_static_private_libs}")

if(_sdl2_libraries MATCHES ".*SDL2main.*")
  list(INSERT SDL2_LIBRARIES 0 SDL2::SDL2main)
  list(INSERT SDL2_STATIC_LIBRARIES 0 SDL2::SDL2main)
  set(_sdl2main_library ${SDL2_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}SDL2main${CMAKE_STATIC_LIBRARY_SUFFIX})
  if(EXISTS "${_sdl2main_library}")
    set(SDL2MAIN_LIBRARY SDL2::SDL2main)
    if(NOT TARGET SDL2::SDL2main)
      add_library(SDL2::SDL2main STATIC IMPORTED)
      set_target_properties(SDL2::SDL2main
        PROPERTIES
          IMPORTED_LOCATION "${_sdl2main_library}"
      )
      if(WIN32)
        # INTERFACE_LINK_OPTIONS needs CMake 3.13
        cmake_minimum_required(VERSION 3.13)
        # Mark WinMain/WinMain@16 as undefined, such that it will be withheld by the linker.
        if(CMAKE_SIZEOF_VOID_P EQUAL 4)
          set_target_properties(SDL2::SDL2main
            PROPERTIES
              INTERFACE_LINK_OPTIONS "-Wl,--undefined=_WinMain@16"
          )
        else()
          set_target_properties(SDL2::SDL2main
            PROPERTIES
              INTERFACE_LINK_OPTIONS "-Wl,--undefined=WinMain"
          )
        endif()
      endif()
    endif()
    set(SDL2_SDL2main_FOUND TRUE)
  else()
    set(SDL2_SDL2main_FOUND FALSE)
  endif()
  unset(_sdl2main_library)
endif()

# Remove SDL2 since this is the "central" library
# Remove SDL2main since this will be provided by SDL2::SDL2main (if available)
# Remove mingw32 and cygwin since these are not needed when using `-Wl,--undefined,WinMain`
set(_sdl2_link_libraries ${_sdl2_libraries})
list(REMOVE_ITEM _sdl2_link_libraries SDL2 SDL2main mingw32 cygwin)

if(WIN32)
  set(_sdl2_implib "${SDL2_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}SDL2${CMAKE_SHARED_LIBRARY_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}")
  set(_sdl2_dll "${SDL2_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}SDL2${CMAKE_SHARED_LIBRARY_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}")
  if(EXISTS "${_sdl2_implib}" AND EXISTS "${_sdl2_dll}")
    if(NOT TARGET SDL2::SDL2)
      add_library(SDL2::SDL2 SHARED IMPORTED)
      set_target_properties(SDL2::SDL2 PROPERTIES
        INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}"
        INTERFACE_LINK_LIBRARIES "${_sdl2_link_libraries}"
        IMPORTED_LINK_INTERFACE_LANGUAGES "C"
        IMPORTED_IMPLIB "${_sdl2_implib}"
        IMPORTED_LOCATION "${_sdl2_dll}"
      )
    endif()
    set(SDL2_SDL2_FOUND TRUE)
  else()
    set(SDL2_SDL2_FOUND FALSE)
  endif()
  unset(_sdl2_implib)
  unset(_sdl2_dll)
else()
  set(_sdl2_shared "${SDL2_LIBDIR}/${CMAKE_SHARED_LIBRARY_PREFIX}SDL2${CMAKE_SHARED_LIBRARY_SUFFIX}")
  if(EXISTS "${_sdl2_shared}")
    if(NOT TARGET SDL2::SDL2)
      add_library(SDL2::SDL2 SHARED IMPORTED)
      set_target_properties(SDL2::SDL2 PROPERTIES
        INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}"
        INTERFACE_LINK_LIBRARIES "${_sdl2_link_libraries}"
        IMPORTED_LINK_INTERFACE_LANGUAGES "C"
        IMPORTED_LOCATION "${_sdl2_shared}"
      )
    endif()
    set(SDL2_SDL2_FOUND TRUE)
  else()
    set(SDL2_SDL2_FOUND FALSE)
  endif()
  unset(_sdl2_shared)
endif()

set(_sdl2_static "${SDL2_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}SDL2${CMAKE_STATIC_LIBRARY_SUFFIX}")
if(EXISTS "${_sdl2_static}")
  if(NOT TARGET SDL2::SDL2-static)
    add_library(SDL2::SDL2-static STATIC IMPORTED)
    set_target_properties(SDL2::SDL2-static
      PROPERTIES
        IMPORTED_LOCATION "${_sdl2_static}"
        INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}"
        INTERFACE_LINK_LIBRARIES "${_sdl2_link_libraries};${_sdl2_static_private_libs}"
        IMPORTED_LINK_INTERFACE_LANGUAGES "C"
    )
  endif()
  set(SDL2_SDL2-static_FOUND TRUE)
else()
  set(SDL2_SDL2-static_FOUND FALSE)
endif()
unset(_sdl2_static)

unset(_sdl2_link_libraries)

set(_sdl2test_library "${SDL2_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}SDL2_test${CMAKE_STATIC_LIBRARY_SUFFIX}")
if(EXISTS "${_sdl2test_library}")
  if(NOT TARGET SDL2::SDL2test)
    add_library(SDL2::SDL2test STATIC IMPORTED)
    set_target_properties(SDL2::SDL2test
      PROPERTIES
        IMPORTED_LOCATION "_sdl2test_library"
        INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}"
        IMPORTED_LINK_INTERFACE_LANGUAGES "C"
    )
  endif()
  set(SDL2_SDL2test_FOUND TRUE)
else()
  set(SDL2_SDL2test_FOUND FALSE)
endif()
unset(_sdl2test_library)

# Copied from `configure_package_config_file`
macro(check_required_components _NAME)
  foreach(comp ${${_NAME}_FIND_COMPONENTS})
    if(NOT ${_NAME}_${comp}_FOUND)
      if(${_NAME}_FIND_REQUIRED_${comp})
        set(${_NAME}_FOUND FALSE)
      endif()
    endif()
  endforeach()
endmacro()

check_required_components(SDL2)

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented Jun 3, 2022

I can create a 2.23.1 pre-release if you think it would be helpful for people to test the updated CMake support. Is now a good time, or do you have other things you'd like to address first?

Also, we should create similar Xcode, VC, and mingw cmake support files for the other SDL libraries. Let me know when you have them in, and I'll update the release build process to include them.

@madebr madebr deleted the cmake-tweaks branch June 3, 2022 20:14
@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented Jun 3, 2022

Okay, the mingw development archive has the files:

That looks correct. The MinGW development package is a frankenstein of 2 fully custom scripts in the root folder (=cmake subfolder) + the unmodified cmake scripts generated by autotools.

@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented Jun 3, 2022

I can create a 2.23.1 pre-release if you think it would be helpful for people to test the updated CMake support. Is now a good time, or do you have other things you'd like to address first?

Having a pre-release out would 100% help in knowing the CMake support is okay.
But first, I would like to eliminate all paths from a sdl2 prefix: there is only one remaining in bin/sdl2-config.

Also, we should create similar Xcode, VC, and mingw cmake support files for the other SDL libraries.

I'm currently working on sdl_image such that the other libraries can be simple adaptations of its "architecture".

Let me know when you have them in, and I'll update the release build process to include them.

I've got a question about the release process.
Right now, the cmake scripts in mingw/pkg-support, VisualC/pkg-support and Xcode/SDL/pkg-support are effectively dead code until they are put in a released tarball.
After creation of the tarballs, you should at least run the cmake script in cmake/test on them to know they are "compatible" with the ordinary cmake scripts.

@madebr
Copy link
Copy Markdown
Contributor Author

madebr commented Jun 3, 2022

While we're talking about the MinGW SDL2 SDK,
are the libtool *.la and the sdl2.pc file usable for users?

libSDL2.la contains the following line:

# Directory that this library needs to be installed in:
libdir='/Users/valve/release/SDL/SDL2-2.0.22/x86_64-w64-mingw32/lib'

and sdl2.pc assumes the following prefix:

prefix=/opt/local/x86_64-w64-mingw32

You'd need to extract the sdk in a specific location to get it working, so it seems.

@slouken
Copy link
Copy Markdown
Collaborator

slouken commented Jun 3, 2022

I have a script that fixes those paths on install.

madebr added a commit to libsdl-org/SDL_net that referenced this pull request Jun 14, 2022
#48

* Add CMake support.

Implementation is based off SDL2_Image.

* Add CMake tests to test-versioning.sh.

* Add CMake workflow

Changes link flags to fix mingw builds.

`showinterfaces` is disabled on MSVC workflow as the minimum version of SDL is too old for current MSVCRT and gives linker errors even when linking `legacy_stdio_definitions.lib`

* Apply suggestion from review

Only set `Compatible Interface Properties` for shared libraries.

Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>

* CMake: Define SDL_MAIN_HANDLED for showinterfaces.

This removes the need for SDL2main as it is a console-only application.
MSVC workflow now builds showinterfaces.

* Apply suggestion from review.

The `mingw32` library is no longer needed as `showinterfaces` is a console app.

Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>

* CMake: Update MSVC compiler flags.

Applied review suggestion to use `target_compile_options`.
Replaced `/wd4996` as `_WINSOCK_DEPRECATED_NO_WARNINGS` is enough.
Raise the warning level to `/W3` to be consistent with the solution in
`VisualC/`.

* Apply suggestions from code review.

- Set a different output name for static libraries on MSVC and WATCOM (cf. libsdl-org/SDL_image#275 and libsdl-org/SDL#5727)
- Fix `PKG_PREFIX` on Windows (cf. libsdl-org/SDL_image#274)

Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>

* CMake: Fix missing parenthesis.

* CMake: Remove dead code.

SDL_net does not build any dependency, so we don't need to force
position independent code.

* CMake: Add config files for XCode Frameworks

* CMake: Generate cmake config when using autotools.

* CMake: Add config files for mingw devel archive.

* CMake: Add config files for VC devel archive.

* Regenerate autotools file with CMake support.

* autogen.sh + cmake integration test

* Don't force an installed SDL2_net::SDL2_net-static to link with a specific SDL2 sharedness library

* Update PrivateSdlFunctions.cmake

* Apply suggestion from review.

Fix option de-duplication issues when linking with SDL2 framework.

Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>

* CMake: Escape framework parent path.

This is necessary if the framework has a space in its path.

* Apply suggestion from review.

Fix name mismatch between the bundled CMake config file for mingw and the generated config.

Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>

* Apply suggestion from review.

Fix regex match.

Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>

* Apply suggestion from review.

No longer set PKG_PREFIX on macOS.

Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>

Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>
Co-authored-by: Anonymous Maarten <anonymous.maarten@gmail.com>
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.

Inconsistent names for static libraries when built for windows with cmake.

4 participants