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
This commit is contained in:
Ben Clayton 2020-06-29 14:20:19 +01:00
parent c858d7bd81
commit d64e859987
4 changed files with 127 additions and 97 deletions

View File

@ -205,6 +205,21 @@ if(BUILD_EXTERNAL AND IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/External)
add_subdirectory(External) add_subdirectory(External)
endif() 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) if(NOT TARGET SPIRV-Tools-opt)
set(ENABLE_OPT OFF) set(ENABLE_OPT OFF)
endif() endif()

View File

@ -63,7 +63,7 @@
#include "../glslang/OSDependent/osinclude.h" #include "../glslang/OSDependent/osinclude.h"
extern "C" { extern "C" {
SH_IMPORT_EXPORT void ShOutputHtml(); GLSLANG_EXPORT void ShOutputHtml();
} }
// Command-line options // Command-line options

View File

@ -132,6 +132,8 @@ target_include_directories(glslang PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>) $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
glslang_only_export_explicit_symbols(glslang)
if(WIN32 AND BUILD_SHARED_LIBS) if(WIN32 AND BUILD_SHARED_LIBS)
set_target_properties(glslang PROPERTIES PREFIX "") set_target_properties(glslang PROPERTIES PREFIX "")
endif() endif()

View File

@ -44,18 +44,27 @@
#include <vector> #include <vector>
#ifdef _WIN32 #ifdef _WIN32
#define C_DECL __cdecl #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
#else #else
#define SH_IMPORT_EXPORT #define C_DECL
#define C_DECL
#endif #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 // This is the platform independent interface between an OGL driver
// and the shading language compiler/linker. // and the shading language compiler/linker.
@ -75,12 +84,12 @@
// //
// (Call once per process, not once per thread.) // (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. // 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. // Types of languages the compiler can consume.
@ -205,7 +214,7 @@ struct TEnvironment {
TTarget target; // what to generate TTarget target; // what to generate
}; };
const char* StageName(EShLanguage); GLSLANG_EXPORT const char* StageName(EShLanguage);
} // end namespace glslang } // end namespace glslang
@ -306,10 +315,10 @@ typedef void* ShHandle;
// Driver calls these to create and destroy compiler/linker // Driver calls these to create and destroy compiler/linker
// objects. // objects.
// //
SH_IMPORT_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader GLSLANG_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader
SH_IMPORT_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair GLSLANG_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair
SH_IMPORT_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object) GLSLANG_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object)
SH_IMPORT_EXPORT void ShDestruct(ShHandle); GLSLANG_EXPORT void ShDestruct(ShHandle);
// //
// The return value of ShCompile is boolean, non-zero indicating // The return value of ShCompile is boolean, non-zero indicating
@ -318,7 +327,7 @@ SH_IMPORT_EXPORT void ShDestruct(ShHandle);
// The info-log should be written by ShCompile into // The info-log should be written by ShCompile into
// ShHandle, so it can answer future queries. // ShHandle, so it can answer future queries.
// //
SH_IMPORT_EXPORT int ShCompile( GLSLANG_EXPORT int ShCompile(
const ShHandle, const ShHandle,
const char* const shaderStrings[], const char* const shaderStrings[],
const int numStrings, const int numStrings,
@ -331,7 +340,7 @@ SH_IMPORT_EXPORT int ShCompile(
EShMessages messages = EShMsgDefault // warnings and errors EShMessages messages = EShMsgDefault // warnings and errors
); );
SH_IMPORT_EXPORT int ShLinkExt( GLSLANG_EXPORT int ShLinkExt(
const ShHandle, // linker object const ShHandle, // linker object
const ShHandle h[], // compiler objects to link together const ShHandle h[], // compiler objects to link together
const int numHandles); const int numHandles);
@ -340,26 +349,26 @@ SH_IMPORT_EXPORT int ShLinkExt(
// ShSetEncrpytionMethod is a place-holder for specifying // ShSetEncrpytionMethod is a place-holder for specifying
// how source code is encrypted. // 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 // All the following return 0 if the information is not
// available in the object passed down, or the object is bad. // available in the object passed down, or the object is bad.
// //
SH_IMPORT_EXPORT const char* ShGetInfoLog(const ShHandle); GLSLANG_EXPORT const char* ShGetInfoLog(const ShHandle);
SH_IMPORT_EXPORT const void* ShGetExecutable(const ShHandle); GLSLANG_EXPORT const void* ShGetExecutable(const ShHandle);
SH_IMPORT_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*); // to detect user aliasing GLSLANG_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 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 // 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 the location ID of the named uniform.
// Returns -1 if error. // 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 #ifdef __cplusplus
} // end extern "C" } // end extern "C"
@ -390,19 +399,19 @@ class TInfoSink;
namespace glslang { namespace glslang {
const char* GetEsslVersionString(); GLSLANG_EXPORT const char* GetEsslVersionString();
const char* GetGlslVersionString(); GLSLANG_EXPORT const char* GetGlslVersionString();
int GetKhronosToolId(); GLSLANG_EXPORT int GetKhronosToolId();
class TIntermediate; class TIntermediate;
class TProgram; class TProgram;
class TPoolAllocator; class TPoolAllocator;
// Call this exactly once per process before using anything else // Call this exactly once per process before using anything else
bool InitializeProcess(); GLSLANG_EXPORT bool InitializeProcess();
// Call once per process to tear down everything // Call once per process to tear down everything
void FinalizeProcess(); GLSLANG_EXPORT void FinalizeProcess();
// Resource type for IO resolver // Resource type for IO resolver
enum TResourceType { enum TResourceType {
@ -435,40 +444,41 @@ enum TResourceType {
// //
class TShader { class TShader {
public: public:
explicit TShader(EShLanguage); GLSLANG_EXPORT explicit TShader(EShLanguage);
virtual ~TShader(); GLSLANG_EXPORT virtual ~TShader();
void setStrings(const char* const* s, int n); GLSLANG_EXPORT void setStrings(const char* const* s, int n);
void setStringsWithLengths(const char* const* s, const int* l, int n); GLSLANG_EXPORT void setStringsWithLengths(
void setStringsWithLengthsAndNames( 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); const char* const* s, const int* l, const char* const* names, int n);
void setPreamble(const char* s) { preamble = s; } void setPreamble(const char* s) { preamble = s; }
void setEntryPoint(const char* entryPoint); GLSLANG_EXPORT void setEntryPoint(const char* entryPoint);
void setSourceEntryPoint(const char* sourceEntryPointName); GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName);
void addProcesses(const std::vector<std::string>&); GLSLANG_EXPORT void addProcesses(const std::vector<std::string>&);
// IO resolver binding data: see comments in ShaderLang.cpp // IO resolver binding data: see comments in ShaderLang.cpp
void setShiftBinding(TResourceType res, unsigned int base); GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base);
void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding GLSLANG_EXPORT void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding
void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding GLSLANG_EXPORT void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding
void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding GLSLANG_EXPORT void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding
void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding GLSLANG_EXPORT void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding GLSLANG_EXPORT void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding
void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding GLSLANG_EXPORT void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding
void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding GLSLANG_EXPORT void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding
void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set); GLSLANG_EXPORT void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set);
void setResourceSetBinding(const std::vector<std::string>& base); GLSLANG_EXPORT void setResourceSetBinding(const std::vector<std::string>& base);
void setAutoMapBindings(bool map); GLSLANG_EXPORT void setAutoMapBindings(bool map);
void setAutoMapLocations(bool map); GLSLANG_EXPORT void setAutoMapLocations(bool map);
void addUniformLocationOverride(const char* name, int loc); GLSLANG_EXPORT void addUniformLocationOverride(const char* name, int loc);
void setUniformLocationBase(int base); GLSLANG_EXPORT void setUniformLocationBase(int base);
void setInvertY(bool invert); GLSLANG_EXPORT void setInvertY(bool invert);
#ifdef ENABLE_HLSL #ifdef ENABLE_HLSL
void setHlslIoMapping(bool hlslIoMap); GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap);
void setFlattenUniformArrays(bool flatten); GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten);
#endif #endif
void setNoStorageFormat(bool useUnknownFormat); GLSLANG_EXPORT void setNoStorageFormat(bool useUnknownFormat);
void setNanMinMaxClamp(bool nanMinMaxClamp); GLSLANG_EXPORT void setNanMinMaxClamp(bool nanMinMaxClamp);
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode); GLSLANG_EXPORT void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
// For setting up the environment (cleared to nothingness in the constructor). // 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 // These must be called so that parsing is done for the right source language and
@ -608,8 +618,10 @@ public:
virtual void releaseInclude(IncludeResult*) override { } virtual void releaseInclude(IncludeResult*) override { }
}; };
bool parse(const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, GLSLANG_EXPORT bool parse(
bool forwardCompatible, EShMessages, Includer&); const TBuiltInResource*, int defaultVersion, EProfile defaultProfile,
bool forceDefaultVersionAndProfile, bool forwardCompatible,
EShMessages, Includer&);
bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
bool forwardCompatible, EShMessages messages) bool forwardCompatible, EShMessages messages)
@ -632,13 +644,14 @@ public:
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string // NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
// is not an officially supported or fully working path. // is not an officially supported or fully working path.
bool preprocess(const TBuiltInResource* builtInResources, GLSLANG_EXPORT bool preprocess(
int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, const TBuiltInResource* builtInResources, int defaultVersion,
bool forwardCompatible, EShMessages message, std::string* outputString, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
Includer& includer); bool forwardCompatible, EShMessages message, std::string* outputString,
Includer& includer);
const char* getInfoLog(); GLSLANG_EXPORT const char* getInfoLog();
const char* getInfoDebugLog(); GLSLANG_EXPORT const char* getInfoDebugLog();
EShLanguage getStage() const { return stage; } EShLanguage getStage() const { return stage; }
TIntermediate* getIntermediate() const { return intermediate; } TIntermediate* getIntermediate() const { return intermediate; }
@ -683,11 +696,11 @@ private:
// Data needed for just a single object at the granularity exchanged by the reflection API // Data needed for just a single object at the granularity exchanged by the reflection API
class TObjectReflection { class TObjectReflection {
public: 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; } GLSLANG_EXPORT const TType* getType() const { return type; }
int getBinding() const; GLSLANG_EXPORT int getBinding() const;
void dump() const; GLSLANG_EXPORT void dump() const;
static TObjectReflection badReflection() { return TObjectReflection(); } static TObjectReflection badReflection() { return TObjectReflection(); }
std::string name; std::string name;
@ -802,14 +815,14 @@ public:
// //
class TProgram { class TProgram {
public: public:
TProgram(); GLSLANG_EXPORT TProgram();
virtual ~TProgram(); GLSLANG_EXPORT virtual ~TProgram();
void addShader(TShader* shader) { stages[shader->stage].push_back(shader); } void addShader(TShader* shader) { stages[shader->stage].push_back(shader); }
std::list<TShader*>& getShaders(EShLanguage stage) { return stages[stage]; } std::list<TShader*>& getShaders(EShLanguage stage) { return stages[stage]; }
// Link Validation interface // Link Validation interface
bool link(EShMessages); GLSLANG_EXPORT bool link(EShMessages);
const char* getInfoLog(); GLSLANG_EXPORT const char* getInfoLog();
const char* getInfoDebugLog(); GLSLANG_EXPORT const char* getInfoDebugLog();
TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; } TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
@ -818,24 +831,24 @@ public:
// Reflection Interface // Reflection Interface
// call first, to do liveness analysis, index mapping, etc.; returns false on failure // call first, to do liveness analysis, index mapping, etc.; returns false on failure
bool buildReflection(int opts = EShReflectionDefault); GLSLANG_EXPORT bool buildReflection(int opts = EShReflectionDefault);
unsigned getLocalSize(int dim) const; // return dim'th local size GLSLANG_EXPORT unsigned getLocalSize(int dim) const; // return dim'th local size
int getReflectionIndex(const char *name) const; GLSLANG_EXPORT int getReflectionIndex(const char *name) const;
int getReflectionPipeIOIndex(const char* name, const bool inOrOut) const; GLSLANG_EXPORT int getReflectionPipeIOIndex(const char* name, const bool inOrOut) const;
int getNumUniformVariables() const; GLSLANG_EXPORT int getNumUniformVariables() const;
const TObjectReflection& getUniform(int index) const; GLSLANG_EXPORT const TObjectReflection& getUniform(int index) const;
int getNumUniformBlocks() const; GLSLANG_EXPORT int getNumUniformBlocks() const;
const TObjectReflection& getUniformBlock(int index) const; GLSLANG_EXPORT const TObjectReflection& getUniformBlock(int index) const;
int getNumPipeInputs() const; GLSLANG_EXPORT int getNumPipeInputs() const;
const TObjectReflection& getPipeInput(int index) const; GLSLANG_EXPORT const TObjectReflection& getPipeInput(int index) const;
int getNumPipeOutputs() const; GLSLANG_EXPORT int getNumPipeOutputs() const;
const TObjectReflection& getPipeOutput(int index) const; GLSLANG_EXPORT const TObjectReflection& getPipeOutput(int index) const;
int getNumBufferVariables() const; GLSLANG_EXPORT int getNumBufferVariables() const;
const TObjectReflection& getBufferVariable(int index) const; GLSLANG_EXPORT const TObjectReflection& getBufferVariable(int index) const;
int getNumBufferBlocks() const; GLSLANG_EXPORT int getNumBufferBlocks() const;
const TObjectReflection& getBufferBlock(int index) const; GLSLANG_EXPORT const TObjectReflection& getBufferBlock(int index) const;
int getNumAtomicCounters() const; GLSLANG_EXPORT int getNumAtomicCounters() const;
const TObjectReflection& getAtomicCounter(int index) const; GLSLANG_EXPORT const TObjectReflection& getAtomicCounter(int index) const;
// Legacy Reflection Interface - expressed in terms of above interface // Legacy Reflection Interface - expressed in terms of above interface
@ -902,15 +915,15 @@ public:
// returns a TType* // returns a TType*
const TType *getAttributeTType(int index) const { return getPipeInput(index).getType(); } 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 // I/O mapping: apply base offsets and map live unbound variables
// If resolver is not provided it uses the previous approach // If resolver is not provided it uses the previous approach
// and respects auto assignment and offsets. // 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 #endif
protected: protected:
bool linkStage(EShLanguage, EShMessages); GLSLANG_EXPORT bool linkStage(EShLanguage, EShMessages);
TPoolAllocator* pool; TPoolAllocator* pool;
std::list<TShader*> stages[EShLangCount]; std::list<TShader*> stages[EShLangCount];