diff --git a/CMakeLists.txt b/CMakeLists.txt index 15bfee8a..2ca7d353 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,36 +1,51 @@ cmake_minimum_required(VERSION 3.16) project(MiniFB VERSION 0.10.1 LANGUAGES C CXX) -if (APPLE) +message(STATUS "Processing " ${PROJECT_NAME}) + +# CMake configuration +#-------------------------------------- + +# prefer these over general `UNIX` or `APPLE` +# `UNIX` also overlaps MacOS, iOS, and Emscripten, which we don't want +if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(LINUX TRUE) +elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(MACOS TRUE) +endif() + +# ensure that an objective-c compiler exists when attempting to compile on any target that uses objective-c +if (MACOS OR IOS) include(CheckLanguage) check_language(OBJC) - if (CMAKE_OBJC_COMPILER) + if (CMAKE_OBJC_COMPILER STREQUAL "NOTFOUND") + message(FATAL "No OBJC compiler could be found.") + else() enable_language(OBJC) endif() endif() -message(STATUS "Processing " ${PROJECT_NAME}) - include(GNUInstallDirs) -include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/versioning.cmake") -include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/minifb_cmake_helpers.cmake") -if (POLICY CMP0072) - cmake_policy(SET CMP0072 NEW) # Prefer GLVND -endif() -set(OpenGL_GL_PREFERENCE "GLVND") +include("cmake/minifb_cmake_helpers.cmake") +# use IDE folders in build systems that support it. enabled by default in cmake 3.26+ +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +# directory to add generated headers (created during configuration) +set(MINIFB_GENERATED_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated") +file(MAKE_DIRECTORY "${MINIFB_GENERATED_INCLUDE_DIR}") + +# generate the version header from the templace (.in) minifb_compute_git_metadata( MINIFB_COMMITS_SINCE_TAG MINIFB_COMMIT_COUNT MINIFB_GIT_SHA MINIFB_GIT_DIRTY ) - -set(MINIFB_GENERATED_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated") -minifb_configure_version_header( - "${CMAKE_CURRENT_SOURCE_DIR}/include/minifb_version.h.in" - "${MINIFB_GENERATED_INCLUDE_DIR}" +configure_file( + include/minifb_version.h.in "${MINIFB_GENERATED_INCLUDE_DIR}/minifb_version.h" + @ONLY ) # Sources @@ -43,6 +58,9 @@ set(SrcLib include/MiniFB_macros.h include/MiniFB_types.h + # remember to include generated headers as source files + "${MINIFB_GENERATED_INCLUDE_DIR}/minifb_version.h" + src/MiniFB_common.c src/MiniFB_cpp.cpp src/MiniFB_internal.c @@ -122,232 +140,305 @@ set(SrcDOS src/dos/vesa.c ) -# Set features -#-------------------------------------- -set(MINIFB_C_STANDARD 11) -set(MINIFB_CXX_STANDARD 11) - -set(MINIFB_COMPILE_OPTIONS) -set(MINIFB_COMPILE_DEFINITIONS) -set(MINIFB_LINK_OPTIONS_LIB) -set(MINIFB_LINK_OPTIONS_EXE) - -if (DJGPP) - # DJGPP headers expose key DOS APIs only in GNU (non-strict ANSI) mode. - set(MINIFB_C_EXTENSIONS ON) - set(MINIFB_CXX_EXTENSIONS ON) -else() - set(MINIFB_C_EXTENSIONS OFF) - set(MINIFB_CXX_EXTENSIONS OFF) -endif() - # Options #-------------------------------------- option(MINIFB_BUILD_EXAMPLES "Build minifb example programs" TRUE) option(MINIFB_AVOID_CPP_HEADERS "Avoid including C++ Headers" FALSE) -if (NOT IOS AND NOT ANDROID AND NOT EMSCRIPTEN) - option(MINIFB_BUILD_VERSION_INFO "Build version info utility" ON) -else() - set(MINIFB_BUILD_VERSION_INFO OFF) -endif() +# purely for internal use, never exposed to the user +set(MINIFB_USE_X11_API OFF) -if (APPLE AND NOT IOS) - option(MINIFB_USE_METAL_API "Build the project using metal API code" ON) - option(MINIFB_USE_INVERTED_Y_ON_MACOS "Use default mouse position: (0, 0) at (left, down)" OFF) - minifb_apply_deprecated_option(USE_METAL_API MINIFB_USE_METAL_API "Build the project using metal API code") +# unfortunatly these old deprecated options can't fit nicely into dependent options due to our custom function, but when we remove these, we can remove this whole block +if (MACOS) + minifb_apply_deprecated_option(USE_METAL_API MINIFB_USE_METAL_API "Build the project using Metal API code") minifb_apply_deprecated_option(USE_INVERTED_Y_ON_MACOS MINIFB_USE_INVERTED_Y_ON_MACOS "Use default mouse position: (0, 0) at (left, down)") -elseif (UNIX AND NOT EMSCRIPTEN) - option(MINIFB_USE_WAYLAND_API "Build the project using wayland API code" OFF) - option(MINIFB_USE_OPENGL_API "Build the project using OpenGL API code" ON) - minifb_apply_deprecated_option(USE_WAYLAND_API MINIFB_USE_WAYLAND_API "Build the project using wayland API code") - minifb_apply_deprecated_option(USE_OPENGL_API MINIFB_USE_OPENGL_API "Build the project using OpenGL API code") +elseif (LINUX) + minifb_apply_deprecated_option(USE_WAYLAND_API MINIFB_USE_WAYLAND_API "Build the project using Wayland API code") + if (NOT MINIFB_USE_WAYLAND_API) + set(MINIFB_USE_X11_API ON) + minifb_apply_deprecated_option(USE_OPENGL_API MINIFB_USE_OPENGL_API "Build the project using OpenGL API code") + endif() elseif (WIN32) - option(MINIFB_USE_OPENGL_API "Build the project using OpenGL API code" ON) minifb_apply_deprecated_option(USE_OPENGL_API MINIFB_USE_OPENGL_API "Build the project using OpenGL API code") endif() -# Set compile flags depending on the compiler -#-------------------------------------- -if (NOT MSVC) +if (NOT MINIFB_HAVE_SET_LEGACY_OPTION) # only use new options if no legacy options are used to prevent conflicts - # GCC/Clang +if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.22) - if (DJGPP) - list(APPEND MINIFB_COMPILE_OPTIONS - "$<$:-gdwarf>" - "$<$:-save-temps>" - ) - else() - list(APPEND MINIFB_COMPILE_OPTIONS - "$<$:-g>" - ) - endif() + # requires 3.22+ to use full condition syntax, technically could use in 3.16, but it would be a lot worse + include(CMakeDependentOption) - list(APPEND MINIFB_COMPILE_OPTIONS - -Wall - -Wextra - -Wno-switch - -Wno-unused-function - -Wno-unused-parameter - -Wno-implicit-fallthrough - "$,-O0,-O2>" - ) + # cmake_dependent_option is used to create a default value for options in case their specific condition isn't met. + # the first 3 args are the same as a normal option(), but the 4th is a condition, where if it's true, expose the option, and if it isn't, the 5th argument is a default value to use. + # setting the default value lets us de-nest `if() if(