yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Gangzheng TongUse GITHUB_TOKEN for fetching prebuilt (#6712)edb728938

master
6.3 KiB174 linesraw
1if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
2    set(dep_shared_library_prefix "")
3else()
4    set(dep_shared_library_prefix "lib")
5endif()
6
7# Helper function to download and extract an archive
8function(download_and_extract archive_name url)
9    cmake_parse_arguments(ARG "" "SLANG_GITHUB_TOKEN" "" ${ARGN})
10    cmake_path(GET url FILENAME filename_with_ext)
11    cmake_path(GET url STEM LAST_ONLY file_stem)
12    set(archive_path "${CMAKE_CURRENT_BINARY_DIR}/${filename_with_ext}")
13    set(extract_dir "${CMAKE_CURRENT_BINARY_DIR}/${file_stem}")
14
15    # Check if already extracted
16    file(GLOB EXTRACT_DIR_CONTENTS "${extract_dir}/*")
17    if(EXTRACT_DIR_CONTENTS)
18        message(STATUS "Using existing extracted files in ${extract_dir}")
19    else()
20        # Check if archive already exists
21        if(EXISTS ${url})
22            message(STATUS "Using local file for ${archive_name}: ${url}")
23            set(archive_path ${url})
24        elseif(EXISTS ${archive_path})
25            message(
26                STATUS
27                "Using existing archive for ${archive_name}: ${archive_path}"
28            )
29        else()
30            set(download_args ${url} ${archive_path} STATUS status)
31            if(ARG_SLANG_GITHUB_TOKEN)
32                list(
33                    APPEND
34                    download_args
35                    HTTPHEADER
36                    "Authorization: token ${ARG_SLANG_GITHUB_TOKEN}"
37                )
38            endif()
39
40            file(DOWNLOAD ${download_args})
41
42            list(GET status 0 status_code)
43            list(GET status 1 status_string)
44            if(NOT status_code EQUAL 0)
45                message(
46                    WARNING
47                    "Failed to download ${archive_name} from ${url}: ${status_string} with status code ${status_code}"
48                )
49                message(
50                    WARNING
51                    "If API rate limit is exceeded, Github allows a higher limit when you use token. Try a cmake option -DSLANG_GITHUB_TOKEN=your_token_here"
52                )
53                return()
54            endif()
55        endif()
56
57        file(ARCHIVE_EXTRACT INPUT ${archive_path} DESTINATION ${extract_dir})
58        message(STATUS "${archive_name} extracted to ${extract_dir}")
59    endif()
60
61    set(${archive_name}_SOURCE_DIR ${extract_dir} PARENT_SCOPE)
62endfunction()
63
64# Add rules to copy & install shared library of name 'library_name' in the 'module_subdir' directory.
65# If 'url' is a directory, the shared library (with platform-specific shared library prefixes and suffixes) will be
66# taken from the directory, and whatever is found there will be used to produce the install rule.
67# If the 'url' is a path to a file with the platform-specific shared library prefix and suffix, then that file
68# will be used to produce the install rule.
69# Otherwise, the 'url' is interpreted as an URL, and the content of the URL will be fetched, extracted and searched
70# for the shared library to produce the install rule.
71function(copy_fetched_shared_library library_name url)
72    cmake_parse_arguments(ARG "IGNORE_FAILURE" "SLANG_GITHUB_TOKEN" "" ${ARGN})
73
74    # Don't ignore failure if a Github token is provided;
75    # as we assume that the token will fix the rate limit issue.
76    if(ARG_IGNORE_FAILURE AND NOT ARG_SLANG_GITHUB_TOKEN)
77        set(error_type STATUS)
78    else()
79        set(error_type SEND_ERROR)
80    endif()
81
82    set(shared_library_filename
83        "${dep_shared_library_prefix}${library_name}${CMAKE_SHARED_LIBRARY_SUFFIX}"
84    )
85    macro(from_glob dir)
86        # A little helper function
87        file(GLOB_RECURSE source_object "${dir}/${shared_library_filename}")
88        list(LENGTH source_object nmatches)
89        if(nmatches EQUAL 0)
90            message(
91                ${error_type}
92                "Unable to find ${shared_library_filename} in ${url}"
93            )
94        elseif(nmatches GREATER 1)
95            message(
96                ${error_type}
97                "Found multiple files named ${shared_library_filename} in ${url}"
98            )
99        endif()
100    endmacro()
101
102    if(IS_DIRECTORY "${url}")
103        # Just glob directly from a local directory
104        from_glob("${url}")
105    elseif(
106        url
107            MATCHES
108            "${dep_shared_library_prefix}.+${CMAKE_SHARED_LIBRARY_SUFFIX}$"
109        AND EXISTS "${url}"
110    )
111        # Otherwise, if it's a direct path to a shared object, use that
112        set(source_object "${url}")
113    else()
114        # Otherwise, download and extract from whatever URL we have
115        download_and_extract(
116            "${library_name}"
117            "${url}"
118            SLANG_GITHUB_TOKEN ${ARG_SLANG_GITHUB_TOKEN}
119        )
120        if(DEFINED ${library_name}_SOURCE_DIR)
121            from_glob(${${library_name}_SOURCE_DIR})
122        elseif(ARG_IGNORE_FAILURE)
123            return()
124        else()
125            message(
126                SEND_ERROR
127                "Unable to download and extract ${library_name} from ${url}"
128            )
129            return()
130        endif()
131    endif()
132
133    # We didn't find it, just return and don't create a target and operation
134    # which will fail
135    if((NOT EXISTS "${source_object}") AND ARG_IGNORE_FAILURE)
136        return()
137    endif()
138
139    set(dest_object
140        ${CMAKE_BINARY_DIR}/$<CONFIG>/${module_subdir}/${shared_library_filename}
141    )
142    add_custom_command(
143        OUTPUT ${dest_object}
144        COMMAND
145            ${CMAKE_COMMAND} -E copy_if_different ${source_object}
146            ${dest_object}
147        DEPENDS ${source_object}
148        VERBATIM
149    )
150    # Give this copying action a name
151    add_custom_target(copy-${library_name} DEPENDS ${dest_object})
152    set_target_properties(copy-${library_name} PROPERTIES FOLDER generated)
153
154    # Put this into a library target
155    add_library(${library_name} MODULE IMPORTED GLOBAL)
156    add_dependencies(${library_name} copy-${library_name})
157    set_property(
158        TARGET ${library_name}
159        PROPERTY IMPORTED_LOCATION ${dest_object}
160    )
161endfunction()
162
163function(install_fetched_shared_library library_name url)
164    copy_fetched_shared_library(${library_name} ${url} ${ARGN})
165    set(shared_library_filename
166        "${dep_shared_library_prefix}${library_name}${CMAKE_SHARED_LIBRARY_SUFFIX}"
167    )
168    set(dest_object
169        ${CMAKE_BINARY_DIR}/$<CONFIG>/${module_subdir}/${shared_library_filename}
170    )
171    if(TARGET ${library_name})
172        install(PROGRAMS ${dest_object} DESTINATION ${module_subdir})
173    endif()
174endfunction()