glslang: Only export public interface for SOs
Default to `-fvisibility=hidden`, and annotate the public glslang interface with `GLSLANG_EXPORT` to change the visibility of these cherry-picked symbols to default.
This is also used by Windows builds for `__declspec(dllexport)`-ing the public DLL interface.
This allows us to classify API changes into those that are publicly backwards compatible, and those that are not.
Note that `libSPIRV` will likely need similar treatment.
Issues: #2283, #1484
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e679228..9c2f861 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -205,6 +205,21 @@
add_subdirectory(External)
endif()
+# glslang_only_export_explicit_symbols() makes the symbol visibility hidden by
+# default for <target> when building shared libraries, and sets the
+# GLSLANG_IS_SHARED_LIBRARY define, and GLSLANG_EXPORTING to 1 when specifically
+# building <target>.
+function(glslang_only_export_explicit_symbols target)
+ target_compile_definitions(${target} PUBLIC "GLSLANG_IS_SHARED_LIBRARY=1")
+ if(BUILD_SHARED_LIBS)
+ if(WIN32)
+ target_compile_definitions(${target} PRIVATE "GLSLANG_EXPORTING=1")
+ else()
+ target_compile_options(${target} PRIVATE "-fvisibility=hidden")
+ endif()
+ endif()
+endfunction()
+
if(NOT TARGET SPIRV-Tools-opt)
set(ENABLE_OPT OFF)
endif()
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index 5e17aff..662b68d 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -63,7 +63,7 @@
#include "../glslang/OSDependent/osinclude.h"
extern "C" {
- SH_IMPORT_EXPORT void ShOutputHtml();
+ GLSLANG_EXPORT void ShOutputHtml();
}
// Command-line options
diff --git a/glslang/CMakeLists.txt b/glslang/CMakeLists.txt
index 990f442..d707b62 100644
--- a/glslang/CMakeLists.txt
+++ b/glslang/CMakeLists.txt
@@ -132,6 +132,8 @@
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
+glslang_only_export_explicit_symbols(glslang)
+
if(WIN32 AND BUILD_SHARED_LIBS)
set_target_properties(glslang PROPERTIES PREFIX "")
endif()
diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h
index d51749b..5b30474 100644
--- a/glslang/Public/ShaderLang.h
+++ b/glslang/Public/ShaderLang.h
@@ -44,18 +44,27 @@
#include <vector>
#ifdef _WIN32
-#define C_DECL __cdecl
-//#ifdef SH_EXPORTING
-// #define SH_IMPORT_EXPORT __declspec(dllexport)
-//#else
-// #define SH_IMPORT_EXPORT __declspec(dllimport)
-//#endif
-#define SH_IMPORT_EXPORT
+ #define C_DECL __cdecl
#else
-#define SH_IMPORT_EXPORT
-#define C_DECL
+ #define C_DECL
#endif
+#ifdef GLSLANG_IS_SHARED_LIBRARY
+ #ifdef _WIN32
+ #ifdef GLSLANG_EXPORTING
+ #define GLSLANG_EXPORT __declspec(dllexport)
+ #else
+ #define GLSLANG_EXPORT __declspec(dllimport)
+ #endif
+ #elif __GNUC__ >= 4
+ #define GLSLANG_EXPORT __attribute__((visibility("default")))
+ #else
+ #define GLSLANG_EXPORT
+ #endif
+#else // GLSLANG_IS_SHARED_LIBRARY
+ #define GLSLANG_EXPORT
+#endif // GLSLANG_IS_SHARED_LIBRARY
+
//
// This is the platform independent interface between an OGL driver
// and the shading language compiler/linker.
@@ -75,12 +84,12 @@
//
// (Call once per process, not once per thread.)
//
-SH_IMPORT_EXPORT int ShInitialize();
+GLSLANG_EXPORT int ShInitialize();
//
// Call this at process shutdown to clean up memory.
//
-SH_IMPORT_EXPORT int ShFinalize();
+GLSLANG_EXPORT int ShFinalize();
//
// Types of languages the compiler can consume.
@@ -205,7 +214,7 @@
TTarget target; // what to generate
};
-const char* StageName(EShLanguage);
+GLSLANG_EXPORT const char* StageName(EShLanguage);
} // end namespace glslang
@@ -306,10 +315,10 @@
// Driver calls these to create and destroy compiler/linker
// objects.
//
-SH_IMPORT_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader
-SH_IMPORT_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair
-SH_IMPORT_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object)
-SH_IMPORT_EXPORT void ShDestruct(ShHandle);
+GLSLANG_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader
+GLSLANG_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair
+GLSLANG_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object)
+GLSLANG_EXPORT void ShDestruct(ShHandle);
//
// The return value of ShCompile is boolean, non-zero indicating
@@ -318,7 +327,7 @@
// The info-log should be written by ShCompile into
// ShHandle, so it can answer future queries.
//
-SH_IMPORT_EXPORT int ShCompile(
+GLSLANG_EXPORT int ShCompile(
const ShHandle,
const char* const shaderStrings[],
const int numStrings,
@@ -331,7 +340,7 @@
EShMessages messages = EShMsgDefault // warnings and errors
);
-SH_IMPORT_EXPORT int ShLinkExt(
+GLSLANG_EXPORT int ShLinkExt(
const ShHandle, // linker object
const ShHandle h[], // compiler objects to link together
const int numHandles);
@@ -340,26 +349,26 @@
// ShSetEncrpytionMethod is a place-holder for specifying
// how source code is encrypted.
//
-SH_IMPORT_EXPORT void ShSetEncryptionMethod(ShHandle);
+GLSLANG_EXPORT void ShSetEncryptionMethod(ShHandle);
//
// All the following return 0 if the information is not
// available in the object passed down, or the object is bad.
//
-SH_IMPORT_EXPORT const char* ShGetInfoLog(const ShHandle);
-SH_IMPORT_EXPORT const void* ShGetExecutable(const ShHandle);
-SH_IMPORT_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*); // to detect user aliasing
-SH_IMPORT_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*); // to force any physical mappings
+GLSLANG_EXPORT const char* ShGetInfoLog(const ShHandle);
+GLSLANG_EXPORT const void* ShGetExecutable(const ShHandle);
+GLSLANG_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*); // to detect user aliasing
+GLSLANG_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*); // to force any physical mappings
//
// Tell the linker to never assign a vertex attribute to this list of physical attributes
//
-SH_IMPORT_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count);
+GLSLANG_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count);
//
// Returns the location ID of the named uniform.
// Returns -1 if error.
//
-SH_IMPORT_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name);
+GLSLANG_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name);
#ifdef __cplusplus
} // end extern "C"
@@ -390,19 +399,19 @@
namespace glslang {
-const char* GetEsslVersionString();
-const char* GetGlslVersionString();
-int GetKhronosToolId();
+GLSLANG_EXPORT const char* GetEsslVersionString();
+GLSLANG_EXPORT const char* GetGlslVersionString();
+GLSLANG_EXPORT int GetKhronosToolId();
class TIntermediate;
class TProgram;
class TPoolAllocator;
// Call this exactly once per process before using anything else
-bool InitializeProcess();
+GLSLANG_EXPORT bool InitializeProcess();
// Call once per process to tear down everything
-void FinalizeProcess();
+GLSLANG_EXPORT void FinalizeProcess();
// Resource type for IO resolver
enum TResourceType {
@@ -435,40 +444,41 @@
//
class TShader {
public:
- explicit TShader(EShLanguage);
- virtual ~TShader();
- void setStrings(const char* const* s, int n);
- void setStringsWithLengths(const char* const* s, const int* l, int n);
- void setStringsWithLengthsAndNames(
+ GLSLANG_EXPORT explicit TShader(EShLanguage);
+ GLSLANG_EXPORT virtual ~TShader();
+ GLSLANG_EXPORT void setStrings(const char* const* s, int n);
+ GLSLANG_EXPORT void setStringsWithLengths(
+ const char* const* s, const int* l, int n);
+ GLSLANG_EXPORT void setStringsWithLengthsAndNames(
const char* const* s, const int* l, const char* const* names, int n);
void setPreamble(const char* s) { preamble = s; }
- void setEntryPoint(const char* entryPoint);
- void setSourceEntryPoint(const char* sourceEntryPointName);
- void addProcesses(const std::vector<std::string>&);
+ GLSLANG_EXPORT void setEntryPoint(const char* entryPoint);
+ GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName);
+ GLSLANG_EXPORT void addProcesses(const std::vector<std::string>&);
// IO resolver binding data: see comments in ShaderLang.cpp
- void setShiftBinding(TResourceType res, unsigned int base);
- void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding
- void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding
- void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding
- void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
- void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding
- void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
- void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
- void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set);
- void setResourceSetBinding(const std::vector<std::string>& base);
- void setAutoMapBindings(bool map);
- void setAutoMapLocations(bool map);
- void addUniformLocationOverride(const char* name, int loc);
- void setUniformLocationBase(int base);
- void setInvertY(bool invert);
+ GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base);
+ GLSLANG_EXPORT void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ GLSLANG_EXPORT void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ GLSLANG_EXPORT void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ GLSLANG_EXPORT void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ GLSLANG_EXPORT void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ GLSLANG_EXPORT void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
+ GLSLANG_EXPORT void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
+ GLSLANG_EXPORT void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set);
+ GLSLANG_EXPORT void setResourceSetBinding(const std::vector<std::string>& base);
+ GLSLANG_EXPORT void setAutoMapBindings(bool map);
+ GLSLANG_EXPORT void setAutoMapLocations(bool map);
+ GLSLANG_EXPORT void addUniformLocationOverride(const char* name, int loc);
+ GLSLANG_EXPORT void setUniformLocationBase(int base);
+ GLSLANG_EXPORT void setInvertY(bool invert);
#ifdef ENABLE_HLSL
- void setHlslIoMapping(bool hlslIoMap);
- void setFlattenUniformArrays(bool flatten);
+ GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap);
+ GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten);
#endif
- void setNoStorageFormat(bool useUnknownFormat);
- void setNanMinMaxClamp(bool nanMinMaxClamp);
- void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
+ GLSLANG_EXPORT void setNoStorageFormat(bool useUnknownFormat);
+ GLSLANG_EXPORT void setNanMinMaxClamp(bool nanMinMaxClamp);
+ GLSLANG_EXPORT void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
// For setting up the environment (cleared to nothingness in the constructor).
// These must be called so that parsing is done for the right source language and
@@ -608,8 +618,10 @@
virtual void releaseInclude(IncludeResult*) override { }
};
- bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
- bool forwardCompatible, EShMessages, Includer&);
+ GLSLANG_EXPORT bool parse(
+ const TBuiltInResource*, int defaultVersion, EProfile defaultProfile,
+ bool forceDefaultVersionAndProfile, bool forwardCompatible,
+ EShMessages, Includer&);
bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
bool forwardCompatible, EShMessages messages)
@@ -632,13 +644,14 @@
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
// is not an officially supported or fully working path.
- bool preprocess(const TBuiltInResource* builtInResources,
- int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
- bool forwardCompatible, EShMessages message, std::string* outputString,
- Includer& includer);
+ GLSLANG_EXPORT bool preprocess(
+ const TBuiltInResource* builtInResources, int defaultVersion,
+ EProfile defaultProfile, bool forceDefaultVersionAndProfile,
+ bool forwardCompatible, EShMessages message, std::string* outputString,
+ Includer& includer);
- const char* getInfoLog();
- const char* getInfoDebugLog();
+ GLSLANG_EXPORT const char* getInfoLog();
+ GLSLANG_EXPORT const char* getInfoDebugLog();
EShLanguage getStage() const { return stage; }
TIntermediate* getIntermediate() const { return intermediate; }
@@ -683,11 +696,11 @@
// Data needed for just a single object at the granularity exchanged by the reflection API
class TObjectReflection {
public:
- TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex);
+ GLSLANG_EXPORT TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex);
- const TType* getType() const { return type; }
- int getBinding() const;
- void dump() const;
+ GLSLANG_EXPORT const TType* getType() const { return type; }
+ GLSLANG_EXPORT int getBinding() const;
+ GLSLANG_EXPORT void dump() const;
static TObjectReflection badReflection() { return TObjectReflection(); }
std::string name;
@@ -802,14 +815,14 @@
//
class TProgram {
public:
- TProgram();
- virtual ~TProgram();
+ GLSLANG_EXPORT TProgram();
+ GLSLANG_EXPORT virtual ~TProgram();
void addShader(TShader* shader) { stages[shader->stage].push_back(shader); }
std::list<TShader*>& getShaders(EShLanguage stage) { return stages[stage]; }
// Link Validation interface
- bool link(EShMessages);
- const char* getInfoLog();
- const char* getInfoDebugLog();
+ GLSLANG_EXPORT bool link(EShMessages);
+ GLSLANG_EXPORT const char* getInfoLog();
+ GLSLANG_EXPORT const char* getInfoDebugLog();
TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
@@ -818,24 +831,24 @@
// Reflection Interface
// call first, to do liveness analysis, index mapping, etc.; returns false on failure
- bool buildReflection(int opts = EShReflectionDefault);
- unsigned getLocalSize(int dim) const; // return dim'th local size
- int getReflectionIndex(const char *name) const;
- int getReflectionPipeIOIndex(const char* name, const bool inOrOut) const;
- int getNumUniformVariables() const;
- const TObjectReflection& getUniform(int index) const;
- int getNumUniformBlocks() const;
- const TObjectReflection& getUniformBlock(int index) const;
- int getNumPipeInputs() const;
- const TObjectReflection& getPipeInput(int index) const;
- int getNumPipeOutputs() const;
- const TObjectReflection& getPipeOutput(int index) const;
- int getNumBufferVariables() const;
- const TObjectReflection& getBufferVariable(int index) const;
- int getNumBufferBlocks() const;
- const TObjectReflection& getBufferBlock(int index) const;
- int getNumAtomicCounters() const;
- const TObjectReflection& getAtomicCounter(int index) const;
+ GLSLANG_EXPORT bool buildReflection(int opts = EShReflectionDefault);
+ GLSLANG_EXPORT unsigned getLocalSize(int dim) const; // return dim'th local size
+ GLSLANG_EXPORT int getReflectionIndex(const char *name) const;
+ GLSLANG_EXPORT int getReflectionPipeIOIndex(const char* name, const bool inOrOut) const;
+ GLSLANG_EXPORT int getNumUniformVariables() const;
+ GLSLANG_EXPORT const TObjectReflection& getUniform(int index) const;
+ GLSLANG_EXPORT int getNumUniformBlocks() const;
+ GLSLANG_EXPORT const TObjectReflection& getUniformBlock(int index) const;
+ GLSLANG_EXPORT int getNumPipeInputs() const;
+ GLSLANG_EXPORT const TObjectReflection& getPipeInput(int index) const;
+ GLSLANG_EXPORT int getNumPipeOutputs() const;
+ GLSLANG_EXPORT const TObjectReflection& getPipeOutput(int index) const;
+ GLSLANG_EXPORT int getNumBufferVariables() const;
+ GLSLANG_EXPORT const TObjectReflection& getBufferVariable(int index) const;
+ GLSLANG_EXPORT int getNumBufferBlocks() const;
+ GLSLANG_EXPORT const TObjectReflection& getBufferBlock(int index) const;
+ GLSLANG_EXPORT int getNumAtomicCounters() const;
+ GLSLANG_EXPORT const TObjectReflection& getAtomicCounter(int index) const;
// Legacy Reflection Interface - expressed in terms of above interface
@@ -902,15 +915,15 @@
// returns a TType*
const TType *getAttributeTType(int index) const { return getPipeInput(index).getType(); }
- void dumpReflection();
+ GLSLANG_EXPORT void dumpReflection();
// I/O mapping: apply base offsets and map live unbound variables
// If resolver is not provided it uses the previous approach
// and respects auto assignment and offsets.
- bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr);
+ GLSLANG_EXPORT bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr);
#endif
protected:
- bool linkStage(EShLanguage, EShMessages);
+ GLSLANG_EXPORT bool linkStage(EShLanguage, EShMessages);
TPoolAllocator* pool;
std::list<TShader*> stages[EShLangCount];