From f503a0b3faf5d324c62881d61e1ba1e0942becd9 Mon Sep 17 00:00:00 2001 From: Ellie Hermaszewska Date: Wed, 21 Aug 2024 15:59:08 +0800 Subject: [PATCH] Dont require llvm for building generators (#4895) * Dont require llvm for building generators * Fetch slang-llvm.so from correct release (#4847) * Fetch slang-llvm.so from correct release Closes https://github.com/shader-slang/slang/issues/4648 Should close https://github.com/shader-slang/slang/issues/4812 * Update docs * Correct documentation on cmake option * Neaten cmake script * Fix fetching on windows --------- Co-authored-by: Yong He * Be a bit more careful dealing with release list fetching failure * clarify error messages --------- Co-authored-by: Yong He --- CMakeLists.txt | 26 +++++----- CMakePresets.json | 14 ++++-- cmake/GitHubRelease.cmake | 100 ++++++++++++++++++++++++++++++++++++++ docs/building.md | 4 ++ 4 files changed, 129 insertions(+), 15 deletions(-) create mode 100644 cmake/GitHubRelease.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 54eae379b9..d2972e642b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,7 @@ include(Glob) include(LLVM) include(SlangTarget) include(AutoOption) +include(GitHubRelease) # # Options @@ -125,25 +126,26 @@ enum_option( "How to get or build slang-llvm:" # Options FETCH_BINARY - "Use a binary distribution of the slang-llvm library instead of building or using LLVM (default for Windows)" + "Use a binary distribution of the slang-llvm library instead of building or using LLVM (default)" USE_SYSTEM_LLVM - "Build slang-llvm using system-provided LLVM and Clang binaries (default for non-Windows hosts)" + "Build slang-llvm using system-provided LLVM and Clang binaries" DISABLE "Do not build llvm or fetch slang-llvm" ) -macro(slang_llvm_binary_url_option version filename) + +if(SLANG_SLANG_LLVM_FLAVOR MATCHES FETCH_BINARY) + # If the user didn't specify a URL, find the best one now + if(NOT SLANG_SLANG_LLVM_BINARY_URL) + get_best_slang_binary_release_url(url) + if(NOT DEFINED url) + message(FATAL_ERROR "Unable to find binary release for slang-llvm, please set a different SLANG_SLANG_LLVM_FLAVOR or set SLANG_SLANG_LLVM_BINARY_URL manually") + endif() + endif() set(SLANG_SLANG_LLVM_BINARY_URL - "https://github.com/shader-slang/slang-llvm/releases/download/${version}/${filename}" + ${url} CACHE STRING "URL specifying the location of the slang-llvm prebuilt library" ) -endmacro() -if(CMAKE_SYSTEM_NAME MATCHES "Windows") - slang_llvm_binary_url_option("v13.x-43" "slang-llvm-13.x-43-win64.zip") -elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin") - slang_llvm_binary_url_option("v13.x-43" "slang-llvm-v13.x-43-macosx-x86_64-release.zip") -else() - slang_llvm_binary_url_option("v13.x-43" "slang-llvm-v13.x-43-linux-x86_64-release.zip") endif() # @@ -392,7 +394,7 @@ if(SLANG_SLANG_LLVM_FLAVOR STREQUAL "FETCH_BINARY") endif() set(slang_llvm_dest_object - ${CMAKE_BINARY_DIR}/$/${runtime_subdir}/${slang_llvm_filename} + ${CMAKE_BINARY_DIR}/$/${module_subdir}/${slang_llvm_filename} ) add_custom_command( OUTPUT ${slang_llvm_dest_object} diff --git a/CMakePresets.json b/CMakePresets.json index cd516c8eae..e87b976bdc 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -53,6 +53,14 @@ "cacheVariables": { "SLANG_SLANG_LLVM_FLAVOR": "USE_SYSTEM_LLVM" } + }, + { + "name": "generators", + "inherits": "default", + "description": "Build the compile time generators used in building Slang", + "cacheVariables": { + "SLANG_SLANG_LLVM_FLAVOR": "DISABLE" + } } ], "buildPresets": [ @@ -69,7 +77,7 @@ { "name": "generators", "inherits": "release", - "configurePreset": "default", + "configurePreset": "generators", "targets": [ "all-generators" ] @@ -115,7 +123,7 @@ { "name": "generators", "inherits": "release", - "configurePreset": "default", + "configurePreset": "generators", "variables": { "CPACK_PACKAGE_FILE_NAME": "slang-generators", "CPACK_COMPONENTS_ALL": "generators" @@ -171,7 +179,7 @@ "steps": [ { "type": "configure", - "name": "default" + "name": "generators" }, { "type": "build", diff --git a/cmake/GitHubRelease.cmake b/cmake/GitHubRelease.cmake new file mode 100644 index 0000000000..e63fb7885b --- /dev/null +++ b/cmake/GitHubRelease.cmake @@ -0,0 +1,100 @@ +function(check_release_and_get_latest owner repo version os arch out_var) + # Construct the URL for the specified version's release API endpoint + set(version_url "https://api.github.com/repos/${owner}/${repo}/releases/tags/v${version}") + + set(json_output_file "${CMAKE_CURRENT_BINARY_DIR}/${owner}_${repo}_release_info.json") + + function(check_assets_for_file json_content filename found_var) + string(JSON asset_count LENGTH "${json_content}" "assets") + set(found "FALSE") + foreach(i RANGE 0 ${asset_count}) + string(JSON asset_name GET "${json_content}" "assets" ${i} "name") + if("${asset_name}" STREQUAL "${filename}") + set(found "TRUE") + break() + endif() + endforeach() + set(${found_var} "${found}" PARENT_SCOPE) + endfunction() + + # Download the specified release info from GitHub + file(DOWNLOAD "${version_url}" "${json_output_file}" STATUS download_statuses) + list(GET download_statuses 0 status_code) + if(status_code EQUAL 0) + file(READ "${json_output_file}" json_content) + + # Check if the specified version contains the expected ZIP file + set(desired_zip "${repo}-${version}-${os}-${arch}.zip") + check_assets_for_file("${json_content}" "${desired_zip}" file_found) + + if(file_found) + set(${out_var} "${version}" PARENT_SCOPE) + return() + endif() + message(WARNING "Failed to find ${desired_zip} in release assets for ${version} from ${version_url}\nFalling back to latest version if it differs") + else() + message(WARNING "Failed to download release info for version ${version} from ${version_url}\nFalling back to latest version if it differs") + endif() + + + # If not found, get the latest release tag + set(latest_release_url "https://api.github.com/repos/${owner}/${repo}/releases/latest") + file(DOWNLOAD "${latest_release_url}" "${json_output_file}" STATUS download_status) + list(GET download_status 0 status_code) + if(NOT status_code EQUAL 0) + message(WARNING "Failed to download latest release info from ${latest_release_url}") + return() + endif() + + # Get the tag from this release json file + file(READ "${json_output_file}" latest_json_content) + string(JSON latest_release_tag GET "${latest_json_content}" "tag_name") + string(REGEX REPLACE "^v" "" latest_version "${latest_release_tag}") + + if(latest_version EQUAL version) + # The versions are the same + message(WARNING "No release binary for ${os}-${arch} exists for ${version}") + return() + endif() + + # Check if the expected ZIP file is in the latest release + set(desired_zip "${repo}-${latest_version}-${os}-${arch}.zip") + check_assets_for_file("${latest_json_content}" "${desired_zip}" file_found_latest) + + if(file_found_latest) + # If we got it, we found a good version + set(${out_var} "${latest_version}" PARENT_SCOPE) + else() + message(WARNING "No release binary for ${os}-${arch} exists for ${version} or the latest version ${latest_version}") + endif() +endfunction() + +function(get_best_slang_binary_release_url out_var) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64") + set(arch "x86_64") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|ARM64|arm64") + set(arch "aarch64") + else() + message(WARNING "Unsupported architecture for slang binary releases: ${CMAKE_SYSTEM_PROCESSOR}") + return() + endif() + + if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(os "windows") + elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(os "macos") + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(os "linux") + else() + message(WARNING "Unsupported operating system for slang binary releases: ${CMAKE_SYSTEM_NAME}") + return() + endif() + + set(owner "shader-slang") + set(repo "slang") + + check_release_and_get_latest(${owner} ${repo} ${SLANG_VERSION_NUMERIC} ${os} ${arch} release_version) + if(DEFINED release_version) + set(${out_var} "https://github.com/${owner}/${repo}/releases/download/v${release_version}/slang-${release_version}-${os}-${arch}.zip" PARENT_SCOPE) + endif() +endfunction() diff --git a/docs/building.md b/docs/building.md index 2b24353021..d86b80205f 100644 --- a/docs/building.md +++ b/docs/building.md @@ -101,6 +101,10 @@ There are several options for getting llvm-support: - You can set `SLANG_SLANG_LLVM_BINARY_URL` to point to a local `libslang-llvm.so/slang-llvm.dll` or set it to a URL of an zip/archive containing such a file + - If this isn't set then the build system tries to download it from the + release on github matching the current tag. If such a tag doesn't exist + or doesn't have the correct os*arch combination then the latest release + will be tried. - Use a system supplied LLVM: `-DSLANG_SLANG_LLVM_FLAVOR=USE_SYSTEM_LLVM`, you must have llvm-13.0 and a matching libclang installed. It's important that either: