Prechádzať zdrojové kódy

Hide unneeded internal symbols when building raylib as an so or dylib (#3573)

Peter0x44 1 rok pred
rodič
commit
e7a486fa81
7 zmenil súbory, kde vykonal 47 pridanie a 24 odobranie
  1. 6 1
      CMakeLists.txt
  2. 5 5
      cmake/GlfwImport.cmake
  3. 9 6
      src/CMakeLists.txt
  4. 6 0
      src/Makefile
  5. 9 4
      src/raylib.h
  6. 3 1
      src/raymath.h
  7. 9 7
      src/rlgl.h

+ 6 - 1
CMakeLists.txt

@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
 project(raylib)
 
 # Avoid excessive expansion of variables in conditionals. In particular, if
-# "PLATFORM" is "DRM" than:
+# "PLATFORM" is "DRM" then:
 #
 # if (${PLATFORM} MATCHES "DRM")
 #
@@ -13,6 +13,11 @@ project(raylib)
 # See https://cmake.org/cmake/help/latest/policy/CMP0054.html
 cmake_policy(SET CMP0054 NEW)
 
+# Makes a hidden visibility preset on a static lib respected
+# This is used to hide glfw's symbols from the library exports when building an so/dylib
+# See https://cmake.org/cmake/help/latest/policy/CMP0063.html
+cmake_policy(SET CMP0063 NEW)
+
 # Directory for easier includes
 # Anywhere you see include(...) you can check <root>/cmake for that file
 set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

+ 5 - 5
cmake/GlfwImport.cmake

@@ -17,16 +17,16 @@ if(NOT glfw3_FOUND AND NOT USE_EXTERNAL_GLFW STREQUAL "ON" AND "${PLATFORM}" MAT
     set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
     set(GLFW_INSTALL OFF CACHE BOOL "" FORCE)
     set(GLFW_USE_WAYLAND ${USE_WAYLAND} CACHE BOOL "" FORCE)
+    set(GLFW_LIBRARY_TYPE "STATIC" CACHE STRING "" FORCE)
     
-    set(WAS_SHARED ${BUILD_SHARED_LIBS})
-    set(BUILD_SHARED_LIBS OFF CACHE BOOL " " FORCE)
 
     add_subdirectory(external/glfw)
 
-    set(BUILD_SHARED_LIBS ${WAS_SHARED} CACHE BOOL " " FORCE)
-    unset(WAS_SHARED)
+    # Hide glfw's symbols when building a shared lib
+    if (BUILD_SHARED_LIBS)
+        set_property(TARGET glfw PROPERTY C_VISIBILITY_PRESET hidden)
+    endif()
     
-    list(APPEND raylib_sources $<TARGET_OBJECTS:glfw>)
     include_directories(BEFORE SYSTEM external/glfw/include)
 elseif("${PLATFORM}" STREQUAL "DRM")
     MESSAGE(STATUS "No GLFW required on PLATFORM_DRM")

+ 9 - 6
src/CMakeLists.txt

@@ -62,12 +62,10 @@ if (NOT BUILD_SHARED_LIBS)
     add_library(raylib_static ALIAS raylib)
 else()
     MESSAGE(STATUS "Building raylib shared library")
-    if (WIN32)
-        target_compile_definitions(raylib
-                                   PRIVATE $<BUILD_INTERFACE:BUILD_LIBTYPE_SHARED>
-                                   INTERFACE $<INSTALL_INTERFACE:USE_LIBTYPE_SHARED>
-                                   )
-    endif ()
+    target_compile_definitions(raylib
+                               PRIVATE $<BUILD_INTERFACE:BUILD_LIBTYPE_SHARED>
+                               INTERFACE $<INSTALL_INTERFACE:USE_LIBTYPE_SHARED>
+                               )
 endif()
 
 if (${PLATFORM} MATCHES "Web")
@@ -84,6 +82,11 @@ if (WITH_PIC OR BUILD_SHARED_LIBS)
     set_property(TARGET raylib PROPERTY POSITION_INDEPENDENT_CODE ON)
 endif ()
 
+if (BUILD_SHARED_LIBS)
+    # Hide raylib's symbols by default so RLAPI can expose them
+    set_property(TARGET raylib PROPERTY C_VISIBILITY_PRESET hidden)
+endif ()
+
 target_link_libraries(raylib "${LIBS_PRIVATE}")
 
 # Sets some compile time definitions for the pre-processor

+ 6 - 0
src/Makefile

@@ -389,7 +389,13 @@ ifeq ($(RAYLIB_LIBTYPE),SHARED)
     # BE CAREFUL: It seems that for gcc -fpic is not the same as -fPIC
     # MinGW32 just doesn't need -fPIC, it shows warnings
     CFLAGS += -fPIC -DBUILD_LIBTYPE_SHARED
+
+    # hide all symbols by default, so RLAPI can expose them
+    ifeq ($(PLATFORM_OS),$(filter $(PLATFORM_OS), LINUX BSD OSX))
+        CFLAGS += -fvisibility=hidden
+    endif
 endif
+
 ifeq ($(PLATFORM),PLATFORM_DRM)
     # without EGL_NO_X11 eglplatform.h tears Xlib.h in which tears X.h in
     # which contains a conflicting type Font

+ 9 - 4
src/raylib.h

@@ -86,17 +86,22 @@
 #define RAYLIB_VERSION_PATCH 0
 #define RAYLIB_VERSION  "5.1-dev"
 
-// Function specifiers in case library is build/used as a shared library (Windows)
+// Function specifiers in case library is build/used as a shared library
 // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
+// NOTE: visibility("default") attribute makes symbols "visible" when compiled with -fvisibility=hidden
 #if defined(_WIN32)
+    #if defined(__TINYC__)
+        #define __declspec(x) __attribute__((x))
+    #endif
     #if defined(BUILD_LIBTYPE_SHARED)
-        #if defined(__TINYC__)
-            #define __declspec(x) __attribute__((x))
-        #endif
         #define RLAPI __declspec(dllexport)     // We are building the library as a Win32 shared library (.dll)
     #elif defined(USE_LIBTYPE_SHARED)
         #define RLAPI __declspec(dllimport)     // We are using the library as a Win32 shared library (.dll)
     #endif
+#else
+    #if defined(BUILD_LIBTYPE_SHARED)
+        #define RLAPI __attribute__((visibility("default"))) // We are building as a Unix shared library (.so/.dylib)
+    #endif
 #endif
 
 #ifndef RLAPI

+ 3 - 1
src/raymath.h

@@ -59,7 +59,9 @@
 // Function specifiers definition
 #if defined(RAYMATH_IMPLEMENTATION)
     #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED)
-        #define RMAPI __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll).
+        #define RMAPI __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll)
+    #elif defined(BUILD_LIBTYPE_SHARED)
+        #define RMAPI __attribute__((visibility("default"))) // We are building raylib as a Unix shared library (.so/.dylib)
     #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
         #define RMAPI __declspec(dllimport)         // We are using raylib as a Win32 shared library (.dll)
     #else

+ 9 - 7
src/rlgl.h

@@ -109,16 +109,18 @@
 
 #define RLGL_VERSION  "4.5"
 
-// Function specifiers in case library is build/used as a shared library (Windows)
+// Function specifiers in case library is build/used as a shared library
 // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
-#if defined(_WIN32)
-    #if defined(BUILD_LIBTYPE_SHARED)
-        #define RLAPI __declspec(dllexport)     // We are building the library as a Win32 shared library (.dll)
-    #elif defined(USE_LIBTYPE_SHARED)
-        #define RLAPI __declspec(dllimport)     // We are using the library as a Win32 shared library (.dll)
-    #endif
+// NOTE: visibility(default) attribute makes symbols "visible" when compiled with -fvisibility=hidden
+#if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED)
+    #define RLAPI __declspec(dllexport)     // We are building the library as a Win32 shared library (.dll)
+#elif defined(BUILD_LIBTYPE_SHARED)
+    #define RLAPI __attribute__((visibility("default"))) // We are building he library as a Unix shared library (.so/.dylib)
+#elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
+    #define RLAPI __declspec(dllimport)     // We are using the library as a Win32 shared library (.dll)
 #endif
 
+
 // Function specifiers definition
 #ifndef RLAPI
     #define RLAPI       // Functions defined as 'extern' by default (implicit specifiers)