Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Attemp to fix https://github.com/KhronosGroup/SPIRV-Tools/issues/3909 #4569

Closed
wants to merge 1 commit into from

Conversation

sl1pkn07
Copy link
Contributor

@sl1pkn07 sl1pkn07 commented Oct 12, 2021

  • Try to fix the point (1).
    • Build static mode by default (like always). for enable shared mode set -DBUILD_SHARED_LIBS=ON
    • Remove SPIRV-Tools-shared.pc.in. not need anymore. SPIRV-Tools.pc.in can handle both.
    • Let's visible always. because hide make problems when link to sprv-foo/test programs in shared mode (can' find any symbols).
  • Build external RE2 in static mode always

TODO:

  • Fix point (2) and point (3)

  • Point (4) is out of my scope. i'm not coder

@ben-clayton
Copy link
Contributor

Continuing discussion from #3909 (comment)

About downstream projects, I'm completely sure rigth now have a workrounds for fixing the actual behaviour, and the devs want to remove it as soon as possible.

This PR removes targets that were identified as in-use. See #3626 (comment) and #3626 (comment). I'm sure there are many more uses in non-public codebases.

There are linux packages shipping libSPIRV-Tools-shared.so, so just yanking that out will likely result in a lot of grumpy package maintainers and developers using these packages.

Let's visible always. because hide make problems when link to sprv-foo/test programs in shared mode (can' find any symbols).

The fact there's a SPIRV_TOOLS_EXPORT shows there was an effort to explicitly annotate APIs as public (although I have no idea how much of an effort was made).

This is a chance to do that correctly.

I do not believe that changing default visibility to public is a good idea. Making all the symbols public can impact binary size and performance. As soon as all symbols are public, they'll get used, and you won't be able to hide them again without breaking downstream code.

@sl1pkn07
Copy link
Contributor Author

sl1pkn07 commented Oct 12, 2021

Continuing discussion from #3909 (comment)

About downstream projects, I'm completely sure rigth now have a workrounds for fixing the actual behaviour, and the devs want to remove it as soon as possible.

This PR removes targets that were identified as in-use. See #3626 (comment) and #3626 (comment). I'm sure there are many more uses in non-public codebases.

you fixed that with unexpected behaviour.

The creation of the file ${SPIRV_TOOLS}-static or ${SPIRV_TOOLS}-shared is not the expected. the thread #3626 OP expect when if use -DBUILD_SHARED_LIBS=ON expect ${SPIRV_TOOLS}.so shared library, and when use -DBUILD_SHARED_LIBS=OFF or leave the option untouch, expect ${SPIRV_TOOLS}.a static lib (windows and macos expect in both cases their file extensions for each files, but Cmake do it this internally (this last statement maybe is not true at all and need change the extension inside the CMakeList.txt)

this can be expanded to package maintainers.

the right now behaviour (without this PR) is explained in this issue #4417, wich is cleary not expected, and i hope this PR fix it

There are linux packages shipping libSPIRV-Tools-shared.so, so just yanking that out will likely result in a lot of grumpy package maintainers and developers using these packages.

this is because the current behaviour is incorrect. and also, the downstrem project with use the fixed behaviour, wich use or .cmake or .pc files for search the dependencies and include in the code, only need rebuild the project and release, like when exist a new version or change. because this not touch the core or how work the library, only change how is builded the library.

Let's visible always. because hide make problems when link to sprv-foo/test programs in shared mode (can' find any symbols).

The fact there's a SPIRV_TOOLS_EXPORT shows there was an effort to explicitly annotate APIs as public (although I have no idea how much of an effort was made).

This is a chance to do that correctly.

I do not believe that changing default visibility to public is a good idea. Making all the symbols public can impact binary size and performance. As soon as all symbols are public, they'll get used, and you won't be able to hide them again without breaking downstream code.

maybe i need chage the things i made in source/CMakeLists.txt. but in my first build as shared library, i get linker errors against missing symbols, and fixed when do public

the part of hide or unhide symbols maybe need much love, but with This is a chance to do that correctly. i mean the creation of shared or static lib, internal things needs atention wich is out of my scope because i'm not coder. only can do the edition of the cmake scripts

greetings

@ben-clayton
Copy link
Contributor

I don't disagree that your changes bring the CMake configurations to a cleaner, and more expected / idiomatic output.
I don't disagree that this is how it should have been done from the start.
That's not my concern with these changes.

We have distribution packages out in the wild that ship with libSPIRV-Tools-shared.so.

As there are packages containing this file, there will be numerous binaries that will depend on libSPIRV-Tools-shared.so. This PR removes libSPIRV-Tools-shared.so. Any binaries / packages depending on this file will not be able to use the new build output. That's a major breaking change.

the downstrem project with use the fixed behaviour

How many downstream projects? This PR affects projects that depend directly on SPIRV-Tools CMake rules, and those that depend on the linux distribution packages. You seem confident that this is a small cost for a small number of projects. I'm less confident about this. I know this will impact a number of Google projects, which I can likely handle, but the changes to symbol visibility may cause additional unexpected problems.

Maybe this major breaking change is the right thing to do.
Maybe the disruption is unacceptable.
I think more people need to be involved in this decision than just you and me.

@sl1pkn07
Copy link
Contributor Author

sl1pkn07 commented Oct 12, 2021

I don't disagree that your changes bring the CMake configurations to a cleaner, and more expected / idiomatic output.
I don't disagree that this is how it should have been done from the start.
That's not my concern with these changes.

sorry if my comments sounds redundant or "strange". my apologyze. my intention is be clear due my lack know of the language

We have distribution packages out in the wild that ship with libSPIRV-Tools-shared.so.

yea, and that name convention is not expected. and depends how is builded can be incorrect
(needs to get rid the -shared in the name, because you can identify by the Extension (.so for shared, .a for static. this a naming convention(on macos and win may vary))

notes about the tings in the main CMakeList.txt

# * SPIRV_TOOLS_BUILD_STATIC - ON or OFF - Defaults to ON.
#   If enabled the following targets will be created:
#     ${SPIRV_TOOLS}-static - STATIC library.
#                             Has full public symbol visibility.

ok

#     ${SPIRV_TOOLS}-shared - SHARED library.
#                             Has default-hidden symbol visibility.
#     ${SPIRV_TOOLS}        - will alias to one of above, based on BUILD_SHARED_LIBS.

${SPIRV_TOOLS}-shared when BUILD_SHARED_LIBS=OFF is "ok" because exposed the symbols for link. but when BUILD_SHARED_LIBS=ON is useless. because it can't link with nothing because the symbols is hidden
as note, if build with BUILD_SHARED_LIBS=OFF internal spirv-foo use to build ${SPIRV_TOOLS} (or i miss something?)

#   If disabled the following targets will be created:
#     ${SPIRV_TOOLS}        - either STATIC or SHARED based on SPIRV_TOOLS_LIBRARY_TYPE.
#                             Has full public symbol visibility.

then why hide the symbol when build if enable shared libs, and why is full exposed here?

i dont understand the logic on this. when build static lib, the ${SPIRV_TOOLS}-shared lib created is with symbol hidden (unusable), but when build in shared mode ${SPIRV_TOOLS}-shared the symbol is exposed.

it's not better expose the symbols in both libraries in any case? (or hide the expecific symbol you want to hide (i think i miss something here)

#     ${SPIRV_TOOLS}-shared - SHARED library.
#                             Has default-hidden symbol visibility.

unfuctional lib. the projects needs to use ${SPIRV_TOOLS}.so because is a working shared library. in this case ${SPIRV_TOOLS}-shared and the .pc counterpart is unnecesary

i try to modify the content of the PR for re-add some deleted logic about visibility and not work at all due a lack of some symbols in spirv-val

changes:

diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index cf5fe48d..56699e57 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -373,6 +373,14 @@ add_library(${SPIRV_TOOLS} ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_SOURCES})
 spirv_tools_default_target_options(${SPIRV_TOOLS})
 set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS})
 
+if(BUILD_SHARED_LIBS)
+  set_target_properties(${SPIRV_TOOLS} PROPERTIES CXX_VISIBILITY_PRESET hidden)
+  target_compile_definitions(${SPIRV_TOOLS}
+    PRIVATE SPIRV_TOOLS_IMPLEMENTATION
+    PUBLIC SPIRV_TOOLS_SHAREDLIB
+  )
+endif()
+
 if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
   find_library(LIBRT rt)
   if(LIBRT)
(END)
[ 92%] Linking CXX executable spirv-val
/usr/bin/ld: CMakeFiles/spirv-val.dir/val/val.cpp.o: in function `print_usage(char*)':
val.cpp:(.text+0x26): undefined reference to `spvTargetEnvList[abi:cxx11](int, int)'
/usr/bin/ld: CMakeFiles/spirv-val.dir/val/val.cpp.o: in function `main':
val.cpp:(.text.startup+0x102): undefined reference to `spvParseUniversalLimitsOptions(char const*, spv_validator_limit*)'
/usr/bin/ld: val.cpp:(.text.startup+0x4b7): undefined reference to `spvtools::SpirvTools::SpirvTools(spv_target_env)'
/usr/bin/ld: val.cpp:(.text.startup+0x4ef): undefined reference to `spvtools::SpirvTools::SetMessageConsumer(std::function<void (spv_message_level_t, char const*, spv_position_t const&, char const*)>)'
/usr/bin/ld: val.cpp:(.text.startup+0x524): undefined reference to `spvtools::SpirvTools::Validate(unsigned int const*, unsigned long, spv_validator_options_t*) const'
/usr/bin/ld: val.cpp:(.text.startup+0x535): undefined reference to `spvtools::SpirvTools::~SpirvTools()'
collect2: error: ld returned 1 exit status
make[2]: *** [tools/CMakeFiles/spirv-val.dir/build.make:115: tools/spirv-val] Error 1
make[1]: *** [CMakeFiles/Makefile2:1203: tools/CMakeFiles/spirv-val.dir/all] Error 2
make: *** [Makefile:146: all] Error 2

something i can't see here

add_spvtools_tool(TARGET spirv-as SRCS as/as.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
add_spvtools_tool(TARGET spirv-dis SRCS dis/dis.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
add_spvtools_tool(TARGET spirv-val SRCS val/val.cpp util/cli_consumer.cpp LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
add_spvtools_tool(TARGET spirv-opt SRCS opt/opt.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY})
if (NOT DEFINED IOS_PLATFORM) # iOS does not allow std::system calls which spirv-reduce requires
add_spvtools_tool(TARGET spirv-reduce SRCS reduce/reduce.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-reduce ${SPIRV_TOOLS_FULL_VISIBILITY})
endif()
add_spvtools_tool(TARGET spirv-link SRCS link/linker.cpp LIBS SPIRV-Tools-link ${SPIRV_TOOLS_FULL_VISIBILITY})
add_spvtools_tool(TARGET spirv-lint SRCS lint/lint.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-lint SPIRV-Tools-opt ${SPIRV_TOOLS_FULL_VISIBILITY})
add_spvtools_tool(TARGET spirv-cfg
SRCS cfg/cfg.cpp
cfg/bin_to_dot.h
cfg/bin_to_dot.cpp
LIBS ${SPIRV_TOOLS_FULL_VISIBILITY})
target_include_directories(spirv-cfg PRIVATE ${spirv-tools_SOURCE_DIR}
${SPIRV_HEADER_INCLUDE_DIR})
set(SPIRV_INSTALL_TARGETS spirv-as spirv-dis spirv-val spirv-opt
spirv-cfg spirv-link spirv-lint)
if(NOT DEFINED IOS_PLATFORM)
set(SPIRV_INSTALL_TARGETS ${SPIRV_INSTALL_TARGETS} spirv-reduce)
endif()
if(SPIRV_BUILD_FUZZER)
add_spvtools_tool(TARGET spirv-fuzz SRCS fuzz/fuzz.cpp util/cli_consumer.cpp LIBS SPIRV-Tools-fuzz ${SPIRV_TOOLS_FULL_VISIBILITY})
set(SPIRV_INSTALL_TARGETS ${SPIRV_INSTALL_TARGETS} spirv-fuzz)
endif(SPIRV_BUILD_FUZZER)

if i understand rigth, these programs needs full visibility, but then build as shared hidden it (or partial), need to be exposed all?

or this programs when build, static or shared, is linked always with static libs?

As there are packages containing this file, there will be numerous binaries that will depend on libSPIRV-Tools-shared.so. This PR removes libSPIRV-Tools-shared.so. Any binaries / packages depending on this file will not be able to use the new build output. That's a major breaking change.

can use the new convention with a simply rebuild.

is possible can exist a wild projects with use the libraries directly instead of use .cmake or .pc config files. that project needs to be updated

How many downstream projects? This PR affects projects that depend directly on SPIRV-Tools CMake rules, and those that depend on the linux distribution packages. You seem confident that this is a small cost for a small number of projects. I'm less confident about this. I know this will impact a number of Google projects, which I can likely handle, but the changes to symbol visibility may cause additional unexpected problems.

until now. all projects wich use this linbrary right now needs, or simply rebuild or change the build system (i assume none on this changes modify any part of the core)

and about package maintainers:

@lordheavy, can you take a little look on this and share your opinion? (archlinux SPIRV-Tools (and Vulkan stack) packages maintainer)

feel to free invoke other distribution maintainers

greetings

@sl1pkn07
Copy link
Contributor Author

sl1pkn07 commented Oct 16, 2021

i have done a V3.

build ok only static, only shared and both. also pases each ctest

tested with GLSLANG and VKD3D in local.

thge first one fails about missing symbols when build as shared. for that i enabled the visibility on the libSPIRV-Tools.so library. point 4 needs be fixed
the last one i need remove the -shared surfix in https://source.winehq.org/git/vkd3d.git/blob/HEAD:/configure.ac#l117. this is completely spected due new changes

the list of the V3 changes is:
__

  • Try to fix the point (1).
    • Build static unconditionally. but is only used for link all spirv-foo programs. because all of them (or partial) need all symbols which is only provided by static libs (until the point 4 get fixed)(*). for install it. see below
      This can increase the size a bit.

    • Now exist two defines witch control what type of library is installed/builded*:

      • BUILD_SHARED_LIBS -> This control if you want build shared libs. and if is builded, install it when invoke make install
      • SPIRV_INSTALL_STATIC_LIBS -> This not control the build static library (because is ON unconditionality), but can control the installation when invoke make install
        I do this because some distros needs only static libs, other only shared libs, other both, or other simply what install only the programs

      --- Table of individual use:

      • BUILD_SHARED_LIBS=OFF or not set -> Disable build and installation of shared libraries
      • BUILD_SHARED_LIBS=ON -> Enable build and install shared libs
      • SPIRV_INSTALL_STATIC_LIBS=OFF -> Disable the installation the libraries when invoke make install
      • SPIRV_INSTALL_STATIC_LIBS=ON or not set -> Option ON by default. Enable the installation when invoke make install

      --- Table of conjuntion use:

      • BUILD_SHARED_LIBS=ON and SPIRV_INSTALL_STATIC_LIBS=ON -> Build and install the wrole project. include programs, static and shared libs.
      • BUILD_SHARED_LIBS=OFF and SPIRV_INSTALL_STATIC_LIBS=ON -> Build the programs and static libs, and install the static libs and the programs when invoke make install (Default).
      • BUILD_SHARED_LIBS=ON and SPIRV_INSTALL_STATIC_LIBS=OFF -> build the programs, shared and static libs, and only install the programs and the shared libs when invoke make install.
      • BUILD_SHARED_LIBS=OFF and SPIRV_INSTALL_STATIC_LIBS=OFF -> build the programs and the static libs, but not install when invoke make install

      In all cases, always install the headers

    • The generation of the .cmake only make one flavor, but depend of the options is used, include shared, static, or both. when enable only static lib, the .cmake files point to static libs, when build only shared libs, points to shared libs,
      in this case, static and shared uses the both cases, uses the same TARGET (libSPIRV-Tools>foo<)
      If enabled both, the TARGET of the static libs is untouched (libSPIRV-Tools>foo<), but the shared libs add the surfix -shared (libSPIRV-Tools>foo<-shared)
      -- This need HARD test. this need a CMakeLists.txt test case wich can get the info when use static libs or use shared libs. and test if can linked with other things.
      I have tested with GLSLANG, and seems work as expected. in a VKD3D project (uses pkg-config), i need remove the -shared in the configure.am file for found the correct library.. build ok and linked the libraries as expected (*)

    • The files libSPIRV-Tools-shared.so and SPIRV-Tools-shared.pc is completely gone. no need anymore.

    • By design, the common SPIRV-Tools.pc can be used in both build modes. the pkg-config stack can handle the information of static libs with --static flag when exist static libs in the library path, and normal use when is used as shared lib.
      Maybe need ajust for include this information (if exist in the project) into SPIRV-Tools.pc.in and setup in the CMakeFiles.txt.

    • (*)The visiblility of the shared/static modules is untouched. BUT the libSPIRV-Tools.so (static libSPIRV-Tools.a is always visible) is turn to visible. needs a internal rework (point 4). i can't link with any library (tested with GLSLANG or VKD3D). Always fails to link about missing symbols.
      Needs fix by dev.

TODO:

  • Fix point (2) and point (3)

  • Point (4) is out of my scope. i'm not coder

__

point 4 need acomplished by devs. i'am completely out of this scope

  - Build static unconditionally. but is only used for link all `spirv-foo` programs. because all of them (or partial) need all symbols which is only provided by static libs (until the point 4 get fixed)(*). for install it. see below
    This can increase the size a bit.
  - Now exist two defines witch control what type of library is installed/builded*:
     - `BUILD_SHARED_LIBS`         -> This control if you want build shared libs. and if is builded, install it when invoke `make install`
     - `SPIRV_INSTALL_STATIC_LIBS` -> This not control the build static library (because is ON unconditionality), but can control the installation when invoke `make install`
        I do this because some distros needs only static libs, other only shared libs, other both, or other simply what install only the programs

     --- Table of individual use:

       - `BUILD_SHARED_LIBS=OFF` or not set          -> Disable build and installation of shared libraries
       - `BUILD_SHARED_LIBS=ON`                      -> Enable build and install shared libs
       - `SPIRV_INSTALL_STATIC_LIBS=OFF`             -> Disable the installation the libraries when invoke `make install`
       - `SPIRV_INSTALL_STATIC_LIBS=ON` or not set   -> Option ON by default. Enable the installation when invoke `make install`

     --- Table of conjuntion use:

       - `BUILD_SHARED_LIBS=ON`  and `SPIRV_INSTALL_STATIC_LIBS=ON`  -> Build and install the wrole project. include programs, static and shared libs.
       - `BUILD_SHARED_LIBS=OFF` and `SPIRV_INSTALL_STATIC_LIBS=ON`  -> Build the programs and static libs, and install the static libs and the programs when invoke `make install` (Default).
       - `BUILD_SHARED_LIBS=ON`  and `SPIRV_INSTALL_STATIC_LIBS=OFF` -> build the programs, shared and static libs, and only install the programs and the shared libs when invoke `make install`.
       - `BUILD_SHARED_LIBS=OFF` and `SPIRV_INSTALL_STATIC_LIBS=OFF` -> build the programs and the static libs, but not install when invoke `make install`

       In all cases, always install the headers

  - The generation of the `.cmake` only make one flavor, but depend of the options is used, include shared, static, or both. when enable only static lib, the `.cmake` files point to `static` libs, when build only shared libs, points to `shared` libs,
    in this case, static and shared uses the both cases, uses the same TARGET (`libSPIRV-Tools>foo<`)
    If enabled both, the TARGET of the static libs is untouched (`libSPIRV-Tools>foo<`), but the shared libs add the surfix `-shared` (`libSPIRV-Tools>foo<-shared`)
    -- This need HARD test. this need a CMakeLists.txt test case wich can get the info when use static libs or use shared libs. and test if can linked with other things.
        I have tested with GLSLANG, and seems work as expected. in a VKD3D project (uses pkg-config), i need remove the `-shared` in the configure.am file for found the correct library.. build ok and linked the libraries as expected (*)
  - The files `libSPIRV-Tools-shared.so` and `SPIRV-Tools-shared.pc` is completely gone. no need anymore.
  - By design, the common `SPIRV-Tools.pc` can be used in both build modes. the `pkg-config` stack can handle the information of static libs with `--static` flag when exist static libs in the library path, and normal use when is used as shared lib.
    Maybe need ajust for include this information (if exist in the project) into `SPIRV-Tools.pc.in` and setup in the `CMakeFiles.txt`.
  - (*)The visiblility of the shared/static modules is untouched. BUT the `libSPIRV-Tools.so` (static `libSPIRV-Tools.a` is always visible) is turn to visible. needs a internal rework (point 4). i can't link with any library (tested with GLSLANG or VKD3D). Always fails to link about missing symbols.
    Needs fix by dev.

TODO:
  - Fix point (2) and point (3)

- Point (4) is out of my scope. i'm not coder
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants