diff --git a/.gitignore b/.gitignore index cf6c326..7e9b02b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,8 @@ bazel-spirv-reflect bazel-SPIRV-Reflect bazel-testlogs /.vs -/.vscode \ No newline at end of file +/.vscode + +# CLion-specific: +/.idea +/cmake-build* diff --git a/CMakeLists.txt b/CMakeLists.txt index e0181c1..725cfdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.5) project(spirv-reflect) +OPTION(BUILD_SHARED_LIBS "Build shared library" OFF) OPTION(SPIRV_REFLECT_EXECUTABLE "Build spirv-reflect executable" ON) OPTION(SPIRV_REFLECT_STATIC_LIB "Build a SPIRV-Reflect static library" OFF) @@ -12,7 +13,6 @@ OPTION(SPIRV_REFLECT_ENABLE_ASAN "Use address sanitization" OFF) set_property(GLOBAL PROPERTY USE_FOLDERS ON) set(CMAKE_CXX_STANDARD 14) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin") if (SPIRV_REFLECT_ENABLE_ASAN) add_compile_options(-fsanitize=address -fno-omit-frame-pointer) @@ -20,6 +20,8 @@ if (SPIRV_REFLECT_ENABLE_ASAN) endif() if (SPIRV_REFLECT_EXECUTABLE) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin") + # ========================================================================== # Compile spirv_reflect.c as C # ========================================================================== @@ -118,3 +120,18 @@ if(SPIRV_REFLECT_STATIC_LIB) ARCHIVE DESTINATION lib) endif() +if(BUILD_SHARED_LIBS) + add_library(spirv-reflect SHARED ${CMAKE_CURRENT_SOURCE_DIR}/spirv_reflect.h + ${CMAKE_CURRENT_SOURCE_DIR}/spirv_reflect.c) + + target_include_directories(spirv-reflect + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + + target_compile_definitions(spirv-reflect PUBLIC SPIRV_REFLECT_SHARED) + target_compile_options(spirv-reflect PRIVATE + $<$:-fvisibility=hidden>) + + install(TARGETS spirv-reflect + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) +endif () diff --git a/README.md b/README.md index 4f7e82b..5e6e80c 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,26 @@ If the project wants to use it's own SPIRV-Header path, it can set `SPIRV_REFLEC target_compile_definitions(project_name PUBLIC SPIRV_REFLECT_USE_SYSTEM_SPIRV_H) ``` +### Building a shared library + +To facilitate integration into managed languages with FFI support (such as Java and Python), +this project could be built as a shared library. This mode is controlled by the `BUILD_SHARED_LIBS` +CMake option: + +```shell +mkdir build && cd build +cmake -DBUILD_SHARED_LIBS=ON -DSPIRV_REFLECT_EXECUTABLE=OFF .. +make +``` + +Please note that shared library mode is not intended for anything else but this. **Especially** it +is not intended for the regular use case of the shared libraries: packaging and shipping a single +global library for all applications in the system. Header files of SPIRV-Reflect expose several C +structures that you are supposed to allocate by yourself without any way of communicating the +actual runtime structure size. Therefore, you must treat the resulting artifact in the same way +you are dealing with static libraries: runtime library version must **exactly** match the version +of `spirv_reflect.h` file you used to compile your app or generate its FFI bindings. + ## Building Samples **This step is only necessary when building/running SPIRV-Reflect's example applications.** diff --git a/spirv_reflect.c b/spirv_reflect.c index efb1149..a7c1c6b 100644 --- a/spirv_reflect.c +++ b/spirv_reflect.c @@ -14,6 +14,7 @@ limitations under the License. */ +#define SPIRV_REFLECT_IMPLEMENTATION // turn dllimports into dllexports #include "spirv_reflect.h" #include diff --git a/spirv_reflect.h b/spirv_reflect.h index 9a42f14..dac4587 100644 --- a/spirv_reflect.h +++ b/spirv_reflect.h @@ -55,6 +55,20 @@ VERSION HISTORY #define SPV_REFLECT_DEPRECATED(msg_str) #endif +#if defined(SPIRV_REFLECT_SHARED) + #if defined(_WIN32) + #if defined(SPIRV_REFLECT_IMPLEMENTATION) + #define SPV_REFLECT_API __declspec(dllexport) + #elif defined(SPIRV_REFLECT_SHARED) + #define SPV_REFLECT_API __declspec(dllimport) + #endif + #else + #define SPV_REFLECT_API __attribute__((visibility("default"))) + #endif +#else + #define SPV_REFLECT_API +#endif + /*! @enum SpvReflectResult */ @@ -633,6 +647,7 @@ extern "C" { @return SPV_REFLECT_RESULT_SUCCESS on success. */ +SPV_REFLECT_API SpvReflectResult spvReflectCreateShaderModule( size_t size, const void* p_code, @@ -648,6 +663,7 @@ SpvReflectResult spvReflectCreateShaderModule( @return SPV_REFLECT_RESULT_SUCCESS on success. */ +SPV_REFLECT_API SpvReflectResult spvReflectCreateShaderModule2( SpvReflectModuleFlags flags, size_t size, @@ -656,6 +672,7 @@ SpvReflectResult spvReflectCreateShaderModule2( ); SPV_REFLECT_DEPRECATED("renamed to spvReflectCreateShaderModule") +SPV_REFLECT_API SpvReflectResult spvReflectGetShaderModule( size_t size, const void* p_code, @@ -668,7 +685,7 @@ SpvReflectResult spvReflectGetShaderModule( @param p_module Pointer to an instance of SpvReflectShaderModule. */ -void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module); +SPV_REFLECT_API void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module); /*! @fn spvReflectGetCodeSize @@ -677,7 +694,7 @@ void spvReflectDestroyShaderModule(SpvReflectShaderModule* p_module); @return Returns the size of the SPIR-V in bytes */ -uint32_t spvReflectGetCodeSize(const SpvReflectShaderModule* p_module); +SPV_REFLECT_API uint32_t spvReflectGetCodeSize(const SpvReflectShaderModule* p_module); /*! @fn spvReflectGetCode @@ -686,7 +703,7 @@ uint32_t spvReflectGetCodeSize(const SpvReflectShaderModule* p_module); @return Returns a const pointer to the compiled SPIR-V bytecode. */ -const uint32_t* spvReflectGetCode(const SpvReflectShaderModule* p_module); +SPV_REFLECT_API const uint32_t* spvReflectGetCode(const SpvReflectShaderModule* p_module); /*! @fn spvReflectGetEntryPoint @@ -695,6 +712,7 @@ const uint32_t* spvReflectGetCode(const SpvReflectShaderModule* p_module); @return Returns a const pointer to the requested entry point, or NULL if it's not found. */ +SPV_REFLECT_API const SpvReflectEntryPoint* spvReflectGetEntryPoint( const SpvReflectShaderModule* p_module, const char* entry_point @@ -718,6 +736,7 @@ const SpvReflectEntryPoint* spvReflectGetEntryPoint( failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectEnumerateDescriptorBindings( const SpvReflectShaderModule* p_module, uint32_t* p_count, @@ -744,6 +763,7 @@ SpvReflectResult spvReflectEnumerateDescriptorBindings( failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectEnumerateEntryPointDescriptorBindings( const SpvReflectShaderModule* p_module, const char* entry_point, @@ -769,6 +789,7 @@ SpvReflectResult spvReflectEnumerateEntryPointDescriptorBindings( failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectEnumerateDescriptorSets( const SpvReflectShaderModule* p_module, uint32_t* p_count, @@ -795,6 +816,7 @@ SpvReflectResult spvReflectEnumerateDescriptorSets( failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectEnumerateEntryPointDescriptorSets( const SpvReflectShaderModule* p_module, const char* entry_point, @@ -822,6 +844,7 @@ SpvReflectResult spvReflectEnumerateEntryPointDescriptorSets( failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectEnumerateInterfaceVariables( const SpvReflectShaderModule* p_module, uint32_t* p_count, @@ -847,6 +870,7 @@ SpvReflectResult spvReflectEnumerateInterfaceVariables( failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectEnumerateEntryPointInterfaceVariables( const SpvReflectShaderModule* p_module, const char* entry_point, @@ -874,6 +898,7 @@ SpvReflectResult spvReflectEnumerateEntryPointInterfaceVariables( failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectEnumerateInputVariables( const SpvReflectShaderModule* p_module, uint32_t* p_count, @@ -899,6 +924,7 @@ SpvReflectResult spvReflectEnumerateInputVariables( failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectEnumerateEntryPointInputVariables( const SpvReflectShaderModule* p_module, const char* entry_point, @@ -926,6 +952,7 @@ SpvReflectResult spvReflectEnumerateEntryPointInputVariables( failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectEnumerateOutputVariables( const SpvReflectShaderModule* p_module, uint32_t* p_count, @@ -951,6 +978,7 @@ SpvReflectResult spvReflectEnumerateOutputVariables( failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectEnumerateEntryPointOutputVariables( const SpvReflectShaderModule* p_module, const char* entry_point, @@ -979,12 +1007,14 @@ SpvReflectResult spvReflectEnumerateEntryPointOutputVariables( failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectEnumeratePushConstantBlocks( const SpvReflectShaderModule* p_module, uint32_t* p_count, SpvReflectBlockVariable** pp_blocks ); SPV_REFLECT_DEPRECATED("renamed to spvReflectEnumeratePushConstantBlocks") +SPV_REFLECT_API SpvReflectResult spvReflectEnumeratePushConstants( const SpvReflectShaderModule* p_module, uint32_t* p_count, @@ -1011,6 +1041,7 @@ SpvReflectResult spvReflectEnumeratePushConstants( failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectEnumerateEntryPointPushConstantBlocks( const SpvReflectShaderModule* p_module, const char* entry_point, @@ -1032,6 +1063,7 @@ SpvReflectResult spvReflectEnumerateEntryPointPushConstantBlocks( @return If successful, returns SPV_REFLECT_RESULT_SUCCESS. Otherwise, the error code indicates the cause of the failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectEnumerateSpecializationConstants( const SpvReflectShaderModule* p_module, uint32_t* p_count, @@ -1060,6 +1092,7 @@ SpvReflectResult spvReflectEnumerateSpecializationConstants( no guarantees about which binding will be returned. */ +SPV_REFLECT_API const SpvReflectDescriptorBinding* spvReflectGetDescriptorBinding( const SpvReflectShaderModule* p_module, uint32_t binding_number, @@ -1092,7 +1125,7 @@ const SpvReflectDescriptorBinding* spvReflectGetDescriptorBinding( no guarantees about which binding will be returned. */ -const SpvReflectDescriptorBinding* spvReflectGetEntryPointDescriptorBinding( +SPV_REFLECT_API const SpvReflectDescriptorBinding* spvReflectGetEntryPointDescriptorBinding( const SpvReflectShaderModule* p_module, const char* entry_point, uint32_t binding_number, @@ -1117,6 +1150,7 @@ const SpvReflectDescriptorBinding* spvReflectGetEntryPointDescriptorBinding( error results are written to *pResult. */ +SPV_REFLECT_API const SpvReflectDescriptorSet* spvReflectGetDescriptorSet( const SpvReflectShaderModule* p_module, uint32_t set_number, @@ -1140,6 +1174,7 @@ const SpvReflectDescriptorSet* spvReflectGetDescriptorSet( error results are written to *pResult. */ +SPV_REFLECT_API const SpvReflectDescriptorSet* spvReflectGetEntryPointDescriptorSet( const SpvReflectShaderModule* p_module, const char* entry_point, @@ -1148,7 +1183,7 @@ const SpvReflectDescriptorSet* spvReflectGetEntryPointDescriptorSet( ); -/* @fn spvReflectGetInputVariableByLocation +/*! @fn spvReflectGetInputVariableByLocation @param p_module Pointer to an instance of SpvReflectShaderModule. @param location The "location" value of the requested input variable. @@ -1168,19 +1203,21 @@ const SpvReflectDescriptorSet* spvReflectGetEntryPointDescriptorSet( @note */ +SPV_REFLECT_API const SpvReflectInterfaceVariable* spvReflectGetInputVariableByLocation( const SpvReflectShaderModule* p_module, uint32_t location, SpvReflectResult* p_result ); SPV_REFLECT_DEPRECATED("renamed to spvReflectGetInputVariableByLocation") +SPV_REFLECT_API const SpvReflectInterfaceVariable* spvReflectGetInputVariable( const SpvReflectShaderModule* p_module, uint32_t location, SpvReflectResult* p_result ); -/* @fn spvReflectGetEntryPointInputVariableByLocation +/*! @fn spvReflectGetEntryPointInputVariableByLocation @param p_module Pointer to an instance of SpvReflectShaderModule. @param entry_point The entry point to get the input variable from. @@ -1201,6 +1238,7 @@ const SpvReflectInterfaceVariable* spvReflectGetInputVariable( @note */ +SPV_REFLECT_API const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableByLocation( const SpvReflectShaderModule* p_module, const char* entry_point, @@ -1208,7 +1246,7 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableByLocatio SpvReflectResult* p_result ); -/* @fn spvReflectGetInputVariableBySemantic +/*! @fn spvReflectGetInputVariableBySemantic @param p_module Pointer to an instance of SpvReflectShaderModule. @param semantic The "semantic" value of the requested input variable. @@ -1229,13 +1267,14 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableByLocatio @note */ +SPV_REFLECT_API const SpvReflectInterfaceVariable* spvReflectGetInputVariableBySemantic( const SpvReflectShaderModule* p_module, const char* semantic, SpvReflectResult* p_result ); -/* @fn spvReflectGetEntryPointInputVariableBySemantic +/*! @fn spvReflectGetEntryPointInputVariableBySemantic @param p_module Pointer to an instance of SpvReflectShaderModule. @param entry_point The entry point to get the input variable from. @@ -1257,6 +1296,7 @@ const SpvReflectInterfaceVariable* spvReflectGetInputVariableBySemantic( @note */ +SPV_REFLECT_API const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableBySemantic( const SpvReflectShaderModule* p_module, const char* entry_point, @@ -1264,7 +1304,7 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableBySemanti SpvReflectResult* p_result ); -/* @fn spvReflectGetOutputVariableByLocation +/*! @fn spvReflectGetOutputVariableByLocation @param p_module Pointer to an instance of SpvReflectShaderModule. @param location The "location" value of the requested output variable. @@ -1284,19 +1324,21 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointInputVariableBySemanti @note */ +SPV_REFLECT_API const SpvReflectInterfaceVariable* spvReflectGetOutputVariableByLocation( const SpvReflectShaderModule* p_module, uint32_t location, SpvReflectResult* p_result ); SPV_REFLECT_DEPRECATED("renamed to spvReflectGetOutputVariableByLocation") +SPV_REFLECT_API const SpvReflectInterfaceVariable* spvReflectGetOutputVariable( const SpvReflectShaderModule* p_module, uint32_t location, SpvReflectResult* p_result ); -/* @fn spvReflectGetEntryPointOutputVariableByLocation +/*! @fn spvReflectGetEntryPointOutputVariableByLocation @param p_module Pointer to an instance of SpvReflectShaderModule. @param entry_point The entry point to get the output variable from. @@ -1317,6 +1359,7 @@ const SpvReflectInterfaceVariable* spvReflectGetOutputVariable( @note */ +SPV_REFLECT_API const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableByLocation( const SpvReflectShaderModule* p_module, const char* entry_point, @@ -1324,7 +1367,7 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableByLocati SpvReflectResult* p_result ); -/* @fn spvReflectGetOutputVariableBySemantic +/*! @fn spvReflectGetOutputVariableBySemantic @param p_module Pointer to an instance of SpvReflectShaderModule. @param semantic The "semantic" value of the requested output variable. @@ -1345,13 +1388,14 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableByLocati @note */ +SPV_REFLECT_API const SpvReflectInterfaceVariable* spvReflectGetOutputVariableBySemantic( const SpvReflectShaderModule* p_module, const char* semantic, SpvReflectResult* p_result ); -/* @fn spvReflectGetEntryPointOutputVariableBySemantic +/*! @fn spvReflectGetEntryPointOutputVariableBySemantic @param p_module Pointer to an instance of SpvReflectShaderModule. @param entry_point The entry point to get the output variable from. @@ -1373,6 +1417,7 @@ const SpvReflectInterfaceVariable* spvReflectGetOutputVariableBySemantic( @note */ +SPV_REFLECT_API const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableBySemantic( const SpvReflectShaderModule* p_module, const char* entry_point, @@ -1397,12 +1442,14 @@ const SpvReflectInterfaceVariable* spvReflectGetEntryPointOutputVariableBySemant error results are written to *pResult. */ +SPV_REFLECT_API const SpvReflectBlockVariable* spvReflectGetPushConstantBlock( const SpvReflectShaderModule* p_module, uint32_t index, SpvReflectResult* p_result ); SPV_REFLECT_DEPRECATED("renamed to spvReflectGetPushConstantBlock") +SPV_REFLECT_API const SpvReflectBlockVariable* spvReflectGetPushConstant( const SpvReflectShaderModule* p_module, uint32_t index, @@ -1428,6 +1475,7 @@ const SpvReflectBlockVariable* spvReflectGetPushConstant( error results are written to *pResult. */ +SPV_REFLECT_API const SpvReflectBlockVariable* spvReflectGetEntryPointPushConstantBlock( const SpvReflectShaderModule* p_module, const char* entry_point, @@ -1458,6 +1506,7 @@ const SpvReflectBlockVariable* spvReflectGetEntryPointPushConstantBlock( Otherwise, the error code indicates the cause of the failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectChangeDescriptorBindingNumbers( SpvReflectShaderModule* p_module, const SpvReflectDescriptorBinding* p_binding, @@ -1465,6 +1514,7 @@ SpvReflectResult spvReflectChangeDescriptorBindingNumbers( uint32_t new_set_number ); SPV_REFLECT_DEPRECATED("Renamed to spvReflectChangeDescriptorBindingNumbers") +SPV_REFLECT_API SpvReflectResult spvReflectChangeDescriptorBindingNumber( SpvReflectShaderModule* p_module, const SpvReflectDescriptorBinding* p_descriptor_binding, @@ -1494,6 +1544,7 @@ SpvReflectResult spvReflectChangeDescriptorBindingNumber( Otherwise, the error code indicates the cause of the failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectChangeDescriptorSetNumber( SpvReflectShaderModule* p_module, const SpvReflectDescriptorSet* p_set, @@ -1517,6 +1568,7 @@ SpvReflectResult spvReflectChangeDescriptorSetNumber( the failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectChangeInputVariableLocation( SpvReflectShaderModule* p_module, const SpvReflectInterfaceVariable* p_input_variable, @@ -1541,6 +1593,7 @@ SpvReflectResult spvReflectChangeInputVariableLocation( the failure. */ +SPV_REFLECT_API SpvReflectResult spvReflectChangeOutputVariableLocation( SpvReflectShaderModule* p_module, const SpvReflectInterfaceVariable* p_output_variable, @@ -1554,7 +1607,7 @@ SpvReflectResult spvReflectChangeOutputVariableLocation( @return Returns string of source language specified in \a source_lang. The caller must not free the memory associated with this string. */ -const char* spvReflectSourceLanguage(SpvSourceLanguage source_lang); +SPV_REFLECT_API const char* spvReflectSourceLanguage(SpvSourceLanguage source_lang); /*! @fn spvReflectBlockVariableTypeName @@ -1562,7 +1615,7 @@ const char* spvReflectSourceLanguage(SpvSourceLanguage source_lang); @return Returns string of block variable's type description type name or NULL if p_var is NULL. */ -const char* spvReflectBlockVariableTypeName( +SPV_REFLECT_API const char* spvReflectBlockVariableTypeName( const SpvReflectBlockVariable* p_var );