Add an option to override the namespace used for spirv_cross.

This is a pragmatic trick to avoid symbol collision where a project
links against SPIRV-Cross statically, while linking to other projects
which also use SPIRV-Cross statically. We can end up with very awkward
symbol collisions which can resolve themselves silently because
SPIRV-Cross is pulled in as necessary. To fix this, we must use
different symbols and embed two copies of SPIRV-Cross in this scenario,
now with different namespaces, which in turn leads to different symbols.
This commit is contained in:
Hans-Kristian Arntzen 2019-03-29 10:29:44 +01:00
parent 3fa09f5677
commit 9b92e68d71
24 changed files with 69 additions and 36 deletions

View File

@ -36,6 +36,8 @@ option(SPIRV_CROSS_SANITIZE_MEMORY "Sanitize memory" OFF)
option(SPIRV_CROSS_SANITIZE_THREADS "Sanitize threads" OFF)
option(SPIRV_CROSS_SANITIZE_UNDEFINED "Sanitize undefined" OFF)
option(SPIRV_CROSS_NAMESPACE_OVERRIDE "" "Override the namespace used in the C++ API.")
if(${CMAKE_GENERATOR} MATCHES "Makefile")
if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
message(FATAL_ERROR "Build out of tree to avoid overwriting Makefile")
@ -99,8 +101,8 @@ macro(extract_headers out_abs file_list)
endforeach()
endmacro()
macro(spirv_cross_add_library name config_name)
add_library(${name} ${ARGN})
macro(spirv_cross_add_library name config_name library_type)
add_library(${name} ${library_type} ${ARGN})
extract_headers(hdrs "${ARGN}")
target_include_directories(${name} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
@ -109,6 +111,13 @@ macro(spirv_cross_add_library name config_name)
PUBLIC_HEADERS "${hdrs}")
target_compile_options(${name} PRIVATE ${spirv-compiler-options})
target_compile_definitions(${name} PRIVATE ${spirv-compiler-defines})
if (SPIRV_CROSS_NAMESPACE_OVERRIDE)
if (${library_type} MATCHES "STATIC")
target_compile_definitions(${name} PUBLIC SPIRV_CROSS_NAMESPACE_OVERRIDE=${SPIRV_CROSS_NAMESPACE_OVERRIDE})
else()
target_compile_definitions(${name} PRIVATE SPIRV_CROSS_NAMESPACE_OVERRIDE=${SPIRV_CROSS_NAMESPACE_OVERRIDE})
endif()
endif()
install(TARGETS ${name}
EXPORT ${config_name}Config
RUNTIME DESTINATION bin
@ -184,8 +193,12 @@ if (SPIRV_CROSS_STATIC)
endif()
if (SPIRV_CROSS_ENABLE_REFLECT)
spirv_cross_add_library(spirv-cross-reflect spirv_cross_reflect STATIC
${spirv-cross-reflect-sources})
if (SPIRV_CROSS_ENABLE_GLSL)
spirv_cross_add_library(spirv-cross-reflect spirv_cross_reflect STATIC
${spirv-cross-reflect-sources})
else()
message(FATAL_ERROR "Must enable GLSL support to enable JSON reflection support.")
endif()
endif()
if (SPIRV_CROSS_ENABLE_MSL)
@ -294,7 +307,11 @@ if (SPIRV_CROSS_SHARED)
endif()
if (SPIRV_CROSS_ENABLE_REFLECT)
target_sources(spirv-cross-c-shared PRIVATE ${spirv-cross-reflect-sources})
if (SPIRV_CROSS_ENABLE_GLSL)
target_sources(spirv-cross-c-shared PRIVATE ${spirv-cross-reflect-sources})
else()
message(FATAL_ERROR "Must enable GLSL support to enable JSON reflection support.")
endif()
target_compile_definitions(spirv-cross-c-shared PRIVATE SPIRV_CROSS_C_API_REFLECT=1)
endif()

View File

@ -36,7 +36,7 @@
#endif
using namespace spv;
using namespace spirv_cross;
using namespace SPIRV_CROSS_NAMESPACE;
using namespace std;
#ifdef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS

View File

@ -21,7 +21,7 @@
using namespace std;
namespace spirv_cross
namespace SPIRV_CROSS_NAMESPACE
{
CFG::CFG(Compiler &compiler_, const SPIRFunction &func_)
: compiler(compiler_)

View File

@ -20,7 +20,7 @@
#include "spirv_common.hpp"
#include <assert.h>
namespace spirv_cross
namespace SPIRV_CROSS_NAMESPACE
{
class Compiler;
class CFG

View File

@ -35,7 +35,23 @@
#include <utility>
#include <vector>
namespace spirv_cross
// A bit crude, but allows projects which embed SPIRV-Cross statically to
// effectively hide all the symbols from other projects.
// There is a case where we have:
// - Project A links against SPIRV-Cross statically.
// - Project A links against Project B statically.
// - Project B links against SPIRV-Cross statically (might be a different version).
// This leads to a conflict with extremely bizarre results.
// By overriding the namespace in one of the project builds, we can work around this.
// If SPIRV-Cross is embedded in dynamic libraries,
// prefer using -fvisibility=hidden on GCC/Clang instead.
#ifdef SPIRV_CROSS_NAMESPACE_OVERRIDE
#define SPIRV_CROSS_NAMESPACE SPIRV_CROSS_NAMESPACE_OVERRIDE
#else
#define SPIRV_CROSS_NAMESPACE spirv_cross
#endif
namespace SPIRV_CROSS_NAMESPACE
{
#ifdef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS

View File

@ -17,7 +17,7 @@
#include "spirv_cpp.hpp"
using namespace spv;
using namespace spirv_cross;
using namespace SPIRV_CROSS_NAMESPACE;
using namespace std;
void CompilerCPP::emit_buffer_block(const SPIRVariable &var)

View File

@ -21,7 +21,7 @@
#include <utility>
#include <vector>
namespace spirv_cross
namespace SPIRV_CROSS_NAMESPACE
{
class CompilerCPP : public CompilerGLSL
{

View File

@ -24,7 +24,7 @@
using namespace std;
using namespace spv;
using namespace spirv_cross;
using namespace SPIRV_CROSS_NAMESPACE;
Compiler::Compiler(vector<uint32_t> ir_)
{
@ -3825,7 +3825,7 @@ void Compiler::build_function_control_flow_graphs_and_analyze()
}
}
Compiler::CFGBuilder::CFGBuilder(spirv_cross::Compiler &compiler_)
Compiler::CFGBuilder::CFGBuilder(Compiler &compiler_)
: compiler(compiler_)
{
}
@ -4109,12 +4109,12 @@ bool Compiler::is_desktop_only_format(spv::ImageFormat format)
return false;
}
bool Compiler::image_is_comparison(const spirv_cross::SPIRType &type, uint32_t id) const
bool Compiler::image_is_comparison(const SPIRType &type, uint32_t id) const
{
return type.image.depth || (comparison_ids.count(id) != 0);
}
bool Compiler::type_is_opaque_value(const spirv_cross::SPIRType &type) const
bool Compiler::type_is_opaque_value(const SPIRType &type) const
{
return !type.pointer && (type.basetype == SPIRType::SampledImage || type.basetype == SPIRType::Image ||
type.basetype == SPIRType::Sampler);

View File

@ -21,7 +21,7 @@
#include "spirv_cfg.hpp"
#include "spirv_cross_parsed_ir.hpp"
namespace spirv_cross
namespace SPIRV_CROSS_NAMESPACE
{
struct Resource
{

View File

@ -63,7 +63,7 @@
#endif
using namespace std;
using namespace spirv_cross;
using namespace SPIRV_CROSS_NAMESPACE;
struct ScratchMemoryAllocation
{

View File

@ -21,7 +21,7 @@
using namespace std;
using namespace spv;
namespace spirv_cross
namespace SPIRV_CROSS_NAMESPACE
{
void ParsedIR::set_id_bounds(uint32_t bounds)
{

View File

@ -22,7 +22,7 @@
#include <unordered_map>
#include <vector>
namespace spirv_cross
namespace SPIRV_CROSS_NAMESPACE
{
// This data structure holds all information needed to perform cross-compilation and reflection.

View File

@ -18,11 +18,11 @@
#include "spirv_common.hpp"
using namespace spv;
using namespace spirv_cross;
using namespace SPIRV_CROSS_NAMESPACE;
namespace spirv_cross_util
{
void rename_interface_variable(spirv_cross::Compiler &compiler, const std::vector<spirv_cross::Resource> &resources,
void rename_interface_variable(Compiler &compiler, const std::vector<Resource> &resources,
uint32_t location, const std::string &name)
{
for (auto &v : resources)
@ -49,7 +49,7 @@ void rename_interface_variable(spirv_cross::Compiler &compiler, const std::vecto
}
}
void inherit_combined_sampler_bindings(spirv_cross::Compiler &compiler)
void inherit_combined_sampler_bindings(Compiler &compiler)
{
auto &samplers = compiler.get_combined_image_samplers();
for (auto &s : samplers)

View File

@ -21,9 +21,9 @@
namespace spirv_cross_util
{
void rename_interface_variable(spirv_cross::Compiler &compiler, const std::vector<spirv_cross::Resource> &resources,
void rename_interface_variable(SPIRV_CROSS_NAMESPACE::Compiler &compiler, const std::vector<SPIRV_CROSS_NAMESPACE::Resource> &resources,
uint32_t location, const std::string &name);
void inherit_combined_sampler_bindings(spirv_cross::Compiler &compiler);
void inherit_combined_sampler_bindings(SPIRV_CROSS_NAMESPACE::Compiler &compiler);
} // namespace spirv_cross_util
#endif

View File

@ -30,7 +30,7 @@
#include <locale.h>
using namespace spv;
using namespace spirv_cross;
using namespace SPIRV_CROSS_NAMESPACE;
using namespace std;
static bool is_unsigned_opcode(Op op)
@ -11348,7 +11348,7 @@ void CompilerGLSL::unroll_array_from_complex_load(uint32_t target_id, uint32_t s
}
void CompilerGLSL::bitcast_from_builtin_load(uint32_t source_id, std::string &expr,
const spirv_cross::SPIRType &expr_type)
const SPIRType &expr_type)
{
auto *var = maybe_get_backing_variable(source_id);
if (var)
@ -11396,7 +11396,7 @@ void CompilerGLSL::bitcast_from_builtin_load(uint32_t source_id, std::string &ex
}
void CompilerGLSL::bitcast_to_builtin_store(uint32_t target_id, std::string &expr,
const spirv_cross::SPIRType &expr_type)
const SPIRType &expr_type)
{
// Only interested in standalone builtin variables.
if (!has_decoration(target_id, DecorationBuiltIn))

View File

@ -24,7 +24,7 @@
#include <unordered_set>
#include <utility>
namespace spirv_cross
namespace SPIRV_CROSS_NAMESPACE
{
enum PlsFormat
{

View File

@ -20,7 +20,7 @@
#include <assert.h>
using namespace spv;
using namespace spirv_cross;
using namespace SPIRV_CROSS_NAMESPACE;
using namespace std;
static unsigned image_format_to_components(ImageFormat fmt)

View File

@ -21,7 +21,7 @@
#include <utility>
#include <vector>
namespace spirv_cross
namespace SPIRV_CROSS_NAMESPACE
{
// Interface which remaps vertex inputs to a fixed semantic name to make linking easier.
struct HLSLVertexAttributeRemap

View File

@ -22,7 +22,7 @@
#include <numeric>
using namespace spv;
using namespace spirv_cross;
using namespace SPIRV_CROSS_NAMESPACE;
using namespace std;
static const uint32_t k_unknown_location = ~0u;

View File

@ -24,7 +24,7 @@
#include <unordered_set>
#include <vector>
namespace spirv_cross
namespace SPIRV_CROSS_NAMESPACE
{
// Indicates the format of the vertex attribute. Currently limited to specifying

View File

@ -20,7 +20,7 @@
using namespace std;
using namespace spv;
namespace spirv_cross
namespace SPIRV_CROSS_NAMESPACE
{
Parser::Parser(std::vector<uint32_t> spirv)
{

View File

@ -21,7 +21,7 @@
#include <stdint.h>
#include <vector>
namespace spirv_cross
namespace SPIRV_CROSS_NAMESPACE
{
class Parser
{

View File

@ -19,7 +19,7 @@
#include <iomanip>
using namespace spv;
using namespace spirv_cross;
using namespace SPIRV_CROSS_NAMESPACE;
using namespace std;
namespace simple_json

View File

@ -26,7 +26,7 @@ namespace simple_json
class Stream;
}
namespace spirv_cross
namespace SPIRV_CROSS_NAMESPACE
{
class CompilerReflection : public CompilerGLSL
{