How to use prebuild config
Hi, Currently building SDL3 with CMake under Windows takes arround 9 minutes, most of time spent in configure part. Is there any way to make this step faster and use prebuild configurations (like: SDL_build_config_windows.h)
I've tried to dig the documentation and CMake file from root but didn't actually find the way.
Thanks in advance, Amer
I see the following configure times:
| Generator | SDL_LIBC=ON | SDL_LIBC=OFF |
|---|---|---|
| Ninja | 144.9s | 37.8s |
| Visual Studio | 216.2s | 46.5s |
These times are comparable with the CI times (201.5s).
Are these similar with your system?
Relinquishing control to the include files is not really "the CMake way".
I prototyped the following completely independent script that parses the vcxproj projects.
Copy it into VisualC/CMakeLists.txt, and use that instead.
VisualC/CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(SDL3 LANGUAGES C CXX)
if(NOT WIN32 OR NOT MSVC)
message(FATAL_ERROR "This CMake script only supports (non-UWP) Windows, using a MSVC compiler")
endif()
get_filename_component(SDL3_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/.." ABSOLUTE)
function(extract_vcxproj_sources SOURCES VCXPROJ_PATH)
set(sources )
get_filename_component(vcxproj_directory "${VCXPROJ_PATH}" DIRECTORY)
file(READ "${VCXPROJ_PATH}" vcxproj_content)
set(re_csource "<(ClCompile|ClInclude|ResourceCompile) Include=\"([.0-9a-zA-Z_\\]+)\"")
string(REGEX MATCHALL "${re_csource}" cmatches "${vcxproj_content}")
foreach(cmatch IN LISTS cmatches)
string(REGEX MATCH "${re_csource}" _ "${cmatch}")
file(TO_CMAKE_PATH "${CMAKE_MATCH_2}" csource)
get_filename_component(csource "${csource}" ABSOLUTE BASE_DIR "${vcxproj_directory}")
list(APPEND sources "${csource}")
endforeach()
if(NOT sources)
message(FATAL_ERROR "Failed to extract sources from ${VCXPROJ_PATH}")
endif()
set(${SOURCES} ${sources} PARENT_SCOPE)
endfunction()
add_library(SDL3_Headers INTERFACE)
add_library(SDL3::Headers ALIAS SDL3_Headers)
target_include_directories(SDL3_Headers INTERFACE "$<BUILD_INTERFACE:${SDL3_ROOT}/include>")
target_include_directories(SDL3_Headers INTERFACE "$<BUILD_INTERFACE:${SDL3_ROOT}/include/SDL3>")
extract_vcxproj_sources(SDL_SOURCES "SDL/SDL.vcxproj")
add_library(SDL3-shared SHARED ${SDL_SOURCES})
add_library(SDL3::SDL3-shared ALIAS SDL3-shared)
add_library(SDL3::SDL3 ALIAS SDL3-shared)
target_compile_definitions(SDL3-shared PRIVATE DLL_EXPORT)
target_include_directories(SDL3-shared PRIVATE "${SDL3_ROOT}/include/build_config")
target_include_directories(SDL3-shared PRIVATE "${SDL3_ROOT}/src")
target_link_libraries(SDL3-shared PUBLIC SDL3::Headers)
target_link_libraries(SDL3-shared PRIVATE setupapi winmm imm32 version)
set_property(TARGET SDL3-shared PROPERTY PREFIX "")
set_property(TARGET SDL3-shared PROPERTY OUTPUT_NAME "SDL3")
include(CMakeDependentOption)
option(SDL_TEST_LIBRARY "Build SDL3_test library" OFF)
cmake_dependent_option(SDL_TESTS "Build SDL test executables" ON SDL_TEST_LIBRARY OFF)
if(SDL_TEST_LIBRARY)
extract_vcxproj_sources(SDL_TEST_SOURCES "SDL_test/SDL_test.vcxproj")
add_library(SDL3_test STATIC ${SDL_TEST_SOURCES})
add_library(SDL3::SDL3_test ALIAS SDL3_test)
target_link_libraries(SDL3_test PUBLIC SDL3::Headers)
set_property(TARGET SDL3_test PROPERTY OUTPUT_NAME "SDL3_test")
endif()
if(SDL_TESTS)
file(GLOB_RECURSE TEST_VCXPROJS "tests/*.vcxproj")
foreach(test_vcxproj IN LISTS TEST_VCXPROJS)
get_filename_component(testname "${test_vcxproj}" NAME_WE)
extract_vcxproj_sources(TEST_SOURCES "${test_vcxproj}")
add_executable(${testname} ${TEST_SOURCES})
target_link_libraries(${testname} PRIVATE SDL3::SDL3_test SDL3::SDL3)
endforeach()
target_include_directories(testautomation PRIVATE "${SDL3_ROOT}/src")
endif()
Configure time drops to 5s since all compile tests have been eliminated.
@slouken I see this warning when building SDL with the vcxproj-parsing cmake script:
C:\Users\maarten\source\repos\SDL\src\video\windows\SDL_windowsevents.c(751,103): warning C4267: 'func
tion': conversion from 'size_t' to 'DWORD', possible loss of data [C:\Users\maarten\source\repos\SDL\b
uild-mingw\SDL3-shared.vcxproj]
@slouken I see this warning when building SDL with the vcxproj-parsing cmake script:
C:\Users\maarten\source\repos\SDL\src\video\windows\SDL_windowsevents.c(751,103): warning C4267: 'func tion': conversion from 'size_t' to 'DWORD', possible loss of data [C:\Users\maarten\source\repos\SDL\b uild-mingw\SDL3-shared.vcxproj]
Fixed, thanks!
BTW, I'll second my desire to have faster config times on Windows. It impacts me less because I do lots of iteration, but the initial cmake configuration step takes a really long time.
configuration step takes a really long time.
Can all the libc checks be skipped under windows?
configuration step takes a really long time.
Can all the libc checks be skipped under windows?
Only if you really really know what toolchain you're targeting, which the Visual Studio and Xcode projects do. The only configurability these offer is modification of the build_config headers.
Because the CMakeLists.txt should remain as platform-independent as possible, I think using the prebuilt config files is not a good direction. What we can do perhaps, is skip tests on MSVC by preseeding the cache. Those preseeded tests will then be skipped, improving configure time.
@slouken What is the minimum supported Visual Studio version? Can you configure SDL on this "old" version, and post the configure output + CMakeCache.txt here? This should probably also be repeated for all architectures, and for the latest supported VS2022. With those logs in hand, I can probably extract a minimum set of features MSVC supports.
Sure, I can get those for you soon.
What we can do perhaps, is skip tests on MSVC by preseeding the cache.
If that's possible, it would be a nice QoL change. In my current setup, the SDL3 configure phase alone takes more time than recompiling the whole code base. Most time is spent in "looking for {stdlib header}" checks, which also seem awfully slow for some weird reason.
I've included the entire cmake configuration for x86 and x64 with Visual Studio 2015, 2017, 2019, and 2022: cmake-visual-studio.zip
Thanks @slouken!
Can everybody here try #9570?
A huge speedup, and seems to work for me just fine. I don't think pre-seeding the COMPILER_SUPPORTS_xxx flags works though. Not sure what's wrong, but it looks like CHECK_CPU_ARCHITECTURE_X64 is not set/true on the very first configure pass with a clean cache.
A huge speedup, and seems to work for me just fine. I don't think pre-seeding the COMPILER_SUPPORTS_xxx flags works though. Not sure what's wrong, but it looks like CHECK_CPU_ARCHITECTURE_X64 is not set/true on the very first configure pass with a clean cache.
Makes sense! The preseeding should happen after detection of the architecture. It is an easy fix.
I created a poc that detects headers and libc functions in parallel using the preprocessor and c++20. It can provide a big time gain, but the c++ code is effectively Undefined Behavior. It would be cool if a similar approach would get supported. It works on at least MSVC2017+ and gcc12+.
https://github.com/madebr/cmake-symbol-test Check the GitHub workflow logs to see the ci times.
Makes sense! The preseeding should happen after detection of the architecture. It is an easy fix.
@madebr, have you already done this?
Makes sense! The preseeding should happen after detection of the architecture. It is an easy fix.
@madebr, have you already done this?
Given we have x86, x64, arm32, arm64 and arm64ec with MSVC, I don't know how to detect this with 100% confidence.
Besides, since the creation of this issue, detection of the cpu architecture has been sped up a lot.
Okay! I think we can close this then.