Skip to content

Commit

Permalink
Generate build information from CHANGES.md
Browse files Browse the repository at this point in the history
This PR significantly reworks the way glslang is versioned.

Instead of committing changes to the `GLSLANG_MINOR_VERSION` define in
`glslang/Public/ShaderLang.h`, and using `make-revision` to generate
`GLSLANG_PATCH_LEVEL` in `glslang/Include/revision.h`, all version
information is now derived from the new `CHANGES.md` file.

`CHANGES.md` acts as the single source of truth for glslang version
information, along with a convenient place to put all release notes for
each notable change made.

`CHANGES.md` is parsed using the new `build_info.py` python script.
This script can read basic template files to produce new source files,
which it does to read the new `build_info.h.tmpl` to generate (at build
time) a glslang private header at
`<build-dir>/include/glslang/build_info.h`.
I've written generators for each of the CMake, Bazel, gn, and
`Android.mk` build scripts.

The new version code conforms to the Semantic Versioning 2.0 spec.

This new version is also used by the CMake rules to produce versioned
shared objects, including a major-versioned SONAME.

New APIs:
---------

* `glslang::GetVersion()` returns a `Version` struct with the version
  major, minor, patch and flavor.

Breaking API changes:
---------------------

* The public defines `GLSLANG_MINOR_VERSION` and `GLSLANG_PATCH_LEVEL`
  have been entirely removed.
* `glslang/Public/ShaderLang.h` and `glslang/Include/revision.h` have
  been deleted.
* Instead, `<build-dir>/include/glslang/build_info.h` is created in
  the build directory, and `<build-dir>/include` is a CMake `PUBLIC`
  (dependee-inherited) include directory for the glslang targets.
* `<build-dir>/include/glslang/build_info.h` contains the following
   new #defines:
   `GLSLANG_VERSION_MAJOR`, `GLSLANG_VERSION_MINOR`,
   `GLSLANG_VERSION_PATCH`, `GLSLANG_VERSION_FLAVOR`,
   `GLSLANG_VERSION_GREATER_THAN(major, minor, patch)`,
   `GLSLANG_VERSION_GREATER_OR_EQUAL_TO(major, minor, patch)`,
   `GLSLANG_VERSION_LESS_THAN(major, minor, patch)`,
   `GLSLANG_VERSION_LESS_OR_EQUAL_TO(major, minor, patch)`
*  The CMake install output directory contains a copy of
   `build_info.h` at: `include/glslang/build_info.h`
*  Python3 is now always required to build glslang (likely always
   required for transitive dependency builds).
  • Loading branch information
ben-clayton committed Jun 22, 2020
1 parent adacba3 commit 9350a22
Show file tree
Hide file tree
Showing 16 changed files with 1,211 additions and 814 deletions.
52 changes: 42 additions & 10 deletions Android.mk
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
LOCAL_PATH := $(call my-dir)

# Generate glslang/build_info.h
GLSLANG_GENERATED_INCLUDEDIR:=$(TARGET_OUT)/include
GLSLANG_BUILD_INFO_H:=$(GLSLANG_GENERATED_INCLUDEDIR)/glslang/build_info.h

define gen_glslang_build_info_h
$(call generate-file-dir,$(GLSLANG_GENERATED_INCLUDEDIR)/dummy_filename)
$(GLSLANG_BUILD_INFO_H): \
$(LOCAL_PATH)/build_info.py \
$(LOCAL_PATH)/build_info.h.tmpl \
$(LOCAL_PATH)/CHANGES.md
@$(HOST_PYTHON) $(LOCAL_PATH)/build_info.py \
$(LOCAL_PATH) \
-i $(LOCAL_PATH)/build_info.h.tmpl \
-o $(GLSLANG_BUILD_INFO_H)
@echo "[$(TARGET_ARCH_ABI)] Generate : $(GLSLANG_BUILD_INFO_H) <= CHANGES.md"
endef
$(eval $(call gen_glslang_build_info_h))

GLSLANG_OS_FLAGS := -DGLSLANG_OSINCLUDE_UNIX
# AMD and NV extensions are turned on by default in upstream Glslang.
GLSLANG_DEFINES:= -DAMD_EXTENSIONS -DNV_EXTENSIONS -DENABLE_HLSL $(GLSLANG_OS_FLAGS)
Expand All @@ -22,31 +40,38 @@ LOCAL_C_INCLUDES:=$(LOCAL_PATH)/OGLCompiler
LOCAL_STATIC_LIBRARIES:=OSDependent
include $(BUILD_STATIC_LIBRARY)

# Build Glslang's HLSL parser library.
# Build the stubbed HLSL library.
# The HLSL source is now directly referenced by the glslang static library
# instead.
include $(CLEAR_VARS)
LOCAL_MODULE:=HLSL
LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti $(GLSLANG_DEFINES)
LOCAL_SRC_FILES:= \
glslang/HLSL/hlslAttributes.cpp \
glslang/HLSL/hlslGrammar.cpp \
glslang/HLSL/hlslOpMap.cpp \
glslang/HLSL/hlslParseables.cpp \
glslang/HLSL/hlslParseHelper.cpp \
glslang/HLSL/hlslScanContext.cpp \
glslang/HLSL/hlslTokenStream.cpp
hlsl/stub.cpp
LOCAL_C_INCLUDES:=$(LOCAL_PATH) \
$(LOCAL_PATH)/glslang/HLSL
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
GLSLANG_OUT_PATH=$(if $(call host-path-is-absolute,$(TARGET_OUT)),$(TARGET_OUT),$(abspath $(TARGET_OUT)))

# ShaderLang.cpp depends on the generated build_info.h
$(LOCAL_PATH)/glslang/MachineIndependent/ShaderLang.cpp: \
$(GLSLANG_BUILD_INFO_H)

LOCAL_MODULE:=glslang
LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti $(GLSLANG_DEFINES)
LOCAL_EXPORT_C_INCLUDES:=$(LOCAL_PATH)
LOCAL_SRC_FILES:= \
glslang/GenericCodeGen/CodeGen.cpp \
glslang/GenericCodeGen/Link.cpp \
glslang/HLSL/hlslAttributes.cpp \
glslang/HLSL/hlslGrammar.cpp \
glslang/HLSL/hlslOpMap.cpp \
glslang/HLSL/hlslParseables.cpp \
glslang/HLSL/hlslParseHelper.cpp \
glslang/HLSL/hlslScanContext.cpp \
glslang/HLSL/hlslTokenStream.cpp \
glslang/MachineIndependent/attribute.cpp \
glslang/MachineIndependent/Constant.cpp \
glslang/MachineIndependent/glslang_tab.cpp \
Expand Down Expand Up @@ -76,14 +101,19 @@ LOCAL_SRC_FILES:= \
glslang/MachineIndependent/preprocessor/PpTokens.cpp
LOCAL_C_INCLUDES:=$(LOCAL_PATH) \
$(LOCAL_PATH)/glslang/MachineIndependent \
$(GLSLANG_GENERATED_INCLUDEDIR) \
$(GLSLANG_OUT_PATH)
LOCAL_STATIC_LIBRARIES:=OSDependent OGLCompiler HLSL
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)

# GlslangToSpv.cpp depends on the generated build_info.h
$(LOCAL_PATH)/glslang/MachineIndependent/GlslangToSpv.cpp: \
$(GLSLANG_BUILD_INFO_H)

LOCAL_MODULE:=SPIRV
LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti -Werror $(GLSLANG_DEFINES)
LOCAL_EXPORT_C_INCLUDES:=$(LOCAL_PATH)
LOCAL_SRC_FILES:= \
SPIRV/GlslangToSpv.cpp \
SPIRV/InReadableOrder.cpp \
Expand All @@ -94,7 +124,9 @@ LOCAL_SRC_FILES:= \
SPIRV/SpvTools.cpp \
SPIRV/disassemble.cpp \
SPIRV/doc.cpp
LOCAL_C_INCLUDES:=$(LOCAL_PATH) $(LOCAL_PATH)/glslang/SPIRV
LOCAL_C_INCLUDES:=$(LOCAL_PATH) \
$(LOCAL_PATH)/glslang/SPIRV \
$(GLSLANG_GENERATED_INCLUDEDIR)
LOCAL_EXPORT_C_INCLUDES:=$(LOCAL_PATH)/glslang/SPIRV
LOCAL_STATIC_LIBRARIES:=glslang
include $(BUILD_STATIC_LIBRARY)
15 changes: 15 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@ licenses(["notice"])

exports_files(["LICENSE"])

# Build information generation script
py_binary(
name = "build_info",
srcs = ["build_info.py"],
)

genrule(
name = "gen_build_info_h",
srcs = ["CHANGES.md", "build_info.h.tmpl"],
outs = ["glslang/build_info.h"],
cmd = "$(location build_info) $$(dirname $(location CHANGES.md)) -i $(location build_info.h.tmpl) -o $(location glslang/build_info.h)",
tools = [":build_info"],
)

COMMON_COPTS = select({
"@bazel_tools//src/conditions:windows": [""],
"//conditions:default": [
Expand Down Expand Up @@ -62,6 +76,7 @@ cc_library(
"StandAlone/DirStackFileIncluder.h",
"glslang/OSDependent/osinclude.h",
"glslang/Public/ShaderLang.h",
":gen_build_info_h",
],
copts = COMMON_COPTS,
defines = [
Expand Down
29 changes: 28 additions & 1 deletion BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,29 @@ if (defined(is_fuchsia_tree) && is_fuchsia_tree) {
_configs_to_add = [ "//build/config/compiler:no_chromium_code" ]
}

action("glslang_build_info") {
script = "build_info.py"

src_dir = "."
changes_file = "CHANGES.md"
template_file = "build_info.h.tmpl"
out_file = "${target_gen_dir}/include/glslang/build_info.h"

inputs = [
changes_file,
script,
template_file,
]
outputs = [
out_file
]
args = [
rebase_path(src_dir, root_build_dir),
"-i", rebase_path(template_file, root_build_dir),
"-o", rebase_path(out_file, root_build_dir),
]
}

spirv_tools_dir = glslang_spirv_tools_dir

config("glslang_public") {
Expand Down Expand Up @@ -114,7 +137,6 @@ source_set("glslang_sources") {
"glslang/Include/Types.h",
"glslang/Include/arrays.h",
"glslang/Include/intermediate.h",
"glslang/Include/revision.h",
"glslang/MachineIndependent/Constant.cpp",
"glslang/MachineIndependent/InfoSink.cpp",
"glslang/MachineIndependent/Initialize.cpp",
Expand Down Expand Up @@ -194,10 +216,13 @@ source_set("glslang_sources") {
}

deps = [
":glslang_build_info",
"${spirv_tools_dir}:spvtools_opt",
"${spirv_tools_dir}:spvtools_val",
]

include_dirs = [ "${target_gen_dir}/include" ]

configs -= _configs_to_remove
configs += _configs_to_add
}
Expand Down Expand Up @@ -230,6 +255,8 @@ executable("glslang_validator") {
":glslang_sources",
]

include_dirs = [ "${target_gen_dir}/include" ]

configs -= _configs_to_remove
configs += _configs_to_add
}
Expand Down
24 changes: 24 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Revision history for `glslang`

All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/).

## 10.15.3802-dev 2020-06-16

### Breaking changes

* The following files have been removed:
* `glslang/include/revision.h`
* `glslang/include/revision.template`

The `GLSLANG_MINOR_VERSION` and `GLSLANG_PATCH_LEVEL` defines have been removed
from the public headers. \
Instead each build script now uses the new `build_info.py`
script along with the `build_info.h.tmpl` and this `CHANGES.md` file to generate
the glslang build-time generated header `glslang/build_info.h`.

The new public API to obtain the `glslang` version is `glslang::GetVersion()`.

### Other changes
* `glslang` shared objects produced by CMake are now `SONAME` versioned using
[Semantic Versioning 2.0.0](https://semver.org/).
46 changes: 43 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,50 @@ endfunction(glslang_set_link_args)

# CMake needs to find the right version of python, right from the beginning,
# otherwise, it will find the wrong version and fail later
if(BUILD_EXTERNAL AND IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/External)
find_package(PythonInterp 3 REQUIRED)
find_package(PythonInterp 3 REQUIRED)

# Root directory for build-time generated include files
set(GLSLANG_GENERATED_INCLUDEDIR "${CMAKE_BINARY_DIR}/include")

################################################################################
# Build version information generation
################################################################################
set(GLSLANG_CHANGES_FILE "${CMAKE_SOURCE_DIR}/CHANGES.md")
set(GLSLANG_BUILD_INFO_PY "${CMAKE_SOURCE_DIR}/build_info.py")
set(GLSLANG_BUILD_INFO_H_TMPL "${CMAKE_SOURCE_DIR}/build_info.h.tmpl")
set(GLSLANG_BUILD_INFO_H "${GLSLANG_GENERATED_INCLUDEDIR}/glslang/build_info.h")

# Command to build the build_info.h file
add_custom_command(
OUTPUT ${GLSLANG_BUILD_INFO_H}
COMMAND ${PYTHON_EXECUTABLE} "${GLSLANG_BUILD_INFO_PY}"
${CMAKE_CURRENT_SOURCE_DIR}
"-i" ${GLSLANG_BUILD_INFO_H_TMPL}
"-o" ${GLSLANG_BUILD_INFO_H}
DEPENDS ${GLSLANG_BUILD_INFO_PY}
${GLSLANG_CHANGES_FILE}
${GLSLANG_BUILD_INFO_H_TMPL}
COMMENT "Generating ${GLSLANG_BUILD_INFO_H}")

# We depend on these for later projects, so they should come first.
# Target to build the build_info.h file
add_custom_target(glslang-build-info DEPENDS ${GLSLANG_BUILD_INFO_H})

# Populate the CMake GLSLANG_VERSION* variables with the build version
# information.
execute_process(
COMMAND ${PYTHON_EXECUTABLE} "${GLSLANG_BUILD_INFO_PY}"
${CMAKE_CURRENT_SOURCE_DIR} "<major>.<minor>.<patch><-flavor>;<major>;<minor>;<patch>;<flavor>"
OUTPUT_VARIABLE "GLSLANG_VERSIONS"
OUTPUT_STRIP_TRAILING_WHITESPACE)
list(GET "GLSLANG_VERSIONS" 0 "GLSLANG_VERSION")
list(GET "GLSLANG_VERSIONS" 1 "GLSLANG_VERSION_MAJOR")
list(GET "GLSLANG_VERSIONS" 2 "GLSLANG_VERSION_MINOR")
list(GET "GLSLANG_VERSIONS" 3 "GLSLANG_VERSION_PATCH")
list(GET "GLSLANG_VERSIONS" 4 "GLSLANG_VERSION_FLAVOR")
configure_file(${GLSLANG_CHANGES_FILE} "${CMAKE_CURRENT_BINARY_DIR}/CHANGES.md") # Required to re-run cmake on version change

if(BUILD_EXTERNAL AND IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/External)
# We depend on these for later projects, so they should come first.
add_subdirectory(External)
endif()

Expand Down
2 changes: 2 additions & 0 deletions SPIRV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ set_property(TARGET SPIRV PROPERTY FOLDER glslang)
set_property(TARGET SPIRV PROPERTY POSITION_INDEPENDENT_CODE ON)
target_include_directories(SPIRV PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
$<BUILD_INTERFACE:${GLSLANG_GENERATED_INCLUDEDIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
add_dependencies(SPIRV glslang-build-info)

if (ENABLE_SPVREMAPPER)
add_library(SPVRemapper ${LIB_TYPE} ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
Expand Down
33 changes: 18 additions & 15 deletions SPIRV/GlslangToSpv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ namespace spv {
#include "../glslang/MachineIndependent/localintermediate.h"
#include "../glslang/MachineIndependent/SymbolTable.h"
#include "../glslang/Include/Common.h"
#include "../glslang/Include/revision.h"

// Build-time generated includes
#include "glslang/build_info.h"

#include <fstream>
#include <iomanip>
Expand Down Expand Up @@ -1613,7 +1615,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
case EShLangAnyHit:
case EShLangClosestHit:
case EShLangMiss:
case EShLangCallable:
case EShLangCallable:
{
auto& extensions = glslangIntermediate->getRequestedExtensions();
if (extensions.find("GL_NV_ray_tracing") == extensions.end()) {
Expand Down Expand Up @@ -2194,7 +2196,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
operandNode = node->getOperand()->getAsBinaryNode()->getLeft();
else
operandNode = node->getOperand();

operandNode->traverse(this);

spv::Id operand = spv::NoResult;
Expand Down Expand Up @@ -3065,7 +3067,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
break;
case 1:
{
OpDecorations decorations = { precision,
OpDecorations decorations = { precision,
TranslateNoContractionDecoration(node->getType().getQualifier()),
TranslateNonUniformDecoration(node->getType().getQualifier()) };
result = createUnaryOperation(
Expand Down Expand Up @@ -3186,7 +3188,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
// smear condition to vector, if necessary (AST is always scalar)
// Before 1.4, smear like for mix(), starting with 1.4, keep it scalar
if (glslangIntermediate->getSpv().spv < glslang::EShTargetSpv_1_4 && builder.isVector(trueValue)) {
condition = builder.smearScalar(spv::NoPrecision, condition,
condition = builder.smearScalar(spv::NoPrecision, condition,
builder.makeVectorType(builder.makeBoolType(),
builder.getNumComponents(trueValue)));
}
Expand Down Expand Up @@ -5201,10 +5203,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
assert(builder.isStructType(resultStructType));

//resType (SPIR-V type) contains 6 elements:
//Member 0 must be a Boolean type scalar(LOD),
//Member 1 must be a vector of integer type, whose Signedness operand is 0(anchor),
//Member 2 must be a vector of integer type, whose Signedness operand is 0(offset),
//Member 3 must be a vector of integer type, whose Signedness operand is 0(mask),
//Member 0 must be a Boolean type scalar(LOD),
//Member 1 must be a vector of integer type, whose Signedness operand is 0(anchor),
//Member 2 must be a vector of integer type, whose Signedness operand is 0(offset),
//Member 3 must be a vector of integer type, whose Signedness operand is 0(mask),
//Member 4 must be a scalar of integer type, whose Signedness operand is 0(lod),
//Member 5 must be a scalar of integer type, whose Signedness operand is 0(granularity).
std::vector<spv::Id> members;
Expand All @@ -5217,7 +5219,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
//call ImageFootprintNV
spv::Id res = builder.createTextureCall(precision, resType, sparse, cracked.fetch, cracked.proj,
cracked.gather, noImplicitLod, params, signExtensionMask());

//copy resType (SPIR-V type) to resultStructType(OpenGL type)
for (int i = 0; i < 5; i++) {
builder.clearAccessChain();
Expand Down Expand Up @@ -5270,7 +5272,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
}
#endif

std::vector<spv::Id> result( 1,
std::vector<spv::Id> result( 1,
builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather,
noImplicitLod, params, signExtensionMask())
);
Expand Down Expand Up @@ -6750,7 +6752,7 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
} else {
scopeId = builder.makeUintConstant(spv::ScopeDevice);
}
// semantics default to relaxed
// semantics default to relaxed
spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.isVolatile() &&
glslangIntermediate->usingVulkanMemoryModel() ?
spv::MemorySemanticsVolatileMask :
Expand Down Expand Up @@ -8680,9 +8682,10 @@ void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName,
out.open(baseName, std::ios::binary | std::ios::out);
if (out.fail())
printf("ERROR: Failed to open file: %s\n", baseName);
out << "\t// " <<
GetSpirvGeneratorVersion() << "." << GLSLANG_MINOR_VERSION << "." << GLSLANG_PATCH_LEVEL <<
std::endl;
out << "\t// " <<
GetSpirvGeneratorVersion() <<
GLSLANG_VERSION_MAJOR << "." << GLSLANG_VERSION_MINOR << "." << GLSLANG_VERSION_PATCH <<
GLSLANG_VERSION_FLAVOR << std::endl;
if (varName != nullptr) {
out << "\t #pragma once" << std::endl;
out << "const uint32_t " << varName << "[] = {" << std::endl;
Expand Down
Loading

0 comments on commit 9350a22

Please sign in to comment.