CMakeLists.txt 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. cmake_minimum_required(VERSION 2.8.12)
  2. project(GLFW C)
  3. set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
  4. if (NOT CMAKE_VERSION VERSION_LESS "3.0")
  5. # Until all major package systems have moved to CMake 3,
  6. # we stick with the older INSTALL_NAME_DIR mechanism
  7. cmake_policy(SET CMP0042 OLD)
  8. endif()
  9. if (NOT CMAKE_VERSION VERSION_LESS "3.1")
  10. cmake_policy(SET CMP0054 NEW)
  11. endif()
  12. set(GLFW_VERSION_MAJOR "3")
  13. set(GLFW_VERSION_MINOR "3")
  14. set(GLFW_VERSION_PATCH "0")
  15. set(GLFW_VERSION_EXTRA "")
  16. set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}")
  17. set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA}")
  18. set(LIB_SUFFIX "" CACHE STRING "Takes an empty string or 64. Directory where lib will be installed: lib or lib64")
  19. set_property(GLOBAL PROPERTY USE_FOLDERS ON)
  20. option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
  21. option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ON)
  22. option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON)
  23. option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON)
  24. option(GLFW_INSTALL "Generate installation target" ON)
  25. option(GLFW_VULKAN_STATIC "Use the Vulkan loader statically linked into application" OFF)
  26. option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF)
  27. if (UNIX)
  28. option(GLFW_USE_OSMESA "Use OSMesa for offscreen context creation" OFF)
  29. endif()
  30. if (WIN32)
  31. option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF)
  32. endif()
  33. if (UNIX AND NOT APPLE)
  34. option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF)
  35. option(GLFW_USE_MIR "Use Mir for window creation" OFF)
  36. endif()
  37. if (MSVC)
  38. option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON)
  39. endif()
  40. if (BUILD_SHARED_LIBS)
  41. set(_GLFW_BUILD_DLL 1)
  42. endif()
  43. if (BUILD_SHARED_LIBS AND UNIX)
  44. # On Unix-like systems, shared libraries can use the soname system.
  45. set(GLFW_LIB_NAME glfw)
  46. else()
  47. set(GLFW_LIB_NAME glfw3)
  48. endif()
  49. if (GLFW_VULKAN_STATIC)
  50. set(_GLFW_VULKAN_STATIC 1)
  51. endif()
  52. list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
  53. find_package(Threads REQUIRED)
  54. find_package(Vulkan)
  55. if (GLFW_BUILD_DOCS)
  56. set(DOXYGEN_SKIP_DOT TRUE)
  57. find_package(Doxygen)
  58. endif()
  59. #--------------------------------------------------------------------
  60. # Set compiler specific flags
  61. #--------------------------------------------------------------------
  62. if (MSVC)
  63. if (MSVC90)
  64. # Workaround for VS 2008 not shipping with the DirectX 9 SDK
  65. include(CheckIncludeFile)
  66. check_include_file(dinput.h DINPUT_H_FOUND)
  67. if (NOT DINPUT_H_FOUND)
  68. message(FATAL_ERROR "DirectX 9 SDK not found")
  69. endif()
  70. # Workaround for VS 2008 not shipping with stdint.h
  71. list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/vs2008")
  72. endif()
  73. if (NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
  74. foreach (flag CMAKE_C_FLAGS
  75. CMAKE_C_FLAGS_DEBUG
  76. CMAKE_C_FLAGS_RELEASE
  77. CMAKE_C_FLAGS_MINSIZEREL
  78. CMAKE_C_FLAGS_RELWITHDEBINFO)
  79. if (${flag} MATCHES "/MD")
  80. string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
  81. endif()
  82. if (${flag} MATCHES "/MDd")
  83. string(REGEX REPLACE "/MDd" "/MTd" ${flag} "${${flag}}")
  84. endif()
  85. endforeach()
  86. endif()
  87. endif()
  88. if (MINGW)
  89. # Workaround for legacy MinGW not providing XInput and DirectInput
  90. include(CheckIncludeFile)
  91. check_include_file(dinput.h DINPUT_H_FOUND)
  92. check_include_file(xinput.h XINPUT_H_FOUND)
  93. if (NOT DINPUT_H_FOUND OR NOT XINPUT_H_FOUND)
  94. list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/mingw")
  95. endif()
  96. # Enable link-time exploit mitigation features enabled by default on MSVC
  97. include(CheckCCompilerFlag)
  98. # Compatibility with data execution prevention (DEP)
  99. set(CMAKE_REQUIRED_FLAGS "-Wl,--nxcompat")
  100. check_c_compiler_flag("" _GLFW_HAS_DEP)
  101. if (_GLFW_HAS_DEP)
  102. set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--nxcompat ${CMAKE_SHARED_LINKER_FLAGS}")
  103. endif()
  104. # Compatibility with address space layout randomization (ASLR)
  105. set(CMAKE_REQUIRED_FLAGS "-Wl,--dynamicbase")
  106. check_c_compiler_flag("" _GLFW_HAS_ASLR)
  107. if (_GLFW_HAS_ASLR)
  108. set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--dynamicbase ${CMAKE_SHARED_LINKER_FLAGS}")
  109. endif()
  110. # Compatibility with 64-bit address space layout randomization (ASLR)
  111. set(CMAKE_REQUIRED_FLAGS "-Wl,--high-entropy-va")
  112. check_c_compiler_flag("" _GLFW_HAS_64ASLR)
  113. if (_GLFW_HAS_64ASLR)
  114. set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--high-entropy-va ${CMAKE_SHARED_LINKER_FLAGS}")
  115. endif()
  116. endif()
  117. if (APPLE)
  118. # Dependencies required by the MoltenVK static library
  119. set(GLFW_VULKAN_DEPS
  120. "-lc++"
  121. "-framework Cocoa"
  122. "-framework Metal"
  123. "-framework QuartzCore")
  124. endif()
  125. #--------------------------------------------------------------------
  126. # Detect and select backend APIs
  127. #--------------------------------------------------------------------
  128. if (GLFW_USE_WAYLAND)
  129. set(_GLFW_WAYLAND 1)
  130. message(STATUS "Using Wayland for window creation")
  131. elseif (GLFW_USE_MIR)
  132. set(_GLFW_MIR 1)
  133. message(STATUS "Using Mir for window creation")
  134. elseif (GLFW_USE_OSMESA)
  135. set(_GLFW_OSMESA 1)
  136. message(STATUS "Using OSMesa for headless context creation")
  137. elseif (WIN32)
  138. set(_GLFW_WIN32 1)
  139. message(STATUS "Using Win32 for window creation")
  140. elseif (APPLE)
  141. set(_GLFW_COCOA 1)
  142. message(STATUS "Using Cocoa for window creation")
  143. elseif (UNIX)
  144. set(_GLFW_X11 1)
  145. message(STATUS "Using X11 for window creation")
  146. else()
  147. message(FATAL_ERROR "No supported platform was detected")
  148. endif()
  149. #--------------------------------------------------------------------
  150. # Add Vulkan static library if requested
  151. #--------------------------------------------------------------------
  152. if (GLFW_VULKAN_STATIC)
  153. if (VULKAN_FOUND AND VULKAN_STATIC_LIBRARY)
  154. list(APPEND glfw_LIBRARIES "${VULKAN_STATIC_LIBRARY}" ${GLFW_VULKAN_DEPS})
  155. if (BUILD_SHARED_LIBS)
  156. message(WARNING "Linking Vulkan loader static library into GLFW")
  157. endif()
  158. else()
  159. if (BUILD_SHARED_LIBS OR GLFW_BUILD_EXAMPLES OR GLFW_BUILD_TESTS)
  160. message(FATAL_ERROR "Vulkan loader static library not found")
  161. else()
  162. message(WARNING "Vulkan loader static library not found")
  163. endif()
  164. endif()
  165. endif()
  166. #--------------------------------------------------------------------
  167. # Find and add Unix math and time libraries
  168. #--------------------------------------------------------------------
  169. if (UNIX AND NOT APPLE)
  170. find_library(RT_LIBRARY rt)
  171. mark_as_advanced(RT_LIBRARY)
  172. if (RT_LIBRARY)
  173. list(APPEND glfw_LIBRARIES "${RT_LIBRARY}")
  174. list(APPEND glfw_PKG_LIBS "-lrt")
  175. endif()
  176. find_library(MATH_LIBRARY m)
  177. mark_as_advanced(MATH_LIBRARY)
  178. if (MATH_LIBRARY)
  179. list(APPEND glfw_LIBRARIES "${MATH_LIBRARY}")
  180. list(APPEND glfw_PKG_LIBS "-lm")
  181. endif()
  182. if (CMAKE_DL_LIBS)
  183. list(APPEND glfw_LIBRARIES "${CMAKE_DL_LIBS}")
  184. list(APPEND glfw_PKG_LIBS "-l${CMAKE_DL_LIBS}")
  185. endif()
  186. endif()
  187. #--------------------------------------------------------------------
  188. # Use Win32 for window creation
  189. #--------------------------------------------------------------------
  190. if (_GLFW_WIN32)
  191. list(APPEND glfw_PKG_LIBS "-lgdi32")
  192. if (GLFW_USE_HYBRID_HPG)
  193. set(_GLFW_USE_HYBRID_HPG 1)
  194. endif()
  195. endif()
  196. #--------------------------------------------------------------------
  197. # Use X11 for window creation
  198. #--------------------------------------------------------------------
  199. if (_GLFW_X11)
  200. find_package(X11 REQUIRED)
  201. list(APPEND glfw_PKG_DEPS "x11")
  202. # Set up library and include paths
  203. list(APPEND glfw_INCLUDE_DIRS "${X11_X11_INCLUDE_PATH}")
  204. list(APPEND glfw_LIBRARIES "${X11_X11_LIB}" "${CMAKE_THREAD_LIBS_INIT}")
  205. # Check for XRandR (modern resolution switching and gamma control)
  206. if (NOT X11_Xrandr_FOUND)
  207. message(FATAL_ERROR "The RandR headers were not found")
  208. endif()
  209. # Check for Xinerama (legacy multi-monitor support)
  210. if (NOT X11_Xinerama_FOUND)
  211. message(FATAL_ERROR "The Xinerama headers were not found")
  212. endif()
  213. # Check for Xkb (X keyboard extension)
  214. if (NOT X11_Xkb_FOUND)
  215. message(FATAL_ERROR "The X keyboard extension headers were not found")
  216. endif()
  217. # Check for Xcursor (cursor creation from RGBA images)
  218. if (NOT X11_Xcursor_FOUND)
  219. message(FATAL_ERROR "The Xcursor headers were not found")
  220. endif()
  221. list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}"
  222. "${X11_Xinerama_INCLUDE_PATH}"
  223. "${X11_Xkb_INCLUDE_PATH}"
  224. "${X11_Xcursor_INCLUDE_PATH}")
  225. endif()
  226. #--------------------------------------------------------------------
  227. # Use Wayland for window creation
  228. #--------------------------------------------------------------------
  229. if (_GLFW_WAYLAND)
  230. find_package(ECM REQUIRED NO_MODULE)
  231. list(APPEND CMAKE_MODULE_PATH "${ECM_MODULE_PATH}")
  232. find_package(Wayland REQUIRED Client Cursor Egl)
  233. find_package(WaylandScanner REQUIRED)
  234. find_package(WaylandProtocols 1.1 REQUIRED)
  235. list(APPEND glfw_PKG_DEPS "wayland-egl")
  236. list(APPEND glfw_INCLUDE_DIRS "${Wayland_INCLUDE_DIRS}")
  237. list(APPEND glfw_LIBRARIES "${Wayland_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}")
  238. find_package(XKBCommon REQUIRED)
  239. list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}")
  240. include(CheckIncludeFiles)
  241. check_include_files(xkbcommon/xkbcommon-compose.h HAVE_XKBCOMMON_COMPOSE_H)
  242. endif()
  243. #--------------------------------------------------------------------
  244. # Use Mir for window creation
  245. #--------------------------------------------------------------------
  246. if (_GLFW_MIR)
  247. find_package(Mir REQUIRED)
  248. list(APPEND glfw_PKG_DEPS "mirclient")
  249. list(APPEND glfw_INCLUDE_DIRS "${MIR_INCLUDE_DIRS}")
  250. list(APPEND glfw_LIBRARIES "${MIR_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}")
  251. find_package(XKBCommon REQUIRED)
  252. list(APPEND glfw_PKG_DEPS "xkbcommon")
  253. list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}")
  254. list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}")
  255. endif()
  256. #--------------------------------------------------------------------
  257. # Use OSMesa for offscreen context creation
  258. #--------------------------------------------------------------------
  259. if (_GLFW_OSMESA)
  260. find_package(OSMesa REQUIRED)
  261. list(APPEND glfw_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
  262. endif()
  263. #--------------------------------------------------------------------
  264. # Use Cocoa for window creation and NSOpenGL for context creation
  265. #--------------------------------------------------------------------
  266. if (_GLFW_COCOA)
  267. list(APPEND glfw_LIBRARIES
  268. "-framework Cocoa"
  269. "-framework IOKit"
  270. "-framework CoreFoundation"
  271. "-framework CoreVideo")
  272. set(glfw_PKG_DEPS "")
  273. set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo")
  274. endif()
  275. #--------------------------------------------------------------------
  276. # Export GLFW library dependencies
  277. #--------------------------------------------------------------------
  278. foreach(arg ${glfw_PKG_DEPS})
  279. set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} ${arg}")
  280. endforeach()
  281. foreach(arg ${glfw_PKG_LIBS})
  282. set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} ${arg}")
  283. endforeach()
  284. #--------------------------------------------------------------------
  285. # Create generated files
  286. #--------------------------------------------------------------------
  287. include(CMakePackageConfigHelpers)
  288. set(GLFW_CONFIG_PATH "lib${LIB_SUFFIX}/cmake/glfw3")
  289. configure_package_config_file(src/glfw3Config.cmake.in
  290. src/glfw3Config.cmake
  291. INSTALL_DESTINATION "${GLFW_CONFIG_PATH}"
  292. NO_CHECK_REQUIRED_COMPONENTS_MACRO)
  293. write_basic_package_version_file(src/glfw3ConfigVersion.cmake
  294. VERSION ${GLFW_VERSION_FULL}
  295. COMPATIBILITY SameMajorVersion)
  296. configure_file(src/glfw_config.h.in src/glfw_config.h @ONLY)
  297. configure_file(src/glfw3.pc.in src/glfw3.pc @ONLY)
  298. #--------------------------------------------------------------------
  299. # Add subdirectories
  300. #--------------------------------------------------------------------
  301. add_subdirectory(src)
  302. if (GLFW_BUILD_EXAMPLES)
  303. add_subdirectory(examples)
  304. endif()
  305. if (GLFW_BUILD_TESTS)
  306. add_subdirectory(tests)
  307. endif()
  308. if (DOXYGEN_FOUND AND GLFW_BUILD_DOCS)
  309. add_subdirectory(docs)
  310. endif()
  311. #--------------------------------------------------------------------
  312. # Install files other than the library
  313. # The library is installed by src/CMakeLists.txt
  314. #--------------------------------------------------------------------
  315. if (GLFW_INSTALL)
  316. install(DIRECTORY include/GLFW DESTINATION include
  317. FILES_MATCHING PATTERN glfw3.h PATTERN glfw3native.h)
  318. install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake"
  319. "${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake"
  320. DESTINATION "${GLFW_CONFIG_PATH}")
  321. install(EXPORT glfwTargets FILE glfw3Targets.cmake
  322. EXPORT_LINK_INTERFACE_LIBRARIES
  323. DESTINATION "${GLFW_CONFIG_PATH}")
  324. install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc"
  325. DESTINATION "lib${LIB_SUFFIX}/pkgconfig")
  326. # Only generate this target if no higher-level project already has
  327. if (NOT TARGET uninstall)
  328. configure_file(cmake_uninstall.cmake.in
  329. cmake_uninstall.cmake IMMEDIATE @ONLY)
  330. add_custom_target(uninstall
  331. "${CMAKE_COMMAND}" -P
  332. "${GLFW_BINARY_DIR}/cmake_uninstall.cmake")
  333. set_target_properties(uninstall PROPERTIES FOLDER "GLFW3")
  334. endif()
  335. endif()