Last active
August 10, 2018 20:00
-
-
Save madebr/eee83071f75d21356c7dabe019d86d89 to your computer and use it in GitHub Desktop.
glad cmake
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 3.8) | |
project(project) | |
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}") | |
include(GladLoaderGenerator) | |
set(egl_VERSIONS 1.0 1.1 1.2 1.3 1.4 1.5) | |
set(gl_VERSIONS 1.0 1.1 1.2 1.3 1.4 1.5 2.0 2.1 3.0 3.1 3.2 3.3 4.0 4.1 4.2 4.3 4.4 4.5 4.6) | |
set(gles1_VERSIONS 1.0) | |
set(gles2_VERSIONS 2.0 3.0 3.1 3.2) | |
set(glsc2_VERSIONS 2.0) | |
set(glx_VERSIONS 1.0 1.1 1.2 1.3 1.4) | |
set(vulkan_VERSIONS 1.0 1.1) | |
set(wgl_VERSIONS 1.0) | |
set(gl_PROFILES core compatibility) | |
set(APIS egl gl gles1 gles2 glsc2 glx vulkan wgl) | |
macro(merge_version RESULT VERSION) | |
string(REPLACE "." "" "${RESULT}" "${VERSION}") | |
endmacro() | |
foreach(API ${APIS}) | |
set(PROFILES "${${API}_PROFILES}") | |
if(NOT PROFILES) | |
set(PROFILES "X") | |
endif() | |
foreach(PROFILE ${PROFILES}) | |
if(PROFILE STREQUAL "X") | |
set(PROFILE "") | |
endif() | |
foreach(VERSION ${${API}_VERSIONS}) | |
set(APISTR "${API}") | |
string(REPLACE "." "" NAME_SUFFIX "${VERSION}") | |
if(PROFILE) | |
string(APPEND APISTR ":${PROFILE}") | |
string(APPEND NAME_SUFFIX "_${PROFILE}") | |
endif() | |
glad_add_library(glad_${API}_${NAME_SUFFIX} EXCLUDE_FROM_ALL | |
LOCATION "${PROJECT_SOURCE_DIR}/external/glad_${API}_${NAME_SUFFIX}" | |
API ${APISTR}=${VERSION} | |
) | |
endforeach() | |
endforeach() | |
endforeach() | |
foreach(glx_VERSION ${glx_VERSIONS}) | |
string(REPLACE "." "" NAME_SUFFIX "${glx_VERSION}") | |
target_link_libraries(glad_glx_${NAME_SUFFIX} | |
PUBLIC | |
glad_gl_10_core | |
) | |
endforeach() | |
foreach(wgl_VERSION ${wgl_VERSIONS}) | |
string(REPLACE "." "" NAME_SUFFIX "${wgl_VERSION}") | |
target_link_libraries(glad_wgl_${NAME_SUFFIX} | |
PUBLIC | |
glad_gl_10_core | |
) | |
endforeach() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
find_program(GLAD_BIN | |
NAMES glad | |
HINTS | |
"$ENV{HOME}/.local/bin" | |
) | |
if(NOT GLAD_BIN) | |
message(FATAL_ERROR "Cannot find glad program.") | |
endif() | |
# Extract specification, profile and version from a string | |
# examples: | |
# gl:core=3.3 => SPEC=gl PROFILE=core VERSION=3.3 | |
# gl:compatibility=4.0 => SPEC=gl PROFILE=compatibility VERSION=4.0 | |
# vulkan=1.1 => SPEC=vulkan PROFILE="" VERSION=1.1 | |
function(__glad_extract_spec_profile_version SPEC PROFILE VERSION STRING) | |
string(REPLACE "=" ";" SPEC_PROFILE_VERSION_LIST "${STRING}") | |
list(LENGTH SPEC_PROFILE_VERSION_LIST SPV_LENGTH) | |
if(SPV_LENGTH LESS 2) | |
message(FATAL_ERROR "${SPEC} is an invalid SPEC") | |
endif() | |
list(GET SPEC_PROFILE_VERSION_LIST 0 SPEC_PROFILE_STR) | |
list(GET SPEC_PROFILE_VERSION_LIST 1 VERSION_STR) | |
string(REPLACE ":" ";" SPEC_PROFILE_LIST "${SPEC_PROFILE_STR}") | |
list(LENGTH SPEC_PROFILE_LIST SP_LENGTH) | |
if(SP_LENGTH LESS 2) | |
list(GET SPEC_PROFILE_LIST 0 SPEC_STR) | |
set(PROFILE_STR "") | |
else() | |
list(GET SPEC_PROFILE_LIST 0 SPEC_STR) | |
list(GET SPEC_PROFILE_LIST 1 PROFILE_STR) | |
endif() | |
set("${SPEC}" "${SPEC_STR}" PARENT_SCOPE) | |
set("${PROFILE}" "${PROFILE_STR}" PARENT_SCOPE) | |
set("${VERSION}" "${VERSION_STR}" PARENT_SCOPE) | |
endfunction() | |
# Calculate the argument and generated files for the "c" subparser for glad | |
function(__glad_c_library CARGS CFILES) | |
cmake_parse_arguments(GGC "ALIAS;DEBUG;HEADERONLY;LOADER;MX;MXGLOBAL" "" "API" ${ARGN}) | |
if(NOT GGC_API) | |
message(FATAL_ERROR "Need API") | |
endif() | |
set(GGC_FILES "") | |
foreach(API ${GGC_API}) | |
__glad_extract_spec_profile_version(SPEC PROFILE VERSION "${API}") | |
if(SPEC STREQUAL "egl") | |
list(APPEND GGC_FILES | |
"${GLAD_DIR}/include/EGL/eglplatform.h" | |
"${GLAD_DIR}/include/KHR/khrplatform.h" | |
"${GLAD_DIR}/include/glad/egl.h" | |
"${GLAD_DIR}/src/egl.c" | |
) | |
elseif(SPEC STREQUAL "vulkan") | |
list(APPEND GGC_FILES | |
"${GLAD_DIR}/include/vk_platform.h" | |
"${GLAD_DIR}/include/glad/vulkan.h" | |
"${GLAD_DIR}/src/vulkan.c" | |
) | |
elseif(SPEC STREQUAL "gl") | |
list(APPEND GGC_FILES | |
"${GLAD_DIR}/include/KHR/khrplatform.h" | |
"${GLAD_DIR}/include/glad/gl.h" | |
"${GLAD_DIR}/src/gl.c" | |
) | |
elseif(SPEC STREQUAL "gles1") | |
list(APPEND GGC_FILES | |
"${GLAD_DIR}/include/KHR/khrplatform.h" | |
"${GLAD_DIR}/include/glad/gles1.h" | |
"${GLAD_DIR}/src/gles1.c" | |
) | |
elseif(SPEC STREQUAL "gles2") | |
list(APPEND GGC_FILES | |
"${GLAD_DIR}/include/KHR/khrplatform.h" | |
"${GLAD_DIR}/include/glad/gles2.h" | |
"${GLAD_DIR}/src/gles2.c" | |
) | |
elseif(SPEC STREQUAL "gles3") | |
list(APPEND GGC_FILES | |
"${GLAD_DIR}/include/KHR/khrplatform.h" | |
"${GLAD_DIR}/include/glad/gles3.h" | |
"${GLAD_DIR}/src/gles3.c" | |
) | |
elseif(SPEC STREQUAL "glsc2") | |
list(APPEND GGC_FILES | |
"${GLAD_DIR}/include/KHR/khrplatform.h" | |
"${GLAD_DIR}/include/glad/glsc2.h" | |
"${GLAD_DIR}/src/glsc2.c" | |
) | |
elseif(SPEC STREQUAL "wgl") | |
list(APPEND GGC_FILES | |
"${GLAD_DIR}/include/glad/wgl.h" | |
"${GLAD_DIR}/src/wgl.c" | |
) | |
elseif(SPEC STREQUAL "glx") | |
list(APPEND GGC_FILES | |
"${GLAD_DIR}/include/glad/glx.h" | |
"${GLAD_DIR}/src/glx.c" | |
) | |
else() | |
message(FATAL_ERROR "Unknown SPEC: '${SPEC}'") | |
endif() | |
endforeach() | |
set(GGC_ARGS "") | |
if(GGC_ALIAS) | |
list(APPEND GGC_ARGS "--alias") | |
endif() | |
if(GGC_DEBUG) | |
list(APPEND GGC_ARGS "--debug") | |
endif() | |
if(GGC_HEADERONLY) | |
list(APPEND GGC_ARGS "--header-only") | |
endif() | |
if(GGC_LOADER) | |
list(APPEND GGC_ARGS "--loader") | |
endif() | |
if(GGC_MX) | |
list(APPEND GGC_ARGS "--mx") | |
endif() | |
if(GGC_MXGLOBAL) | |
list(APPEND GGC_ARGS "--mx-global") | |
endif() | |
set("${CARGS}" "${GGC_ARGS}" PARENT_SCOPE) | |
set("${CFILES}" "${GGC_FILES}" PARENT_SCOPE) | |
endfunction() | |
# Create a glad library named "${TARGET}" | |
function(glad_add_library TARGET) | |
cmake_parse_arguments(GG "MERGE;QUIET;EXCLUDE_FROM_ALL" "LOCATION;LANGUAGE" "API;EXTENSIONS" ${ARGN}) | |
if(NOT GG_LOCATION) | |
message(FATAL_ERROR "Need LOCATION") | |
endif() | |
set(GLAD_DIR "${GG_LOCATION}") | |
if(NOT IS_DIRECTORY "${GLAD_DIR}") | |
file(MAKE_DIRECTORY "${GLAD_DIRECTORY}") | |
endif() | |
set(GLAD_ARGS --out-path "${GLAD_DIR}") | |
if(NOT GG_API) | |
message(FATAL_ERROR "Need API") | |
endif() | |
string(REPLACE ";" "," GLAD_API "${GG_API}") | |
list(APPEND GLAD_ARGS --api "${GLAD_API}") | |
if(GG_EXTENSIONS) | |
string(REPLACE ";" "," GLAD_EXTENSIONS ${GG_EXTENSIONS}) | |
list(APPEND GLAD_ARGS --extensions "${GLAD_EXTENSIONS}") | |
endif() | |
if(GG_QUIET) | |
list(APPEND GLAD_ARGS --quiet) | |
endif() | |
if(GG_MERGE) | |
list(APPEND GLAD_ARGS --merge) | |
endif() | |
set(GLAD_LANGUAGE "c") | |
if(GG_LANGUAGE) | |
string(TOLOWER "${GG_LANGUAGE}" "${GLAD_LANGUAGE}") | |
endif() | |
if(GLAD_LANGUAGE STREQUAL "c") | |
__glad_c_library(LANG_ARGS GLAD_FILES ${GG_UNPARSED_ARGUMENTS} API ${GG_API}) | |
else() | |
message(FATAL_ERROR "Unknown LANGUAGE") | |
endif() | |
list(APPEND GLAD_ARGS ${GLAD_LANGUAGE} ${LANG_ARGS}) | |
# allows: | |
# - bootstrap: generate sources when non-existent | |
# - do not remove the sources when cleaning | |
# BUG: running clean directly after an initial make without sources present, removes the sources | |
set(GLAD_OUT_OF_DATE OFF) | |
set(GLAD_ARGS_PATH "${GLAD_DIR}/args.txt") | |
if(NOT EXISTS "${GLAD_ARGS_PATH}") | |
set(GLAD_OUT_OF_DATE ON) | |
else() | |
file(READ "${GLAD_ARGS_PATH}" GLAD_ARGS_FILE) | |
if(NOT GLAD_ARGS STREQUAL GLAD_ARGS_FILE) | |
set(GLAD_OUT_OF_DATE ON) | |
endif() | |
endif() | |
# regenerate files when argument changes | |
if(GLAD_OUT_OF_DATE) | |
message("${TARGET}: OUT OF DATA") | |
add_custom_command(OUTPUT ${GLAD_FILES} ${GLAD_ARGS_PATH} | |
COMMAND "${CMAKE_COMMAND}" -E remove_directory "${GLAD_DIR}" | |
COMMAND "${GLAD_BIN}" ${GLAD_ARGS} | |
COMMAND "${CMAKE_COMMAND}" "-DPATH=${GLAD_ARGS_PATH}" "-DTEXT=\"${GLAD_ARGS}\"" -P "${CMAKE_CURRENT_SOURCE_DIR}/WriteFile.cmake" | |
COMMAND "${CMAKE_COMMAND}" -E sleep 1 | |
COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_LIST_FILE}" | |
) | |
endif() | |
# add make custom target | |
add_custom_target("regenerate_${TARGET}" | |
COMMAND "${CMAKE_COMMAND}" -E remove_directory "${GLAD_DIR}" | |
COMMAND "${GLAD_BIN}" ${GLAD_ARGS} | |
COMMAND "${CMAKE_COMMAND}" "-DPATH=${GLAD_ARGS_PATH}" "-DTEXT=\"${GLAD_ARGS}\"" -P "${CMAKE_CURRENT_SOURCE_DIR}/WriteFile.cmake" | |
COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_LIST_FILE}" | |
COMMAND "${CMAKE_COMMAND}" -E sleep 1 | |
COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_LIST_FILE}" | |
COMMENT "Regenerating glad source files for ${TARGET}..." | |
) | |
set(GLAD_ADD_LIBRARY_ARGS "") | |
if(GG_EXCLUDE_FROM_ALL) | |
list(APPEND GLAD_ADD_LIBRARY_ARGS EXCLUDE_FROM_ALL) | |
endif() | |
add_library("${TARGET}" ${GLAD_ADD_LIBRARY_ARGS} | |
${GLAD_FILES} | |
) | |
target_include_directories("${TARGET}" | |
PUBLIC | |
"${GLAD_DIR}/include" | |
) | |
target_link_libraries("${TARGET}" | |
PUBLIC | |
${CMAKE_DL_LIBS} | |
) | |
endfunction() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment