CMakeLists.txt 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. # This project defines a `glad_add_library` function that will create a glad library.
  2. # The created library will automatically generate the glad sources.
  3. # Consumers can link to the the library.
  4. #
  5. # configuration variables:
  6. # GLAD_SOURCES_DIR: path to the sources of glad (=python module)
  7. #
  8. #
  9. # glad_add_library(<TARGET> [SHARED|STATIC|MODULE|INTERFACE] [EXCLUDE_FROM_ALL] [MERGE] [QUIET] [LOCATION <PATH>]
  10. # [LANGUAGE <LANG>] [API <API1> [<API2> ...]] [EXTENSIONS [<EXT1> [<EXT2> ...]]])
  11. # - <TARGET>
  12. # Name of the TARGET
  13. # - SHARED|STATIC|MODULE|INTERFACE
  14. # Type of the library, if none is specified, default BUILD_SHARED_LIBS behavior is honored
  15. # - EXCLUDE_FROM_ALL
  16. # Exclude building the library from the all target
  17. # - MERGE
  18. # Merge multiple APIs of the same specitifation into one file.
  19. # - QUIET
  20. # Disable logging
  21. # - LOCATION <PATH>
  22. # Set the location where the generated glad should be saved.
  23. # - LANGUAGE <LANG>
  24. # Language of the generated glad sources.
  25. # - API <API1> [<API2> ...]]
  26. # Apis to include in the generated glad library.
  27. # - EXTENSIONS [<EXT1> [<EXT2> ...]]
  28. # Extensions to include in the generated glad library. Pass NONE to add no extensions whatsoever.
  29. #
  30. # examples:
  31. # - create a shared glad library of the core profile of opengl 3.3, having all extensions:
  32. # ```
  33. # glad_add_library(glad_gl_core_33 SHARED API gl:core=3.3)
  34. # ```
  35. # - create a module glad library of the compatibility profile of opengl 1.0, having only the GL_EXT_COMPRESSION_s3tc extensionsion
  36. # ```
  37. # glad_add_library(glad_gl_compat_10 MODULE API gl:compatibility=1.0 EXTENSIONS GL_EXT_COMPRESSION_s3tc)
  38. # ```
  39. # - create a static glad library with the vulkan=1.1
  40. cmake_minimum_required(VERSION 3.2)
  41. project(glad C)
  42. find_package(PythonInterp REQUIRED)
  43. set(GLAD_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE STRING "Directory containing glad generator CMakeLists.txt")
  44. set(GLAD_SOURCES_DIR "${GLAD_CMAKE_DIR}/../" CACHE STRING "Directory containing glad sources (python modules), used as working directory")
  45. mark_as_advanced(GLAD_CMAKE_DIR)
  46. # Extract specification, profile and version from a string
  47. # examples:
  48. # gl:core=3.3 => SPEC=gl PROFILE=core VERSION=3.3
  49. # gl:compatibility=4.0 => SPEC=gl PROFILE=compatibility VERSION=4.0
  50. # vulkan=1.1 => SPEC=vulkan PROFILE="" VERSION=1.1
  51. function(__glad_extract_spec_profile_version SPEC PROFILE VERSION STRING)
  52. string(REPLACE "=" ";" SPEC_PROFILE_VERSION_LIST "${STRING}")
  53. list(LENGTH SPEC_PROFILE_VERSION_LIST SPV_LENGTH)
  54. if(SPV_LENGTH LESS 2)
  55. message(FATAL_ERROR "${SPEC} is an invalid SPEC")
  56. endif()
  57. list(GET SPEC_PROFILE_VERSION_LIST 0 SPEC_PROFILE_STR)
  58. list(GET SPEC_PROFILE_VERSION_LIST 1 VERSION_STR)
  59. string(REPLACE ":" ";" SPEC_PROFILE_LIST "${SPEC_PROFILE_STR}")
  60. list(LENGTH SPEC_PROFILE_LIST SP_LENGTH)
  61. if(SP_LENGTH LESS 2)
  62. list(GET SPEC_PROFILE_LIST 0 SPEC_STR)
  63. set(PROFILE_STR "")
  64. else()
  65. list(GET SPEC_PROFILE_LIST 0 SPEC_STR)
  66. list(GET SPEC_PROFILE_LIST 1 PROFILE_STR)
  67. endif()
  68. set("${SPEC}" "${SPEC_STR}" PARENT_SCOPE)
  69. set("${PROFILE}" "${PROFILE_STR}" PARENT_SCOPE)
  70. set("${VERSION}" "${VERSION_STR}" PARENT_SCOPE)
  71. endfunction()
  72. # Calculate the argument and generated files for the "c" subparser for glad
  73. function(__glad_c_library CARGS CFILES)
  74. cmake_parse_arguments(GGC "ALIAS;DEBUG;HEADERONLY;LOADER;MX;MXGLOBAL;ON_DEMAND" "" "API" ${ARGN})
  75. if(NOT GGC_API)
  76. message(FATAL_ERROR "Need API")
  77. endif()
  78. set(GGC_FILES "")
  79. foreach(API ${GGC_API})
  80. __glad_extract_spec_profile_version(SPEC PROFILE VERSION "${API}")
  81. if(SPEC STREQUAL "egl")
  82. list(APPEND GGC_FILES
  83. "${GLAD_DIR}/include/EGL/eglplatform.h"
  84. "${GLAD_DIR}/include/KHR/khrplatform.h"
  85. "${GLAD_DIR}/include/glad/egl.h"
  86. "${GLAD_DIR}/src/egl.c"
  87. )
  88. elseif(SPEC STREQUAL "vulkan")
  89. list(APPEND GGC_FILES
  90. "${GLAD_DIR}/include/vk_platform.h"
  91. "${GLAD_DIR}/include/glad/vulkan.h"
  92. "${GLAD_DIR}/src/vulkan.c"
  93. )
  94. elseif(SPEC STREQUAL "gl")
  95. list(APPEND GGC_FILES
  96. "${GLAD_DIR}/include/KHR/khrplatform.h"
  97. "${GLAD_DIR}/include/glad/gl.h"
  98. "${GLAD_DIR}/src/gl.c"
  99. )
  100. elseif(SPEC STREQUAL "gles1")
  101. list(APPEND GGC_FILES
  102. "${GLAD_DIR}/include/KHR/khrplatform.h"
  103. "${GLAD_DIR}/include/glad/gles1.h"
  104. "${GLAD_DIR}/src/gles1.c"
  105. )
  106. elseif(SPEC STREQUAL "gles2")
  107. list(APPEND GGC_FILES
  108. "${GLAD_DIR}/include/KHR/khrplatform.h"
  109. "${GLAD_DIR}/include/glad/gles2.h"
  110. "${GLAD_DIR}/src/gles2.c"
  111. )
  112. elseif(SPEC STREQUAL "glsc2")
  113. list(APPEND GGC_FILES
  114. "${GLAD_DIR}/include/KHR/khrplatform.h"
  115. "${GLAD_DIR}/include/glad/glsc2.h"
  116. "${GLAD_DIR}/src/glsc2.c"
  117. )
  118. elseif(SPEC STREQUAL "wgl")
  119. list(APPEND GGC_FILES
  120. "${GLAD_DIR}/include/glad/wgl.h"
  121. "${GLAD_DIR}/src/wgl.c"
  122. )
  123. elseif(SPEC STREQUAL "glx")
  124. list(APPEND GGC_FILES
  125. "${GLAD_DIR}/include/glad/glx.h"
  126. "${GLAD_DIR}/src/glx.c"
  127. )
  128. else()
  129. message(FATAL_ERROR "Unknown SPEC: '${SPEC}'")
  130. endif()
  131. endforeach()
  132. set(GGC_ARGS "")
  133. if(GGC_ALIAS)
  134. list(APPEND GGC_ARGS "--alias")
  135. endif()
  136. if(GGC_DEBUG)
  137. list(APPEND GGC_ARGS "--debug")
  138. endif()
  139. if(GGC_HEADERONLY)
  140. list(APPEND GGC_ARGS "--header-only")
  141. endif()
  142. if(GGC_LOADER)
  143. list(APPEND GGC_ARGS "--loader")
  144. endif()
  145. if(GGC_MX)
  146. list(APPEND GGC_ARGS "--mx")
  147. endif()
  148. if(GGC_MXGLOBAL)
  149. list(APPEND GGC_ARGS "--mx-global")
  150. endif()
  151. if(GGC_ON_DEMAND)
  152. list(APPEND GGC_ARGS "--on-demand")
  153. endif()
  154. set("${CARGS}" "${GGC_ARGS}" PARENT_SCOPE)
  155. set("${CFILES}" "${GGC_FILES}" PARENT_SCOPE)
  156. endfunction()
  157. # Create a glad library named "${TARGET}"
  158. function(glad_add_library TARGET)
  159. message(STATUS "Glad Library \'${TARGET}\'")
  160. cmake_parse_arguments(GG "MERGE;QUIET;REPRODUCIBLE;STATIC;SHARED;MODULE;INTERFACE;EXCLUDE_FROM_ALL" "LOCATION;LANGUAGE" "API;EXTENSIONS" ${ARGN})
  161. if(NOT GG_LOCATION)
  162. set(GG_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/gladsources/${TARGET}")
  163. endif()
  164. set(GLAD_DIR "${GG_LOCATION}")
  165. if(NOT IS_DIRECTORY "${GLAD_DIR}")
  166. file(MAKE_DIRECTORY "${GLAD_DIRECTORY}")
  167. endif()
  168. set(GLAD_ARGS --out-path "${GLAD_DIR}")
  169. if(NOT GG_API)
  170. message(FATAL_ERROR "Need API")
  171. endif()
  172. string(REPLACE ";" "," GLAD_API "${GG_API}")
  173. list(APPEND GLAD_ARGS --api "${GLAD_API}")
  174. if(GG_EXTENSIONS)
  175. list(FIND GG_EXTENSIONS NONE GG_EXT_NONE)
  176. if(GG_EXT_NONE GREATER -1)
  177. set(GLAD_EXTENSIONS " ")
  178. else()
  179. list(REMOVE_DUPLICATES GG_EXTENSIONS)
  180. list(JOIN GG_EXTENSIONS "," GLAD_EXTENSIONS)
  181. endif()
  182. list(APPEND GLAD_ARGS --extensions "${GLAD_EXTENSIONS}")
  183. endif()
  184. if(GG_QUIET)
  185. list(APPEND GLAD_ARGS --quiet)
  186. endif()
  187. if(GG_MERGE)
  188. list(APPEND GLAD_ARGS --merge)
  189. endif()
  190. if(GG_REPRODUCIBLE)
  191. list(APPEND GLAD_ARGS --reproducible)
  192. endif()
  193. set(GLAD_LANGUAGE "c")
  194. if(GG_LANGUAGE)
  195. string(TOLOWER "${GG_LANGUAGE}" "${GLAD_LANGUAGE}")
  196. endif()
  197. if(GLAD_LANGUAGE STREQUAL "c")
  198. __glad_c_library(LANG_ARGS GLAD_FILES ${GG_UNPARSED_ARGUMENTS} API ${GG_API})
  199. else()
  200. message(FATAL_ERROR "Unknown LANGUAGE")
  201. endif()
  202. list(APPEND GLAD_ARGS ${GLAD_LANGUAGE} ${LANG_ARGS})
  203. string(REPLACE "${GLAD_DIR}" GLAD_DIRECTORY GLAD_ARGS_UNIVERSAL "${GLAD_ARGS}")
  204. set(GLAD_ARGS_PATH "${GLAD_DIR}/args.txt")
  205. # add make custom target
  206. add_custom_command(
  207. OUTPUT ${GLAD_FILES} ${GLAD_ARGS_PATH}
  208. COMMAND echo Cleaning ${GLAD_DIR}
  209. COMMAND ${CMAKE_COMMAND} -E remove_directory ${GLAD_DIR}
  210. COMMAND ${CMAKE_COMMAND} -E make_directory ${GLAD_DIR}
  211. COMMAND echo Generating with args ${GLAD_ARGS}
  212. COMMAND ${PYTHON_EXECUTABLE} -m glad ${GLAD_ARGS}
  213. COMMAND echo Writing ${GLAD_ARGS_PATH}
  214. COMMAND echo ${GLAD_ARGS} > ${GLAD_ARGS_PATH}
  215. WORKING_DIRECTORY ${GLAD_SOURCES_DIR}
  216. COMMENT "${TARGET}-generate"
  217. USES_TERMINAL
  218. )
  219. set(GLAD_ADD_LIBRARY_ARGS "")
  220. if(GG_SHARED)
  221. list(APPEND GLAD_ADD_LIBRARY_ARGS SHARED)
  222. elseif(GG_STATIC)
  223. list(APPEND GLAD_ADD_LIBRARY_ARGS STATIC)
  224. elseif(GG_MODULE)
  225. list(APPEND GLAD_ADD_LIBRARY_ARGS MODULE)
  226. elseif(GG_INTERFACE)
  227. list(APPEND GLAD_ADD_LIBRARY_ARGS INTERFACE)
  228. endif()
  229. if(GG_EXCLUDE_FROM_ALL)
  230. list(APPEND GLAD_ADD_LIBRARY_ARGS EXCLUDE_FROM_ALL)
  231. endif()
  232. add_library("${TARGET}" ${GLAD_ADD_LIBRARY_ARGS}
  233. ${GLAD_FILES}
  234. )
  235. target_include_directories("${TARGET}"
  236. PUBLIC
  237. "${GLAD_DIR}/include"
  238. )
  239. target_link_libraries("${TARGET}"
  240. PUBLIC
  241. ${CMAKE_DL_LIBS}
  242. )
  243. if(GG_SHARED)
  244. target_compile_definitions("${TARGET}" PUBLIC GLAD_API_CALL_EXPORT)
  245. set_target_properties("${TARGET}"
  246. PROPERTIES
  247. DEFINE_SYMBOL "GLAD_API_CALL_EXPORT_BUILD"
  248. )
  249. endif()
  250. endfunction()