glslang: Only export public interface for SOs
authorBen Clayton <bclayton@google.com>
Mon, 29 Jun 2020 13:20:19 +0000 (14:20 +0100)
committerBen Clayton <bclayton@google.com>
Tue, 30 Jun 2020 16:06:17 +0000 (17:06 +0100)
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

CMakeLists.txt
StandAlone/StandAlone.cpp
glslang/CMakeLists.txt
glslang/Public/ShaderLang.h

index e679228..9c2f861 100644 (file)
@@ -205,6 +205,21 @@ if(BUILD_EXTERNAL AND IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/External)
        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()
index 5e17aff..662b68d 100644 (file)
@@ -63,7 +63,7 @@
 #include "../glslang/OSDependent/osinclude.h"
 
 extern "C" {
-    SH_IMPORT_EXPORT void ShOutputHtml();
+    GLSLANG_EXPORT void ShOutputHtml();
 }
 
 // Command-line options
index 990f442..d707b62 100644 (file)
@@ -132,6 +132,8 @@ target_include_directories(glslang PUBLIC
     $<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()
index d51749b..5b30474 100644 (file)
 #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.
 //
 // (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 @@ struct TEnvironment {
     TTarget target;           // what to generate
 };
 
-const char* StageName(EShLanguage);
+GLSLANG_EXPORT const char* StageName(EShLanguage);
 
 } // end namespace glslang
 
@@ -306,10 +315,10 @@ typedef void* ShHandle;
 // 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 @@ SH_IMPORT_EXPORT void ShDestruct(ShHandle);
 // 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 @@ SH_IMPORT_EXPORT int ShCompile(
     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 @@ SH_IMPORT_EXPORT int ShLinkExt(
 // 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 @@ class TInfoSink;
 
 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 @@ enum TResourceType {
 //
 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 @@ public:
         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 @@ public:
 
     // 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);
-
-    const char* getInfoLog();
-    const char* getInfoDebugLog();
+    GLSLANG_EXPORT bool preprocess(
+        const TBuiltInResource* builtInResources, int defaultVersion,
+        EProfile defaultProfile, bool forceDefaultVersionAndProfile,
+        bool forwardCompatible, EShMessages message, std::string* outputString,
+        Includer& includer);
+
+    GLSLANG_EXPORT const char* getInfoLog();
+    GLSLANG_EXPORT const char* getInfoDebugLog();
     EShLanguage getStage() const { return stage; }
     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
 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 @@ public:
 //
 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 @@ public:
     // 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 @@ public:
     // 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];