Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Runtime selection of platform (or window system) #1958

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 5 additions & 28 deletions .github/workflows/build.yml
Expand Up @@ -31,8 +31,8 @@ jobs:
- name: Build shared library
run: cmake --build build-shared --parallel

build-linux-wayland-clang:
name: Wayland (Linux, Clang)
build-linux-full-clang:
name: X11+Wayland (Linux, Clang)
runs-on: ubuntu-latest
env:
CC: clang
Expand All @@ -42,38 +42,15 @@ jobs:
- name: Install dependencies
run: |
sudo apt update
sudo apt install wayland-protocols libwayland-dev libxkbcommon-dev
sudo apt install libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxext-dev wayland-protocols libwayland-dev libxkbcommon-dev

- name: Configure static library
run: cmake -S . -B build-static -D GLFW_USE_WAYLAND=ON
run: cmake -S . -B build-static -D GLFW_BUILD_WAYLAND=ON
- name: Build static library
run: cmake --build build-static --parallel

- name: Configure shared library
run: cmake -S . -B build-shared -D GLFW_USE_WAYLAND=ON -D BUILD_SHARED_LIBS=ON
- name: Build shared library
run: cmake --build build-shared --parallel

build-linux-null-clang:
name: Null (Linux, Clang)
runs-on: ubuntu-latest
env:
CC: clang
CFLAGS: -Werror
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
sudo apt update
sudo apt install libosmesa6-dev

- name: Configure static library
run: cmake -S . -B build-static -D GLFW_USE_OSMESA=ON
- name: Build static library
run: cmake --build build-static --parallel

- name: Configure shared library
run: cmake -S . -B build-shared -D GLFW_USE_OSMESA=ON -D BUILD_SHARED_LIBS=ON
run: cmake -S . -B build-shared -D GLFW_BUILD_WAYLAND=ON -D BUILD_SHARED_LIBS=ON
- name: Build shared library
run: cmake --build build-shared --parallel

Expand Down
206 changes: 21 additions & 185 deletions CMakeLists.txt
Expand Up @@ -32,12 +32,13 @@ option(GLFW_VULKAN_STATIC "Assume the Vulkan loader is linked with the applicati
include(GNUInstallDirs)
include(CMakeDependentOption)

cmake_dependent_option(GLFW_USE_OSMESA "Use OSMesa for offscreen context creation" OFF
"UNIX" OFF)
cmake_dependent_option(GLFW_BUILD_WIN32 "Build support for Win32" ON "WIN32" OFF)
cmake_dependent_option(GLFW_BUILD_COCOA "Build support for Cocoa" ON "APPLE" OFF)
cmake_dependent_option(GLFW_BUILD_X11 "Build support for X11" ON "UNIX;NOT APPLE" OFF)
cmake_dependent_option(GLFW_BUILD_WAYLAND "Build support for Wayland" OFF "UNIX;NOT APPLE" OFF)

cmake_dependent_option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF
"WIN32" OFF)
cmake_dependent_option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF
"UNIX;NOT APPLE" OFF)
cmake_dependent_option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON
"MSVC" OFF)

Expand All @@ -54,22 +55,6 @@ else()
set(GLFW_BUILD_SHARED_LIBRARY ${BUILD_SHARED_LIBS})
endif()

if (UNIX AND GLFW_BUILD_SHARED_LIBRARY)
# On Unix-like systems, shared libraries can use the soname system.
set(GLFW_LIB_NAME glfw)
else()
set(GLFW_LIB_NAME glfw3)
endif()

if (GLFW_VULKAN_STATIC)
if (GLFW_BUILD_SHARED_LIBRARY)
# If you absolutely must do this, remove this line and add the Vulkan
# loader static library via the CMAKE_SHARED_LINKER_FLAGS
message(FATAL_ERROR "You are trying to link the Vulkan loader static library into the GLFW shared library")
endif()
set(_GLFW_VULKAN_STATIC 1)
endif()

list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")

find_package(Threads REQUIRED)
Expand All @@ -79,6 +64,22 @@ if (GLFW_BUILD_DOCS)
find_package(Doxygen)
endif()

#--------------------------------------------------------------------
# Report backend selection
#--------------------------------------------------------------------
if (GLFW_BUILD_WIN32)
message(STATUS "Including Win32 support")
endif()
if (GLFW_BUILD_COCOA)
message(STATUS "Including Cocoa support")
endif()
if (GLFW_BUILD_WAYLAND)
message(STATUS "Including Wayland support")
endif()
if (GLFW_BUILD_X11)
message(STATUS "Including X11 support")
endif()

#--------------------------------------------------------------------
# Apply Microsoft C runtime library option
# This is here because it also applies to tests and examples
Expand All @@ -104,169 +105,6 @@ if (MSVC AND NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
endif()
endif()

#--------------------------------------------------------------------
# Detect and select backend APIs
#--------------------------------------------------------------------
if (GLFW_USE_WAYLAND)
set(_GLFW_WAYLAND 1)
message(STATUS "Using Wayland for window creation")
elseif (GLFW_USE_OSMESA)
set(_GLFW_OSMESA 1)
message(STATUS "Using OSMesa for headless context creation")
elseif (WIN32)
set(_GLFW_WIN32 1)
message(STATUS "Using Win32 for window creation")
elseif (APPLE)
set(_GLFW_COCOA 1)
message(STATUS "Using Cocoa for window creation")
elseif (UNIX)
set(_GLFW_X11 1)
message(STATUS "Using X11 for window creation")
else()
message(FATAL_ERROR "No supported platform was detected")
endif()

#--------------------------------------------------------------------
# Find and add Unix math and time libraries
#--------------------------------------------------------------------
if (UNIX AND NOT APPLE)
find_library(RT_LIBRARY rt)
mark_as_advanced(RT_LIBRARY)
if (RT_LIBRARY)
list(APPEND glfw_LIBRARIES "${RT_LIBRARY}")
list(APPEND glfw_PKG_LIBS "-lrt")
endif()

find_library(MATH_LIBRARY m)
mark_as_advanced(MATH_LIBRARY)
if (MATH_LIBRARY)
list(APPEND glfw_LIBRARIES "${MATH_LIBRARY}")
list(APPEND glfw_PKG_LIBS "-lm")
endif()

if (CMAKE_DL_LIBS)
list(APPEND glfw_LIBRARIES "${CMAKE_DL_LIBS}")
list(APPEND glfw_PKG_LIBS "-l${CMAKE_DL_LIBS}")
endif()
endif()

#--------------------------------------------------------------------
# Use Win32 for window creation
#--------------------------------------------------------------------
if (_GLFW_WIN32)

list(APPEND glfw_PKG_LIBS "-lgdi32")

if (GLFW_USE_HYBRID_HPG)
set(_GLFW_USE_HYBRID_HPG 1)
endif()
endif()

#--------------------------------------------------------------------
# Use X11 for window creation
#--------------------------------------------------------------------
if (_GLFW_X11)

find_package(X11 REQUIRED)

# Set up library and include paths
list(APPEND glfw_INCLUDE_DIRS "${X11_X11_INCLUDE_PATH}")

# Check for XRandR (modern resolution switching and gamma control)
if (NOT X11_Xrandr_INCLUDE_PATH)
message(FATAL_ERROR "RandR headers not found; install libxrandr development package")
endif()

# Check for Xinerama (legacy multi-monitor support)
if (NOT X11_Xinerama_INCLUDE_PATH)
message(FATAL_ERROR "Xinerama headers not found; install libxinerama development package")
endif()

# Check for Xkb (X keyboard extension)
if (NOT X11_Xkb_INCLUDE_PATH)
message(FATAL_ERROR "XKB headers not found; install X11 development package")
endif()

# Check for Xcursor (cursor creation from RGBA images)
if (NOT X11_Xcursor_INCLUDE_PATH)
message(FATAL_ERROR "Xcursor headers not found; install libxcursor development package")
endif()

# Check for XInput (modern HID input)
if (NOT X11_Xi_INCLUDE_PATH)
message(FATAL_ERROR "XInput headers not found; install libxi development package")
endif()

# Check for X Shape (custom window input shape)
if (NOT X11_Xshape_INCLUDE_PATH)
message(FATAL_ERROR "X Shape headers not found; install libxext development package")
endif()
endif()

#--------------------------------------------------------------------
# Use Wayland for window creation
#--------------------------------------------------------------------
if (_GLFW_WAYLAND)

include(FindPkgConfig)
pkg_check_modules(Wayland REQUIRED
wayland-client>=0.2.7
wayland-cursor>=0.2.7
wayland-egl>=0.2.7
xkbcommon)

list(APPEND glfw_INCLUDE_DIRS "${Wayland_INCLUDE_DIRS}")

include(CheckIncludeFiles)
include(CheckFunctionExists)
check_include_files(xkbcommon/xkbcommon-compose.h HAVE_XKBCOMMON_COMPOSE_H)
check_function_exists(memfd_create HAVE_MEMFD_CREATE)

if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
find_package(EpollShim)
if (EPOLLSHIM_FOUND)
list(APPEND glfw_INCLUDE_DIRS "${EPOLLSHIM_INCLUDE_DIRS}")
list(APPEND glfw_LIBRARIES "${EPOLLSHIM_LIBRARIES}")
endif()
endif()
endif()

#--------------------------------------------------------------------
# Use Cocoa for window creation and NSOpenGL for context creation
#--------------------------------------------------------------------
if (_GLFW_COCOA)

list(APPEND glfw_LIBRARIES
"-framework Cocoa"
"-framework IOKit"
"-framework CoreFoundation")

set(glfw_PKG_DEPS "")
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation")
endif()

#--------------------------------------------------------------------
# Add the Vulkan loader as a dependency if necessary
#--------------------------------------------------------------------
if (GLFW_VULKAN_STATIC)
list(APPEND glfw_PKG_DEPS "vulkan")
endif()

#--------------------------------------------------------------------
# Export GLFW library dependencies
#--------------------------------------------------------------------
foreach(arg ${glfw_PKG_DEPS})
string(APPEND deps " ${arg}")
endforeach()
foreach(arg ${glfw_PKG_LIBS})
string(APPEND libs " ${arg}")
endforeach()

set(GLFW_PKG_CONFIG_REQUIRES_PRIVATE "${deps}" CACHE INTERNAL
"GLFW pkg-config Requires.private")
set(GLFW_PKG_CONFIG_LIBS_PRIVATE "${libs}" CACHE INTERNAL
"GLFW pkg-config Libs.private")

#--------------------------------------------------------------------
# Create generated files
#--------------------------------------------------------------------
Expand All @@ -283,8 +121,6 @@ write_basic_package_version_file(src/glfw3ConfigVersion.cmake
VERSION ${GLFW_VERSION}
COMPATIBILITY SameMajorVersion)

configure_file(CMake/glfw3.pc.in src/glfw3.pc @ONLY)

#--------------------------------------------------------------------
# Add subdirectories
#--------------------------------------------------------------------
Expand Down
5 changes: 5 additions & 0 deletions README.md
Expand Up @@ -116,6 +116,9 @@ information on what to include when reporting a bug.

## Changelog

- Added `GLFW_PLATFORM` init hint for runtime platform selection
- Added `glfwGetPlatform` function to query what platform was selected
- Added `glfwPlatformSupported` function to query if a platform is supported
- Added `glfwInitAllocator` for setting a custom memory allocator (#544,#1628,#1947)
- Added `GLFWallocator` struct and `GLFWallocatefun`, `GLFWreallocatefun` and
`GLFWdeallocatefun` types (#544,#1628,#1947)
Expand All @@ -140,6 +143,7 @@ information on what to include when reporting a bug.
- Made `GLFW_DOUBLEBUFFER` a read-only window attribute
- Updated the minimum required CMake version to 3.1
- Disabled tests and examples by default when built as a CMake subdirectory
- Removed CMake generated configuration header
- Bugfix: The CMake config-file package used an absolute path and was not
relocatable (#1470)
- Bugfix: Video modes with a duplicate screen area were discarded (#1555,#1556)
Expand Down Expand Up @@ -433,6 +437,7 @@ skills.
- Eddie Ringle
- Max Risuhin
- Jorge Rodriguez
- Jari Ronkainen
- Luca Rood
- Ed Ropple
- Aleksey Rybalkin
Expand Down
9 changes: 4 additions & 5 deletions docs/compile.dox
Expand Up @@ -341,11 +341,10 @@ a configuration macro to be defined in order to know what window system it is
being compiled for and also has optional, platform-specific ones for various
features.

When building with CMake, the `glfw_config.h` configuration header is generated
based on the current platform and CMake options. The GLFW CMake environment
defines @b GLFW_USE_CONFIG_H, which causes this header to be included by
`internal.h`. Without this macro, GLFW will expect the necessary configuration
macros to be defined on the command-line.
When building, GLFW will expect the necessary configuration macros to be defined
on the command-line. The GLFW CMake files set these as private compile
definitions on the GLFW target but if you compile the GLFW sources manually you
will need to define them yourself.

The window creation API is used to create windows, handle input, monitors, gamma
ramps and clipboard. The options are:
Expand Down
3 changes: 1 addition & 2 deletions docs/internal.dox
Expand Up @@ -104,8 +104,7 @@ Examples: `isValidElementForJoystick`
@section internals_config Configuration macros

GLFW uses a number of configuration macros to select at compile time which
interfaces and code paths to use. They are defined in the glfw_config.h header file,
which is generated from the `glfw_config.h.in` file by CMake.
interfaces and code paths to use. They are defined in the GLFW CMake target.

Configuration macros the same style as tokens in the public interface, except
with a leading underscore.
Expand Down
11 changes: 11 additions & 0 deletions docs/intro.dox
Expand Up @@ -30,6 +30,7 @@ successfully initialized, and only from the main thread.

- @ref glfwGetVersion
- @ref glfwGetVersionString
- @ref glfwPlatformSupported
- @ref glfwGetError
- @ref glfwSetErrorCallback
- @ref glfwInitHint
Expand Down Expand Up @@ -89,6 +90,15 @@ Setting these hints requires no platform specific headers or functions.

@subsubsection init_hints_shared Shared init hints

@anchor GLFW_PLATFORM
__GLFW_PLATFORM__ specifies the platform to use for windowing and input.
Possible values are `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`,
`GLFW_PLATFORM_COCOA`, `GLFW_PLATFORM_X11`, `GLFW_PLATFORM_WAYLAND` and
`GLFW_PLATFORM_NULL`. The default value is `GLFW_ANY_PLATFORM`, which will
choose any platform the library includes support for except for the null
backend.


@anchor GLFW_JOYSTICK_HAT_BUTTONS
__GLFW_JOYSTICK_HAT_BUTTONS__ specifies whether to also expose joystick hats as
buttons, for compatibility with earlier versions of GLFW that did not have @ref
Expand Down Expand Up @@ -137,6 +147,7 @@ the `VK_KHR_xlib_surface` extension. Possible values are `GLFW_TRUE` and

Initialization hint | Default value | Supported values
-------------------------------- | ------------------------------- | ----------------
@ref GLFW_PLATFORM | `GLFW_ANY_PLATFORM` | `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`, `GLFW_PLATFORM_X11`, `GLFW_PLATFORM_WAYLAND` or `GLFW_PLATFORM_NULL`
@ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_ANGLE_PLATFORM_TYPE | `GLFW_ANGLE_PLATFORM_TYPE_NONE` | `GLFW_ANGLE_PLATFORM_TYPE_NONE`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGL`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGLES`, `GLFW_ANGLE_PLATFORM_TYPE_D3D9`, `GLFW_ANGLE_PLATFORM_TYPE_D3D11`, `GLFW_ANGLE_PLATFORM_TYPE_VULKAN` or `GLFW_ANGLE_PLATFORM_TYPE_METAL`
@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
Expand Down