Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Cleanup library symbol visibility issues.

* On gcc-based systems, use __attribute__((visibility("hidden|default")))
  (in export.h) to clearly mark which symbols must be visible as part of
  the public API (or that must be found by dlsym() in order for LLVM to
  correctly generate code to call them from shaders), versus symbols
  used only internally to the library that don't need to be visible to
  apps linking OSL libraries.  Note that Windows already did this for DLLs.

* For Unix-like systems, if the CMake variable HIDE_SYMBOLS is on (or
  'make HIDE_SYMBOLS=1'), then use -fvisibility=hidden on the compile & link
  lines to control symbol visibility so that the default is to hide symbols
  not marked as part of the public APIs.  (Note: Windows does this by
  default.)  Even if HIDE_SYBOLS=1, the symbols are not hidden for DEBUG
  builds, so that all the symbols are available.

* Add Makefile/CMake option LLVM_STATIC to use static LLVM libs rather than
  dynamic library.

* On Linux, when LLVM_STATIC is used, also use linker option --version-script
  and a custom version-script for liboslexec.so in order to force LLVM's
  symbols to also remain hidden outside the OSL library.  This is extremely
  helpful to apps that want to embed OSL but also embed LLVM for other reasons
  (and not necessarily the same version of LLVM) -- this makes sure the
  symbols don't crash when the program runs, leading to strange crashes.
  • Loading branch information...
commit 71963521a7af5b8a25968ebc4522946e27f3b034 1 parent ca48e4a
@lgritz lgritz authored
View
10 Makefile
@@ -59,10 +59,18 @@ ifneq (${LLVM_NAMESPACE},)
MY_CMAKE_FLAGS += -DLLVM_NAMESPACE:STRING=${LLVM_NAMESPACE}
endif
+ifneq (${LLVM_STATIC},)
+MY_CMAKE_FLAGS += -DLLVM_STATIC:BOOL=${LLVM_STATIC}
+endif
+
ifneq (${NAMESPACE},)
MY_CMAKE_FLAGS += -DOSL_NAMESPACE:STRING=${NAMESPACE}
endif
+ifneq (${HIDE_SYMBOLS},)
+MY_CMAKE_FLAGS += -DHIDE_SYMBOLS:BOOL=${HIDE_SYMBOLS}
+endif
+
ifneq (${USE_BOOST_WAVE},)
MY_CMAKE_FLAGS += -DUSE_BOOST_WAVE:BOOL=${USE_BOOST_WAVE}
endif
@@ -205,6 +213,8 @@ help:
@echo " make LLVM_VERSION=2.9 ... Specify which LLVM version to use"
@echo " make LLVM_DIRECTORY=xx ... Specify where LLVM lives"
@echo " make LLVM_NAMESPACE=xx ... Specify custom LLVM namespace"
+ @echo " make LLVM_STATIC=1 Use static LLVM libraries"
@echo " make NAMESPACE=name Wrap OSL APIs in another namespace"
+ @echo " make HIDE_SYMBOLS=1 Hide symbols not in the public API"
@echo " make USE_BOOST_WAVE=1 Use Boost 'wave' insted of cpp"
@echo ""
View
2  site/spi/Makefile-bits
@@ -28,6 +28,8 @@ ifeq ($(SP_ARCH), spinux1_x86_64)
-DOPENEXR_CUSTOM=1 \
-DOPENEXR_CUSTOM_LIBRARY="SpiIlmImf" \
-DLLVM_CUSTOM=1 \
+ -DLLVM_STATIC=1 \
+ -DEXTRA_OSLEXEC_LIBRARIES="/usr/lib64/libpthread.so" \
-DLLVM_VERSION=${LLVM_VERSION} \
-DLLVM_DIRECTORY=${LLVM_DIRECTORY}
ifeq (${COMPILER}, clang)
View
24 src/CMakeLists.txt
@@ -22,6 +22,11 @@ endif ()
if (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE "Release")
endif ()
+if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+ add_definitions ("-DDEBUG=1")
+ set (DEBUGMODE ON)
+endif ()
+
# Figure out which compiler we're using
if (CMAKE_COMPILER_IS_GNUCC)
@@ -63,12 +68,27 @@ if (CMAKE_COMPILER_IS_CLANG OR CMAKE_COMPILER_IS_GNUCC)
set (CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem ")
endif ()
+if (CMAKE_COMPILER_IS_CLANG OR CMAKE_COMPILER_IS_GNUCC)
+ if (HIDE_SYMBOLS AND NOT DEBUGMODE)
+ # Turn default symbol visibility to hidden
+ set (VISIBILITY_COMMAND "-fvisibility=hidden")
+ add_definitions (${VISIBILITY_COMMAND})
+ endif ()
+ if (LLVM_STATIC AND ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND NOT DEBUGMODE)
+ # Linux: When linking against LLVM statically, we can also hide
+ # all its symbols to prevent clashes if OSL is linked against an
+ # app that also embeds LLVM.
+ set (VISIBILITY_MAP_COMMAND "-Wl,--version-script=${PROJECT_SOURCE_DIR}/liboslexec/liboslexec.map")
+ endif ()
+endif ()
+
set (USE_TBB ON CACHE BOOL "Use TBB if needed")
if (WIN32)
set (USE_BOOST_WAVE ON CACHE BOOL "Use Boost Wave as preprocessor")
else ()
set (USE_BOOST_WAVE OFF CACHE BOOL "Use Boost Wave as preprocessor")
endif ()
+set (HIDE_SYMBOLS OFF CACHE BOOL "Hide symbols not in the public API")
if (LLVM_NAMESPACE)
add_definitions ("-DLLVM_NAMESPACE=${LLVM_NAMESPACE}")
@@ -93,10 +113,6 @@ include_directories (
include_directories ("include")
-if (CMAKE_BUILD_TYPE STREQUAL "Debug")
- add_definitions ("-DDEBUG=1")
-endif ()
-
if (OSL_NAMESPACE)
add_definitions ("-DOSL_NAMESPACE=${OSL_NAMESPACE}")
endif ()
View
15 src/cmake/externalpackages.cmake
@@ -276,6 +276,21 @@ if (LLVM_LIBRARY AND LLVM_INCLUDES AND LLVM_DIRECTORY AND LLVM_LIB_DIR)
string (REGEX REPLACE "\\." "" OSL_LLVM_VERSION ${LLVM_VERSION})
message (STATUS "LLVM OSL_LLVM_VERSION = ${OSL_LLVM_VERSION}")
add_definitions ("-DOSL_LLVM_VERSION=${OSL_LLVM_VERSION}")
+ if (LLVM_STATIC)
+ # if static LLVM libraries were requested, use llvm-config to generate
+ # the list of what libraries we need, and substitute that in the right
+ # way for LLVM_LIBRARY.
+ set (LLVM_LIBRARY "")
+ execute_process (COMMAND ${LLVM_CONFIG} --libs
+ OUTPUT_VARIABLE llvm_library_list
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ string (REPLACE "-l" "" llvm_library_list ${llvm_library_list})
+ string (REPLACE " " ";" llvm_library_list ${llvm_library_list})
+ foreach (f ${llvm_library_list})
+ list (APPEND LLVM_LIBRARY "${LLVM_LIB_DIR}/lib${f}.a")
+ endforeach ()
+ endif ()
+ message (STATUS "LLVM library = ${LLVM_LIBRARY}")
else ()
message (FATAL_ERROR "LLVM not found.")
endif ()
View
81 src/include/export.h
@@ -49,58 +49,57 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/// dilemma since the same header file is used by both the library and
/// its clients. Sheesh!
///
-/// We solve this awful mess by defining these macros:
-///
-/// OSLPUBLIC - normally, assumes that it's being seen by a client
-/// of the library, and therefore declare as 'imported'.
-/// But if OSL_EXPORT_PUBLIC is defined, change the declaration
-/// to 'exported' -- you want to define this macro when
-/// compiling the module that actually defines the class.
+/// But on Linux/OSX as well, we want to only have the DSO export the
+/// symbols we designate as the public interface. So we link with
+/// -fvisibility=hidden to default to hiding the symbols. See
+/// http://gcc.gnu.org/wiki/Visibility
///
-/// Note that on Linux, all symbols are exported so this just isn't a
-/// problem, so we define these macros to be nothing.
+/// We solve this awful mess by defining these macros:
///
-/// It's a shame that we have to clutter all our header files with these
-/// stupid macros just because the Windows world is such a mess.
+/// OSL*PUBLIC - normally, assumes that it's being seen by a client
+/// of the library, and therefore declare as 'imported'.
+/// But if OSL_EXPORT_PUBLIC is defined, change the declaration
+/// to 'exported' -- you want to define this macro when
+/// compiling the module that actually defines the class.
///
/// There is a separate define for each library, because there inter-
/// dependencies, and so what is exported for one may be imported for
/// another.
-#ifndef OSLCOMPPUBLIC
-# if defined(_MSC_VER) && defined(_WIN32)
-# if defined(oslcomp_EXPORTS)
-# define OSLCOMPPUBLIC __declspec(dllexport)
-# else
-# define OSLCOMPPUBLIC __declspec(dllimport)
-# endif
-# else
-# define OSLCOMPPUBLIC
-# endif
+#if defined(_MSC_VER) || defined(__CYGWIN__)
+ #define OSL_DLL_IMPORT __declspec(dllimport)
+ #define OSL_DLL_EXPORT __declspec(dllexport)
+ #define OSL_DLL_LOCAL
+#else
+ #if __GNUC__ >= 4
+ #define OSL_DLL_IMPORT __attribute__ ((visibility ("default")))
+ #define OSL_DLL_EXPORT __attribute__ ((visibility ("default")))
+ #define OSL_DLL_LOCAL __attribute__ ((visibility ("hidden")))
+ #else
+ #define OSL_DLL_IMPORT
+ #define OSL_DLL_EXPORT
+ #define OSL_DLL_LOCAL
+ #endif
+#endif
+
+
+
+#if defined(oslcomp_EXPORTS)
+# define OSLCOMPPUBLIC OSL_DLL_EXPORT
+#else
+# define OSLCOMPPUBLIC OSL_DLL_IMPORT
#endif
-#ifndef OSLEXECPUBLIC
-# if defined(_MSC_VER) && defined(_WIN32)
-# if defined(oslexec_EXPORTS)
-# define OSLEXECPUBLIC __declspec(dllexport)
-# else
-# define OSLEXECPUBLIC __declspec(dllimport)
-# endif
-# else
-# define OSLEXECPUBLIC
-# endif
+#if defined(oslexec_EXPORTS)
+# define OSLEXECPUBLIC OSL_DLL_EXPORT
+#else
+# define OSLEXECPUBLIC OSL_DLL_IMPORT
#endif
-#ifndef OSLQUERYPUBLIC
-# if defined(_MSC_VER) && defined(_WIN32)
-# if defined(oslquery_EXPORTS)
-# define OSLQUERYPUBLIC __declspec(dllexport)
-# else
-# define OSLQUERYPUBLIC __declspec(dllimport)
-# endif
-# else
-# define OSLQUERYPUBLIC
-# endif
+#if defined(oslquery_EXPORTS)
+# define OSLQUERYPUBLIC OSL_DLL_EXPORT
+#else
+# define OSLQUERYPUBLIC OSL_DLL_IMPORT
#endif
#endif // OSL_EXPORT_H
View
6 src/include/oslquery.h
@@ -78,13 +78,13 @@ class OSLQUERYPUBLIC OSLQuery {
{ }
};
- OSLQuery ();
- ~OSLQuery ();
+ OSLQUERYPUBLIC OSLQuery ();
+ OSLQUERYPUBLIC ~OSLQuery ();
/// Get info on the named shader with optional searcphath. Return
/// true for success, false if the shader could not be found or
/// opened properly.
- bool open (const std::string &shadername,
+ OSLQUERYPUBLIC bool open (const std::string &shadername,
const std::string &searchpath=std::string());
/// Return the shader type: "surface", "displacement", "volume",
View
1  src/liboslcomp/ast.cpp
@@ -34,7 +34,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "osl_pvt.h"
#include "oslcomp_pvt.h"
-#include "ast.h"
#include "OpenImageIO/dassert.h"
#include "OpenImageIO/strutil.h"
View
2  src/liboslcomp/codegen.cpp
@@ -33,8 +33,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/foreach.hpp>
#include "oslcomp_pvt.h"
-#include "symtab.h"
-#include "ast.h"
#include "OpenImageIO/dassert.h"
#include "OpenImageIO/strutil.h"
View
4 src/liboslcomp/oslgram.y
@@ -42,8 +42,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include "oslcomp_pvt.h"
-#include "ast.h"
-#include "symtab.h"
#undef yylex
#define yyFlexLexer oslFlexLexer
@@ -949,7 +947,7 @@ yyerror (const char *err)
// Convert from the lexer's symbolic type (COLORTYPE, etc.) to a TypeDesc.
-TypeDesc
+inline TypeDesc
OSL::pvt::lextype (int lex)
{
switch (lex) {
View
1  src/liboslcomp/osllex.l
@@ -93,6 +93,7 @@ CPLUSCOMMENT \/\/.*\n
#include <string>
#include "oslcomp_pvt.h"
+
using namespace OSL;
using namespace OSL::pvt;
View
1  src/liboslcomp/symtab.cpp
@@ -30,7 +30,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include "oslcomp_pvt.h"
-#include "ast.h"
#include "OpenImageIO/strutil.h"
#include "OpenImageIO/dassert.h"
View
1  src/liboslcomp/typecheck.cpp
@@ -30,7 +30,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include "oslcomp_pvt.h"
-#include "ast.h"
#include "OpenImageIO/dassert.h"
#include "OpenImageIO/strutil.h"
View
14 src/liboslexec/CMakeLists.txt
@@ -22,9 +22,12 @@ SET ( liboslexec_srcs
../liboslcomp/typecheck.cpp
)
-FILE ( GLOB compiler_headers "*.h" )
-FLEX_BISON ( osolex.l osogram.y oso liboslexec_srcs compiler_headers )
+include_directories ( ${CMAKE_SOURCE_DIR}/liboslcomp )
+
+FILE ( GLOB exec_headers "*.h" )
+
+FLEX_BISON ( osolex.l osogram.y oso liboslexec_srcs exec_headers )
SET ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS" )
@@ -94,9 +97,12 @@ else ()
endif ()
ADD_LIBRARY ( oslexec SHARED ${liboslexec_srcs} )
-TARGET_LINK_LIBRARIES ( oslexec oslcomp ${OPENIMAGEIO_LIBRARY}
+TARGET_LINK_LIBRARIES ( oslexec
+ ${VISIBILITY_COMMAND} ${VISIBILITY_MAP_COMMAND}
+ ${OPENIMAGEIO_LIBRARY}
${Boost_LIBRARIES} ${CMAKE_DL_LIBS}
- ${LLVM_LIBRARY} )
+ ${LLVM_LIBRARY} ${EXTRA_OSLEXEC_LIBRARIES})
+ADD_DEPENDENCIES (oslexec ${CMAKE_CURRENT_SOURCE_DIR}/liboslcexec.map)
LINK_ILMBASE ( oslexec )
INSTALL ( TARGETS oslexec LIBRARY DESTINATION lib )
View
4 src/liboslexec/liboslexec.map
@@ -0,0 +1,4 @@
+{
+ global: *OSL*; osl_*;
+ local: *;
+};
View
9 src/liboslexec/loadshader.cpp
@@ -234,7 +234,8 @@ OSOReaderToMaster::symdefault (float def)
if (sym.typespec().simpletype().basetype == TypeDesc::FLOAT)
m_master->m_fconsts[offset] = def;
else {
- ASSERT (0 && "unexpected type");
+ ASSERTMSG (0, "unexpected type: %s (%s)",
+ sym.typespec().c_str(), sym.name().c_str());
}
}
}
@@ -252,13 +253,15 @@ OSOReaderToMaster::symdefault (const char *def)
if (sym.typespec().simpletype().basetype == TypeDesc::STRING)
m_master->m_sdefaults[offset] = ustring(def);
else {
- ASSERT (0 && "unexpected type");
+ ASSERTMSG (0, "unexpected type: %s (%s)",
+ sym.typespec().c_str(), sym.name().c_str());
}
} else if (sym.symtype() == SymTypeConst) {
if (sym.typespec().simpletype().basetype == TypeDesc::STRING)
m_master->m_sconsts[offset] = ustring(def);
else {
- ASSERT (0 && "unexpected type");
+ ASSERTMSG (0, "unexpected type: %s (%s)",
+ sym.typespec().c_str(), sym.name().c_str());
}
}
}
View
48 src/liboslexec/oslexec_pvt.h
@@ -131,11 +131,7 @@ struct OpDescriptor {
// Prefix for OSL shade up declarations, so LLVM can find them
-#ifdef _MSC_VER
-#define OSL_SHADEOP extern "C" __declspec(dllexport)
-#else
-#define OSL_SHADEOP extern "C"
-#endif
+#define OSL_SHADEOP extern "C" OSLEXECPUBLIC
@@ -623,10 +619,10 @@ class ClosureRegistry {
-class ShadingSystemImpl : public ShadingSystem
+class OSLEXECPUBLIC ShadingSystemImpl : public ShadingSystem
{
public:
- ShadingSystemImpl (RendererServices *renderer=NULL,
+ OSLEXECPUBLIC ShadingSystemImpl (RendererServices *renderer=NULL,
TextureSystem *texturesystem=NULL,
ErrorHandler *err=NULL);
virtual ~ShadingSystemImpl ();
@@ -1216,25 +1212,25 @@ class ShadingAttribState
namespace Strings {
- extern ustring camera, common, object, shader, screen, NDC;
- extern ustring rgb, RGB, hsv, hsl, YIQ, XYZ, xyz, xyY;
- extern ustring null, default_;
- extern ustring label;
- extern ustring sidedness, front, back, both;
- extern ustring P, I, N, Ng, dPdu, dPdv, u, v, time, dtime, dPdtime, Ps;
- extern ustring Ci;
- extern ustring width, swidth, twidth, rwidth;
- extern ustring blur, sblur, tblur, rblur;
- extern ustring wrap, swrap, twrap, rwrap;
- extern ustring black, clamp, periodic, mirror;
- extern ustring firstchannel, fill, alpha;
- extern ustring interp, closest, linear, cubic, smartcubic;
- extern ustring perlin, uperlin, noise, snoise, pnoise, psnoise;
- extern ustring cell, cellnoise, pcellnoise;
- extern ustring genericnoise, genericpnoise, gabor, gabornoise, gaborpnoise;
- extern ustring anisotropic, direction, do_filter, bandwidth, impulses;
- extern ustring op_dowhile, op_for, op_while;
- extern ustring subimage, subimagename;
+ extern OSLEXECPUBLIC ustring camera, common, object, shader, screen, NDC;
+ extern OSLEXECPUBLIC ustring rgb, RGB, hsv, hsl, YIQ, XYZ, xyz, xyY;
+ extern OSLEXECPUBLIC ustring null, default_;
+ extern OSLEXECPUBLIC ustring label;
+ extern OSLEXECPUBLIC ustring sidedness, front, back, both;
+ extern OSLEXECPUBLIC ustring P, I, N, Ng, dPdu, dPdv, u, v, time, dtime, dPdtime, Ps;
+ extern OSLEXECPUBLIC ustring Ci;
+ extern OSLEXECPUBLIC ustring width, swidth, twidth, rwidth;
+ extern OSLEXECPUBLIC ustring blur, sblur, tblur, rblur;
+ extern OSLEXECPUBLIC ustring wrap, swrap, twrap, rwrap;
+ extern OSLEXECPUBLIC ustring black, clamp, periodic, mirror;
+ extern OSLEXECPUBLIC ustring firstchannel, fill, alpha;
+ extern OSLEXECPUBLIC ustring interp, closest, linear, cubic, smartcubic;
+ extern OSLEXECPUBLIC ustring perlin, uperlin, noise, snoise, pnoise, psnoise;
+ extern OSLEXECPUBLIC ustring cell, cellnoise, pcellnoise;
+ extern OSLEXECPUBLIC ustring genericnoise, genericpnoise, gabor, gabornoise, gaborpnoise;
+ extern OSLEXECPUBLIC ustring anisotropic, direction, do_filter, bandwidth, impulses;
+ extern OSLEXECPUBLIC ustring op_dowhile, op_for, op_while;
+ extern OSLEXECPUBLIC ustring subimage, subimagename;
}; // namespace Strings
View
2  src/liboslexec/osogram.y
@@ -331,7 +331,7 @@ yyerror (const char *err)
// Convert from the lexer's symbolic type (COLORTYPE, etc.) to a TypeDesc.
-TypeDesc
+inline TypeDesc
OSL::pvt::lextype (int lex)
{
switch (lex) {
View
11 src/liboslexec/shadingsys.cpp
@@ -29,6 +29,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector>
#include <string>
#include <cstdio>
+#include <fstream>
#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
@@ -1353,3 +1354,13 @@ const ClosureRegistry::ClosureEntry *ClosureRegistry::get_entry(ustring name)con
}; // namespace pvt
OSL_NAMESPACE_EXIT
+
+
+// Symbols needed to resolve some linkage issues because we pull some
+// components in from liboslcomp.
+int oslparse() { return 0; }
+class oslFlexLexer {
+public:
+ oslFlexLexer (std::istream *in, std::ostream *out);
+};
+oslFlexLexer::oslFlexLexer (std::istream *in, std::ostream *out) { }
Please sign in to comment.
Something went wrong with that request. Please try again.