From eed112d9eab210ebef69c0ea9c1be074a9eba273 Mon Sep 17 00:00:00 2001
From: Laurent Gomila <laurent.gom@gmail.com>
Date: Sun, 16 Oct 2011 19:30:37 +0200
Subject: [PATCH] SFML shared libraries now use ELF visibility on Unixes with
 gcc >= 4

---
 cmake/Macros.cmake      | 46 ++++++++++++++++++++++++-----------------
 include/SFML/Config.hpp | 46 ++++++++++++++++++++++++++++-------------
 2 files changed, 59 insertions(+), 33 deletions(-)

diff --git a/cmake/Macros.cmake b/cmake/Macros.cmake
index 348c918e..6cb03aaa 100644
--- a/cmake/Macros.cmake
+++ b/cmake/Macros.cmake
@@ -133,29 +133,37 @@ macro(sfml_add_library target)
         endif()
     endif()
 
+    # on Unix systems with gcc 4.x, we must hide public symbols by default
+    # (exported ones are explicitely marked)
+    if((LINUX OR MACOSX) AND COMPILER_GCC)
+        if(${GCC_VERSION} MATCHES "4\\..*")
+            set_target_properties(${target} PROPERTIES COMPILE_FLAGS -fvisibility=hidden)
+        endif()
+    endif()
+
     # link the target to its SFML dependencies
     if(THIS_DEPENDS)
         target_link_libraries(${target} ${THIS_DEPENDS})
     endif()
 
-    # build frameworks or dylibs
-    if(MACOSX AND BUILD_SHARED_LIBS)
-        if(BUILD_FRAMEWORKS)
-            # adapt target to build frameworks instead of dylibs
-            set_target_properties(${target} PROPERTIES 
-                                  FRAMEWORK TRUE
-                                  FRAMEWORK_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
-                                  MACOSX_FRAMEWORK_IDENTIFIER org.sfml-dev.${target}
-                                  MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
-                                  MACOSX_FRAMEWORK_BUNDLE_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
-        endif()
-        
-        # adapt install directory to allow distributing dylibs/frameworks in user’s frameworks/application bundle
-        set_target_properties(${target} PROPERTIES 
-                              BUILD_WITH_INSTALL_RPATH 1 
-                              INSTALL_NAME_DIR "@executable_path/../Frameworks")
-    endif()
-
+    # build frameworks or dylibs
+    if(MACOSX AND BUILD_SHARED_LIBS)
+        if(BUILD_FRAMEWORKS)
+            # adapt target to build frameworks instead of dylibs
+            set_target_properties(${target} PROPERTIES 
+                                  FRAMEWORK TRUE
+                                  FRAMEWORK_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
+                                  MACOSX_FRAMEWORK_IDENTIFIER org.sfml-dev.${target}
+                                  MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
+                                  MACOSX_FRAMEWORK_BUNDLE_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
+        endif()
+        
+        # adapt install directory to allow distributing dylibs/frameworks in user’s frameworks/application bundle
+        set_target_properties(${target} PROPERTIES 
+                              BUILD_WITH_INSTALL_RPATH 1 
+                              INSTALL_NAME_DIR "@executable_path/../Frameworks")
+    endif()
+
     # link the target to its external dependencies
     if(THIS_EXTERNAL_LIBS)
         if(BUILD_SHARED_LIBS)
@@ -172,7 +180,7 @@ macro(sfml_add_library target)
     install(TARGETS ${target}
             RUNTIME DESTINATION bin COMPONENT bin
             LIBRARY DESTINATION lib${LIB_SUFFIX} COMPONENT bin 
-            ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT devel
+            ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT devel
             FRAMEWORK DESTINATION ${CMAKE_INSTALL_FRAMEWORK_PREFIX} COMPONENT bin)
 
 endmacro()
diff --git a/include/SFML/Config.hpp b/include/SFML/Config.hpp
index 92f229cb..677d4096 100644
--- a/include/SFML/Config.hpp
+++ b/include/SFML/Config.hpp
@@ -97,32 +97,50 @@
 ////////////////////////////////////////////////////////////
 // Define portable import / export macros
 ////////////////////////////////////////////////////////////
-#if defined(SFML_SYSTEM_WINDOWS) && !defined(SFML_STATIC)
+#if !defined(SFML_STATIC)
 
-    #ifdef SFML_EXPORTS
+    #if defined(SFML_SYSTEM_WINDOWS)
 
-        // From DLL side, we must export
-        #define SFML_API __declspec(dllexport)
+        #ifdef SFML_EXPORTS
 
-    #else
+            // From DLL side, we must export
+            #define SFML_API __declspec(dllexport)
 
-        // From client application side, we must import
-        #define SFML_API __declspec(dllimport)
+        #else
 
-    #endif
+            // From client application side, we must import
+            #define SFML_API __declspec(dllimport)
 
-    // For Visual C++ compilers, we also need to turn off this annoying C4251 warning.
-    // You can read lots ot different things about it, but the point is the code will
-    // just work fine, and so the simplest way to get rid of this warning is to disable it
-    #ifdef _MSC_VER
+        #endif
 
-        #pragma warning(disable : 4251)
+        // For Visual C++ compilers, we also need to turn off this annoying C4251 warning.
+        // You can read lots ot different things about it, but the point is the code will
+        // just work fine, and so the simplest way to get rid of this warning is to disable it
+        #ifdef _MSC_VER
+
+            #pragma warning(disable : 4251)
+
+        #endif
+
+    #else // Linux, FreeBSD, Mac OS X
+
+        #if __GNUC__ >= 4
+
+            // gcc 4 has special keywords for showing/hidding symbols
+            #define SFML_API __attribute__ ((visibility ("default")))
+
+        #else
+
+            // gcc < 4 has no mechanism to explicitely hide symbols, everything's exported
+            #define SFML_API
+
+        #endif
 
     #endif
 
 #else
 
-    // Other platforms and static build don't need these export macros
+    // Static build doesn't need these export macros
     #define SFML_API
 
 #endif