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 Jul 9, 2020
1 parent 5aaa0c2 commit fbe9a23
Show file tree
Hide file tree
Showing 16 changed files with 515 additions and 64 deletions.
52 changes: 42 additions & 10 deletions Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,24 @@

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 @@ -55,31 +73,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 @@ -109,14 +134,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)/SPIRV/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 @@ -127,7 +157,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 @@ -43,6 +43,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 @@ -93,6 +107,7 @@ cc_library(
"StandAlone/DirStackFileIncluder.h",
"glslang/OSDependent/osinclude.h",
"glslang/Public/ShaderLang.h",
":gen_build_info_h",
],
copts = COMMON_COPTS,
defines = [
Expand Down
33 changes: 31 additions & 2 deletions 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
if (!defined(glslang_angle)) {
glslang_angle = false
Expand Down Expand Up @@ -109,7 +132,6 @@ template("glslang_sources_common") {
"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 @@ -216,13 +238,18 @@ template("glslang_sources_common") {
]
}

deps = [ ":glslang_build_info" ]

if (invoker.enable_opt) {
deps = [
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 @@ -265,6 +292,8 @@ executable("glslang_validator") {
]
public_configs = [ ":glslang_hlsl" ]

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.3847-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/).
67 changes: 61 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ if(BUILD_SHARED_LIBS)
set(LIB_TYPE SHARED)
endif()

if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
# This logic inside SPIRV-Tools, which can upset build target dependencies
# if changed after targets are already defined. To prevent these issues,
# ensure CMAKE_BUILD_TYPE is assigned early and at the glslang root scope.
message(STATUS "No build type selected, default to Debug")
set(CMAKE_BUILD_TYPE "Debug")
endif()

option(SKIP_GLSLANG_INSTALL "Skip installation" ${SKIP_GLSLANG_INSTALL})
if(NOT ${SKIP_GLSLANG_INSTALL})
set(ENABLE_GLSLANG_INSTALL ON)
Expand Down Expand Up @@ -221,12 +229,54 @@ 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)

# We depend on these for later projects, so they should come first.
add_subdirectory(External)
endif()
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}")

# 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

# glslang_add_build_info_dependency() adds the glslang-build-info dependency and
# generated include directories to target.
function(glslang_add_build_info_dependency target)
target_include_directories(${target} PUBLIC $<BUILD_INTERFACE:${GLSLANG_GENERATED_INCLUDEDIR}>)
add_dependencies(${target} glslang-build-info)
endfunction()

# glslang_only_export_explicit_symbols() makes the symbol visibility hidden by
# default for <target> when building shared libraries, and sets the
Expand Down Expand Up @@ -256,6 +306,11 @@ else()
message(NOTICE "Your CMake version is ${CMAKE_VERSION}. Update to at least 3.16 to enable precompiled headers to speed up incremental builds")
endif()

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()

if(NOT TARGET SPIRV-Tools-opt)
set(ENABLE_OPT OFF)
endif()
Expand Down
10 changes: 6 additions & 4 deletions SPIRV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,10 @@ add_library(SPIRV ${LIB_TYPE} ${SOURCES} ${HEADERS})
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}/..>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)

glslang_add_build_info_dependency(SPIRV)

if (ENABLE_SPVREMAPPER)
add_library(SPVRemapper ${LIB_TYPE} ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
Expand All @@ -95,8 +97,8 @@ if(ENABLE_OPT)
)
target_link_libraries(SPIRV PRIVATE MachineIndependent SPIRV-Tools-opt)
target_include_directories(SPIRV PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../External>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/External>)
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../External>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/External>)
else()
target_link_libraries(SPIRV PRIVATE MachineIndependent)
endif(ENABLE_OPT)
Expand Down
11 changes: 7 additions & 4 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 @@ -8689,9 +8691,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
12 changes: 7 additions & 5 deletions StandAlone/StandAlone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
#include "Worklist.h"
#include "DirStackFileIncluder.h"
#include "./../glslang/Include/ShHandle.h"
#include "./../glslang/Include/revision.h"
#include "./../glslang/Public/ShaderLang.h"
#include "../SPIRV/GlslangToSpv.h"
#include "../SPIRV/GLSL.std.450.h"
Expand All @@ -62,6 +61,9 @@

#include "../glslang/OSDependent/osinclude.h"

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

extern "C" {
GLSLANG_EXPORT void ShOutputHtml();
}
Expand Down Expand Up @@ -1278,13 +1280,13 @@ int singleMain()
#endif

if (Options & EOptionDumpBareVersion) {
printf("%d.%d.%d\n",
glslang::GetSpirvGeneratorVersion(), GLSLANG_MINOR_VERSION, GLSLANG_PATCH_LEVEL);
printf("%d:%d.%d.%d%s\n", glslang::GetSpirvGeneratorVersion(), GLSLANG_VERSION_MAJOR, GLSLANG_VERSION_MINOR,
GLSLANG_VERSION_PATCH, GLSLANG_VERSION_FLAVOR);
if (workList.empty())
return ESuccess;
} else if (Options & EOptionDumpVersions) {
printf("Glslang Version: %d.%d.%d\n",
glslang::GetSpirvGeneratorVersion(), GLSLANG_MINOR_VERSION, GLSLANG_PATCH_LEVEL);
printf("Glslang Version: %d:%d.%d.%d%s\n", glslang::GetSpirvGeneratorVersion(), GLSLANG_VERSION_MAJOR,
GLSLANG_VERSION_MINOR, GLSLANG_VERSION_PATCH, GLSLANG_VERSION_FLAVOR);
printf("ESSL Version: %s\n", glslang::GetEsslVersionString());
printf("GLSL Version: %s\n", glslang::GetGlslVersionString());
std::string spirvVersion;
Expand Down
Loading

0 comments on commit fbe9a23

Please sign in to comment.