1 cmake_minimum_required(VERSION 3.1...3.17 FATAL_ERROR)
3 project(GLFW VERSION 3.4.0 LANGUAGES C)
5 set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
8 cmake_policy(SET CMP0054 NEW)
12 cmake_policy(SET CMP0069 NEW)
16 cmake_policy(SET CMP0077 NEW)
19 set_property(GLOBAL PROPERTY USE_FOLDERS ON)
21 if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
22 set(GLFW_STANDALONE TRUE)
25 option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
26 option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ${GLFW_STANDALONE})
27 option(GLFW_BUILD_TESTS "Build the GLFW test programs" ${GLFW_STANDALONE})
28 option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON)
29 option(GLFW_INSTALL "Generate installation target" ON)
30 option(GLFW_VULKAN_STATIC "Assume the Vulkan loader is linked with the application" OFF)
32 include(GNUInstallDirs)
33 include(CMakeDependentOption)
35 cmake_dependent_option(GLFW_USE_OSMESA "Use OSMesa for offscreen context creation" OFF
37 cmake_dependent_option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF
39 cmake_dependent_option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF
41 cmake_dependent_option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON
44 if (BUILD_SHARED_LIBS)
45 set(_GLFW_BUILD_DLL 1)
48 if (BUILD_SHARED_LIBS AND UNIX)
49 # On Unix-like systems, shared libraries can use the soname system.
50 set(GLFW_LIB_NAME glfw)
52 set(GLFW_LIB_NAME glfw3)
55 if (GLFW_VULKAN_STATIC)
56 if (BUILD_SHARED_LIBS)
57 # If you absolutely must do this, remove this line and add the Vulkan
58 # loader static library via the CMAKE_SHARED_LINKER_FLAGS
59 message(FATAL_ERROR "You are trying to link the Vulkan loader static library into the GLFW shared library")
61 set(_GLFW_VULKAN_STATIC 1)
64 list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
66 find_package(Threads REQUIRED)
69 set(DOXYGEN_SKIP_DOT TRUE)
73 #--------------------------------------------------------------------
74 # Set compiler specific flags
75 #--------------------------------------------------------------------
78 # Workaround for VS 2008 not shipping with the DirectX 9 SDK
79 include(CheckIncludeFile)
80 check_include_file(dinput.h DINPUT_H_FOUND)
81 if (NOT DINPUT_H_FOUND)
82 message(FATAL_ERROR "DirectX 9 headers not found; install DirectX 9 SDK")
84 # Workaround for VS 2008 not shipping with stdint.h
85 list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/vs2008")
88 if (NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
89 foreach (flag CMAKE_C_FLAGS
92 CMAKE_C_FLAGS_MINSIZEREL
93 CMAKE_C_FLAGS_RELWITHDEBINFO)
95 if (${flag} MATCHES "/MD")
96 string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
98 if (${flag} MATCHES "/MDd")
99 string(REGEX REPLACE "/MDd" "/MTd" ${flag} "${${flag}}")
107 # Workaround for legacy MinGW not providing XInput and DirectInput
108 include(CheckIncludeFile)
110 check_include_file(dinput.h DINPUT_H_FOUND)
111 check_include_file(xinput.h XINPUT_H_FOUND)
112 if (NOT DINPUT_H_FOUND OR NOT XINPUT_H_FOUND)
113 list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/mingw")
116 # Enable link-time exploit mitigation features enabled by default on MSVC
117 include(CheckCCompilerFlag)
119 # Compatibility with data execution prevention (DEP)
120 set(CMAKE_REQUIRED_FLAGS "-Wl,--nxcompat")
121 check_c_compiler_flag("" _GLFW_HAS_DEP)
123 set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--nxcompat ${CMAKE_SHARED_LINKER_FLAGS}")
126 # Compatibility with address space layout randomization (ASLR)
127 set(CMAKE_REQUIRED_FLAGS "-Wl,--dynamicbase")
128 check_c_compiler_flag("" _GLFW_HAS_ASLR)
130 set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--dynamicbase ${CMAKE_SHARED_LINKER_FLAGS}")
133 # Compatibility with 64-bit address space layout randomization (ASLR)
134 set(CMAKE_REQUIRED_FLAGS "-Wl,--high-entropy-va")
135 check_c_compiler_flag("" _GLFW_HAS_64ASLR)
136 if (_GLFW_HAS_64ASLR)
137 set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--high-entropy-va ${CMAKE_SHARED_LINKER_FLAGS}")
141 #--------------------------------------------------------------------
142 # Detect and select backend APIs
143 #--------------------------------------------------------------------
144 if (GLFW_USE_WAYLAND)
146 message(STATUS "Using Wayland for window creation")
147 elseif (GLFW_USE_OSMESA)
149 message(STATUS "Using OSMesa for headless context creation")
152 message(STATUS "Using Win32 for window creation")
155 message(STATUS "Using Cocoa for window creation")
158 message(STATUS "Using X11 for window creation")
160 message(FATAL_ERROR "No supported platform was detected")
163 #--------------------------------------------------------------------
164 # Find and add Unix math and time libraries
165 #--------------------------------------------------------------------
166 if (UNIX AND NOT APPLE)
167 find_library(RT_LIBRARY rt)
168 mark_as_advanced(RT_LIBRARY)
170 list(APPEND glfw_LIBRARIES "${RT_LIBRARY}")
171 list(APPEND glfw_PKG_LIBS "-lrt")
174 find_library(MATH_LIBRARY m)
175 mark_as_advanced(MATH_LIBRARY)
177 list(APPEND glfw_LIBRARIES "${MATH_LIBRARY}")
178 list(APPEND glfw_PKG_LIBS "-lm")
182 list(APPEND glfw_LIBRARIES "${CMAKE_DL_LIBS}")
183 list(APPEND glfw_PKG_LIBS "-l${CMAKE_DL_LIBS}")
187 #--------------------------------------------------------------------
188 # Use Win32 for window creation
189 #--------------------------------------------------------------------
192 list(APPEND glfw_PKG_LIBS "-lgdi32")
194 if (GLFW_USE_HYBRID_HPG)
195 set(_GLFW_USE_HYBRID_HPG 1)
199 #--------------------------------------------------------------------
200 # Use X11 for window creation
201 #--------------------------------------------------------------------
204 find_package(X11 REQUIRED)
206 list(APPEND glfw_PKG_DEPS "x11")
208 # Set up library and include paths
209 list(APPEND glfw_INCLUDE_DIRS "${X11_X11_INCLUDE_PATH}")
210 list(APPEND glfw_LIBRARIES "${X11_X11_LIB}" "${CMAKE_THREAD_LIBS_INIT}")
212 # Check for XRandR (modern resolution switching and gamma control)
213 if (NOT X11_Xrandr_INCLUDE_PATH)
214 message(FATAL_ERROR "RandR headers not found; install libxrandr development package")
217 # Check for Xinerama (legacy multi-monitor support)
218 if (NOT X11_Xinerama_INCLUDE_PATH)
219 message(FATAL_ERROR "Xinerama headers not found; install libxinerama development package")
222 # Check for Xkb (X keyboard extension)
223 if (NOT X11_Xkb_INCLUDE_PATH)
224 message(FATAL_ERROR "XKB headers not found; install X11 development package")
227 # Check for Xcursor (cursor creation from RGBA images)
228 if (NOT X11_Xcursor_INCLUDE_PATH)
229 message(FATAL_ERROR "Xcursor headers not found; install libxcursor development package")
232 # Check for XInput (modern HID input)
233 if (NOT X11_Xi_INCLUDE_PATH)
234 message(FATAL_ERROR "XInput headers not found; install libxi development package")
237 # Check for X Shape (custom window input shape)
238 if (NOT X11_Xshape_INCLUDE_PATH)
239 message(FATAL_ERROR "X Shape headers not found; install libxext development package")
242 list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}"
243 "${X11_Xinerama_INCLUDE_PATH}"
244 "${X11_Xkb_INCLUDE_PATH}"
245 "${X11_Xcursor_INCLUDE_PATH}"
246 "${X11_Xi_INCLUDE_PATH}")
249 #--------------------------------------------------------------------
250 # Use Wayland for window creation
251 #--------------------------------------------------------------------
253 find_package(ECM REQUIRED NO_MODULE)
254 list(APPEND CMAKE_MODULE_PATH "${ECM_MODULE_PATH}")
256 find_package(Wayland REQUIRED Client Cursor Egl)
257 find_package(WaylandScanner REQUIRED)
258 find_package(WaylandProtocols 1.15 REQUIRED)
260 list(APPEND glfw_PKG_DEPS "wayland-egl")
262 list(APPEND glfw_INCLUDE_DIRS "${Wayland_INCLUDE_DIRS}")
263 list(APPEND glfw_LIBRARIES "${Wayland_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}")
265 find_package(XKBCommon REQUIRED)
266 list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}")
268 include(CheckIncludeFiles)
269 include(CheckFunctionExists)
270 check_include_files(xkbcommon/xkbcommon-compose.h HAVE_XKBCOMMON_COMPOSE_H)
271 check_function_exists(memfd_create HAVE_MEMFD_CREATE)
273 if (NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux"))
274 find_package(EpollShim)
276 list(APPEND glfw_INCLUDE_DIRS "${EPOLLSHIM_INCLUDE_DIRS}")
277 list(APPEND glfw_LIBRARIES "${EPOLLSHIM_LIBRARIES}")
282 #--------------------------------------------------------------------
283 # Use OSMesa for offscreen context creation
284 #--------------------------------------------------------------------
286 find_package(OSMesa REQUIRED)
287 list(APPEND glfw_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
290 #--------------------------------------------------------------------
291 # Use Cocoa for window creation and NSOpenGL for context creation
292 #--------------------------------------------------------------------
295 list(APPEND glfw_LIBRARIES
298 "-framework CoreFoundation")
300 set(glfw_PKG_DEPS "")
301 set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation")
304 #--------------------------------------------------------------------
305 # Add the Vulkan loader as a dependency if necessary
306 #--------------------------------------------------------------------
307 if (GLFW_VULKAN_STATIC)
308 list(APPEND glfw_PKG_DEPS "vulkan")
311 #--------------------------------------------------------------------
312 # Export GLFW library dependencies
313 #--------------------------------------------------------------------
314 foreach(arg ${glfw_PKG_DEPS})
315 set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} ${arg}" CACHE INTERNAL
316 "GLFW pkg-config Requires.private")
318 foreach(arg ${glfw_PKG_LIBS})
319 set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} ${arg}" CACHE INTERNAL
320 "GLFW pkg-config Libs.private")
323 #--------------------------------------------------------------------
324 # Create generated files
325 #--------------------------------------------------------------------
326 include(CMakePackageConfigHelpers)
328 set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_LIBDIR}/cmake/glfw3")
330 configure_package_config_file(CMake/glfw3Config.cmake.in
331 src/glfw3Config.cmake
332 INSTALL_DESTINATION "${GLFW_CONFIG_PATH}"
333 NO_CHECK_REQUIRED_COMPONENTS_MACRO)
335 write_basic_package_version_file(src/glfw3ConfigVersion.cmake
336 VERSION ${GLFW_VERSION}
337 COMPATIBILITY SameMajorVersion)
339 configure_file(src/glfw_config.h.in src/glfw_config.h @ONLY)
341 configure_file(CMake/glfw3.pc.in CMake/glfw3.pc @ONLY)
343 #--------------------------------------------------------------------
345 #--------------------------------------------------------------------
346 add_subdirectory(src)
348 if (GLFW_BUILD_EXAMPLES)
349 add_subdirectory(examples)
352 if (GLFW_BUILD_TESTS)
353 add_subdirectory(tests)
356 if (DOXYGEN_FOUND AND GLFW_BUILD_DOCS)
357 add_subdirectory(docs)
360 #--------------------------------------------------------------------
361 # Install files other than the library
362 # The library is installed by src/CMakeLists.txt
363 #--------------------------------------------------------------------
365 install(DIRECTORY include/GLFW DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
366 FILES_MATCHING PATTERN glfw3.h PATTERN glfw3native.h)
368 install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake"
369 "${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake"
370 DESTINATION "${GLFW_CONFIG_PATH}")
372 install(EXPORT glfwTargets FILE glfw3Targets.cmake
373 EXPORT_LINK_INTERFACE_LIBRARIES
374 DESTINATION "${GLFW_CONFIG_PATH}")
375 install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc"
376 DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
378 if (DOXYGEN_FOUND AND GLFW_BUILD_DOCS)
379 install(DIRECTORY "${GLFW_BINARY_DIR}/docs/html"
380 DESTINATION "${CMAKE_INSTALL_DOCDIR}")
383 # Only generate this target if no higher-level project already has
384 if (NOT TARGET uninstall)
385 configure_file(CMake/cmake_uninstall.cmake.in
386 cmake_uninstall.cmake IMMEDIATE @ONLY)
388 add_custom_target(uninstall
389 "${CMAKE_COMMAND}" -P
390 "${GLFW_BINARY_DIR}/cmake_uninstall.cmake")
391 set_target_properties(uninstall PROPERTIES FOLDER "GLFW3")