CMakeLists.txt (13945B)
1 2 add_library(glfw ${GLFW_LIBRARY_TYPE} 3 "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h" 4 "${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h" 5 internal.h platform.h mappings.h 6 context.c init.c input.c monitor.c platform.c vulkan.c window.c 7 egl_context.c osmesa_context.c null_platform.h null_joystick.h 8 null_init.c null_monitor.c null_window.c null_joystick.c) 9 10 # The time, thread and module code is shared between all backends on a given OS, 11 # including the null backend, which still needs those bits to be functional 12 if (APPLE) 13 target_sources(glfw PRIVATE cocoa_time.h cocoa_time.c posix_thread.h 14 posix_module.c posix_thread.c) 15 elseif (WIN32) 16 target_sources(glfw PRIVATE win32_time.h win32_thread.h win32_module.c 17 win32_time.c win32_thread.c) 18 else() 19 target_sources(glfw PRIVATE posix_time.h posix_thread.h posix_module.c 20 posix_time.c posix_thread.c) 21 endif() 22 23 add_custom_target(update_mappings 24 COMMAND "${CMAKE_COMMAND}" -P "${GLFW_SOURCE_DIR}/CMake/GenerateMappings.cmake" mappings.h.in mappings.h 25 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 26 COMMENT "Updating gamepad mappings from upstream repository" 27 SOURCES mappings.h.in "${GLFW_SOURCE_DIR}/CMake/GenerateMappings.cmake" 28 VERBATIM) 29 30 set_target_properties(update_mappings PROPERTIES FOLDER "GLFW3") 31 32 if (GLFW_BUILD_COCOA) 33 target_compile_definitions(glfw PRIVATE _GLFW_COCOA) 34 target_sources(glfw PRIVATE cocoa_platform.h cocoa_joystick.h cocoa_init.m 35 cocoa_joystick.m cocoa_monitor.m cocoa_window.m 36 nsgl_context.m) 37 endif() 38 39 if (GLFW_BUILD_WIN32) 40 target_compile_definitions(glfw PRIVATE _GLFW_WIN32) 41 target_sources(glfw PRIVATE win32_platform.h win32_joystick.h win32_init.c 42 win32_joystick.c win32_monitor.c win32_window.c 43 wgl_context.c) 44 endif() 45 46 if (GLFW_BUILD_X11) 47 target_compile_definitions(glfw PRIVATE _GLFW_X11) 48 target_sources(glfw PRIVATE x11_platform.h xkb_unicode.h x11_init.c 49 x11_monitor.c x11_window.c xkb_unicode.c 50 glx_context.c) 51 endif() 52 53 if (GLFW_BUILD_WAYLAND) 54 target_compile_definitions(glfw PRIVATE _GLFW_WAYLAND) 55 target_sources(glfw PRIVATE wl_platform.h xkb_unicode.h wl_init.c 56 wl_monitor.c wl_window.c xkb_unicode.c) 57 endif() 58 59 if (GLFW_BUILD_X11 OR GLFW_BUILD_WAYLAND) 60 if (CMAKE_SYSTEM_NAME STREQUAL "Linux") 61 target_sources(glfw PRIVATE linux_joystick.h linux_joystick.c) 62 endif() 63 target_sources(glfw PRIVATE posix_poll.h posix_poll.c) 64 endif() 65 66 if (GLFW_BUILD_WAYLAND) 67 include(CheckIncludeFiles) 68 include(CheckFunctionExists) 69 check_function_exists(memfd_create HAVE_MEMFD_CREATE) 70 if (HAVE_MEMFD_CREATE) 71 target_compile_definitions(glfw PRIVATE HAVE_MEMFD_CREATE) 72 endif() 73 74 find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner) 75 if (NOT WAYLAND_SCANNER_EXECUTABLE) 76 message(FATAL_ERROR "Failed to find wayland-scanner") 77 endif() 78 79 macro(generate_wayland_protocol protocol_file) 80 set(protocol_path "${GLFW_SOURCE_DIR}/deps/wayland/${protocol_file}") 81 82 string(REGEX REPLACE "\\.xml$" "-client-protocol.h" header_file ${protocol_file}) 83 string(REGEX REPLACE "\\.xml$" "-client-protocol-code.h" code_file ${protocol_file}) 84 85 add_custom_command(OUTPUT ${header_file} 86 COMMAND "${WAYLAND_SCANNER_EXECUTABLE}" client-header "${protocol_path}" ${header_file} 87 DEPENDS "${protocol_path}" 88 VERBATIM) 89 90 add_custom_command(OUTPUT ${code_file} 91 COMMAND "${WAYLAND_SCANNER_EXECUTABLE}" private-code "${protocol_path}" ${code_file} 92 DEPENDS "${protocol_path}" 93 VERBATIM) 94 95 target_sources(glfw PRIVATE ${header_file} ${code_file}) 96 endmacro() 97 98 generate_wayland_protocol("wayland.xml") 99 generate_wayland_protocol("viewporter.xml") 100 generate_wayland_protocol("xdg-shell.xml") 101 generate_wayland_protocol("idle-inhibit-unstable-v1.xml") 102 generate_wayland_protocol("pointer-constraints-unstable-v1.xml") 103 generate_wayland_protocol("relative-pointer-unstable-v1.xml") 104 generate_wayland_protocol("fractional-scale-v1.xml") 105 generate_wayland_protocol("xdg-activation-v1.xml") 106 generate_wayland_protocol("xdg-decoration-unstable-v1.xml") 107 endif() 108 109 if (WIN32 AND GLFW_BUILD_SHARED_LIBRARY) 110 configure_file(glfw.rc.in glfw.rc @ONLY) 111 target_sources(glfw PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/glfw.rc") 112 endif() 113 114 if (UNIX AND GLFW_BUILD_SHARED_LIBRARY) 115 # On Unix-like systems, shared libraries can use the soname system. 116 set(GLFW_LIB_NAME glfw) 117 else() 118 set(GLFW_LIB_NAME glfw3) 119 endif() 120 set(GLFW_LIB_NAME_SUFFIX "") 121 122 set_target_properties(glfw PROPERTIES 123 OUTPUT_NAME ${GLFW_LIB_NAME} 124 VERSION ${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR} 125 SOVERSION ${GLFW_VERSION_MAJOR} 126 POSITION_INDEPENDENT_CODE ON 127 C_STANDARD 99 128 C_EXTENSIONS OFF 129 DEFINE_SYMBOL _GLFW_BUILD_DLL 130 FOLDER "GLFW3") 131 132 target_include_directories(glfw PUBLIC 133 "$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>" 134 "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>") 135 target_include_directories(glfw PRIVATE 136 "${GLFW_SOURCE_DIR}/src" 137 "${GLFW_BINARY_DIR}/src") 138 target_link_libraries(glfw PRIVATE Threads::Threads) 139 140 # Workaround for CMake not knowing about .m files before version 3.16 141 if (CMAKE_VERSION VERSION_LESS "3.16" AND APPLE) 142 set_source_files_properties(cocoa_init.m cocoa_joystick.m cocoa_monitor.m 143 cocoa_window.m nsgl_context.m PROPERTIES 144 LANGUAGE C) 145 endif() 146 147 if (GLFW_BUILD_WIN32) 148 list(APPEND glfw_PKG_LIBS "-lgdi32") 149 endif() 150 151 if (GLFW_BUILD_COCOA) 152 target_link_libraries(glfw PRIVATE "-framework Cocoa" 153 "-framework IOKit" 154 "-framework CoreFoundation") 155 156 set(glfw_PKG_DEPS "") 157 set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation") 158 endif() 159 160 if (GLFW_BUILD_WAYLAND) 161 include(FindPkgConfig) 162 163 pkg_check_modules(Wayland REQUIRED 164 wayland-client>=0.2.7 165 wayland-cursor>=0.2.7 166 wayland-egl>=0.2.7 167 xkbcommon>=0.5.0) 168 169 target_include_directories(glfw PRIVATE ${Wayland_INCLUDE_DIRS}) 170 171 if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") 172 find_package(EpollShim) 173 if (EPOLLSHIM_FOUND) 174 target_include_directories(glfw PRIVATE ${EPOLLSHIM_INCLUDE_DIRS}) 175 target_link_libraries(glfw PRIVATE ${EPOLLSHIM_LIBRARIES}) 176 endif() 177 endif() 178 endif() 179 180 if (GLFW_BUILD_X11) 181 find_package(X11 REQUIRED) 182 target_include_directories(glfw PRIVATE "${X11_X11_INCLUDE_PATH}") 183 184 # Check for XRandR (modern resolution switching and gamma control) 185 if (NOT X11_Xrandr_INCLUDE_PATH) 186 message(FATAL_ERROR "RandR headers not found; install libxrandr development package") 187 endif() 188 target_include_directories(glfw PRIVATE "${X11_Xrandr_INCLUDE_PATH}") 189 190 # Check for Xinerama (legacy multi-monitor support) 191 if (NOT X11_Xinerama_INCLUDE_PATH) 192 message(FATAL_ERROR "Xinerama headers not found; install libxinerama development package") 193 endif() 194 target_include_directories(glfw PRIVATE "${X11_Xinerama_INCLUDE_PATH}") 195 196 # Check for Xkb (X keyboard extension) 197 if (NOT X11_Xkb_INCLUDE_PATH) 198 message(FATAL_ERROR "XKB headers not found; install X11 development package") 199 endif() 200 target_include_directories(glfw PRIVATE "${X11_Xkb_INCLUDE_PATH}") 201 202 # Check for Xcursor (cursor creation from RGBA images) 203 if (NOT X11_Xcursor_INCLUDE_PATH) 204 message(FATAL_ERROR "Xcursor headers not found; install libxcursor development package") 205 endif() 206 target_include_directories(glfw PRIVATE "${X11_Xcursor_INCLUDE_PATH}") 207 208 # Check for XInput (modern HID input) 209 if (NOT X11_Xi_INCLUDE_PATH) 210 message(FATAL_ERROR "XInput headers not found; install libxi development package") 211 endif() 212 target_include_directories(glfw PRIVATE "${X11_Xi_INCLUDE_PATH}") 213 214 # Check for X Shape (custom window input shape) 215 if (NOT X11_Xshape_INCLUDE_PATH) 216 message(FATAL_ERROR "X Shape headers not found; install libxext development package") 217 endif() 218 target_include_directories(glfw PRIVATE "${X11_Xshape_INCLUDE_PATH}") 219 endif() 220 221 if (UNIX AND NOT APPLE) 222 find_library(RT_LIBRARY rt) 223 mark_as_advanced(RT_LIBRARY) 224 if (RT_LIBRARY) 225 target_link_libraries(glfw PRIVATE "${RT_LIBRARY}") 226 list(APPEND glfw_PKG_LIBS "-lrt") 227 endif() 228 229 find_library(MATH_LIBRARY m) 230 mark_as_advanced(MATH_LIBRARY) 231 if (MATH_LIBRARY) 232 target_link_libraries(glfw PRIVATE "${MATH_LIBRARY}") 233 list(APPEND glfw_PKG_LIBS "-lm") 234 endif() 235 236 if (CMAKE_DL_LIBS) 237 target_link_libraries(glfw PRIVATE "${CMAKE_DL_LIBS}") 238 list(APPEND glfw_PKG_LIBS "-l${CMAKE_DL_LIBS}") 239 endif() 240 endif() 241 242 if (WIN32) 243 if (GLFW_USE_HYBRID_HPG) 244 target_compile_definitions(glfw PRIVATE _GLFW_USE_HYBRID_HPG) 245 endif() 246 endif() 247 248 # Enable a reasonable set of warnings 249 # NOTE: The order matters here, Clang-CL matches both MSVC and Clang 250 if (MSVC) 251 target_compile_options(glfw PRIVATE "/W3") 252 elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR 253 CMAKE_C_COMPILER_ID STREQUAL "Clang" OR 254 CMAKE_C_COMPILER_ID STREQUAL "AppleClang") 255 256 target_compile_options(glfw PRIVATE "-Wall") 257 endif() 258 259 if (GLFW_BUILD_WIN32) 260 target_compile_definitions(glfw PRIVATE UNICODE _UNICODE) 261 endif() 262 263 # HACK: When building on MinGW, WINVER and UNICODE need to be defined before 264 # the inclusion of stddef.h (by glfw3.h), which is itself included before 265 # win32_platform.h. We define them here until a saner solution can be found 266 # NOTE: MinGW-w64 and Visual C++ do /not/ need this hack. 267 if (MINGW) 268 target_compile_definitions(glfw PRIVATE WINVER=0x0501) 269 endif() 270 271 # Workaround for legacy MinGW not providing XInput and DirectInput 272 if (MINGW) 273 include(CheckIncludeFile) 274 check_include_file(dinput.h DINPUT_H_FOUND) 275 check_include_file(xinput.h XINPUT_H_FOUND) 276 if (NOT DINPUT_H_FOUND OR NOT XINPUT_H_FOUND) 277 target_include_directories(glfw PRIVATE "${GLFW_SOURCE_DIR}/deps/mingw") 278 endif() 279 endif() 280 281 # Workaround for the MS CRT deprecating parts of the standard library 282 if (MSVC OR CMAKE_C_SIMULATE_ID STREQUAL "MSVC") 283 target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS) 284 endif() 285 286 # Workaround for -std=c99 on Linux disabling _DEFAULT_SOURCE (POSIX 2008 and more) 287 if (CMAKE_SYSTEM_NAME STREQUAL "Linux") 288 target_compile_definitions(glfw PRIVATE _DEFAULT_SOURCE) 289 endif() 290 291 if (GLFW_BUILD_SHARED_LIBRARY) 292 if (WIN32) 293 if (MINGW) 294 # Remove the dependency on the shared version of libgcc 295 # NOTE: MinGW-w64 has the correct default but MinGW needs this 296 target_link_libraries(glfw PRIVATE "-static-libgcc") 297 298 # Remove the lib prefix on the DLL (but not the import library) 299 set_target_properties(glfw PROPERTIES PREFIX "") 300 301 # Add a suffix to the import library to avoid naming conflicts 302 set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.a") 303 else() 304 # Add a suffix to the import library to avoid naming conflicts 305 set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib") 306 endif() 307 set (GLFW_LIB_NAME_SUFFIX "dll") 308 309 target_compile_definitions(glfw INTERFACE GLFW_DLL) 310 endif() 311 312 if (MINGW) 313 # Enable link-time exploit mitigation features enabled by default on MSVC 314 include(CheckCCompilerFlag) 315 316 # Compatibility with data execution prevention (DEP) 317 set(CMAKE_REQUIRED_FLAGS "-Wl,--nxcompat") 318 check_c_compiler_flag("" _GLFW_HAS_DEP) 319 if (_GLFW_HAS_DEP) 320 target_link_libraries(glfw PRIVATE "-Wl,--nxcompat") 321 endif() 322 323 # Compatibility with address space layout randomization (ASLR) 324 set(CMAKE_REQUIRED_FLAGS "-Wl,--dynamicbase") 325 check_c_compiler_flag("" _GLFW_HAS_ASLR) 326 if (_GLFW_HAS_ASLR) 327 target_link_libraries(glfw PRIVATE "-Wl,--dynamicbase") 328 endif() 329 330 # Compatibility with 64-bit address space layout randomization (ASLR) 331 set(CMAKE_REQUIRED_FLAGS "-Wl,--high-entropy-va") 332 check_c_compiler_flag("" _GLFW_HAS_64ASLR) 333 if (_GLFW_HAS_64ASLR) 334 target_link_libraries(glfw PRIVATE "-Wl,--high-entropy-va") 335 endif() 336 337 # Clear flags again to avoid breaking later tests 338 set(CMAKE_REQUIRED_FLAGS) 339 endif() 340 341 if (UNIX) 342 # Hide symbols not explicitly tagged for export from the shared library 343 target_compile_options(glfw PRIVATE "-fvisibility=hidden") 344 endif() 345 endif() 346 347 foreach(arg ${glfw_PKG_DEPS}) 348 string(APPEND deps " ${arg}") 349 endforeach() 350 foreach(arg ${glfw_PKG_LIBS}) 351 string(APPEND libs " ${arg}") 352 endforeach() 353 354 set(GLFW_PKG_CONFIG_REQUIRES_PRIVATE "${deps}" CACHE INTERNAL 355 "GLFW pkg-config Requires.private") 356 set(GLFW_PKG_CONFIG_LIBS_PRIVATE "${libs}" CACHE INTERNAL 357 "GLFW pkg-config Libs.private") 358 359 configure_file("${GLFW_SOURCE_DIR}/CMake/glfw3.pc.in" glfw3.pc @ONLY) 360 361 if (GLFW_INSTALL) 362 install(TARGETS glfw 363 EXPORT glfwTargets 364 RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 365 ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" 366 LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") 367 endif() 368