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

[Bug]: Multiple Definition Linker Error for IID_IUnknown #193

Closed
chapterjason opened this issue Mar 4, 2024 · 10 comments
Closed

[Bug]: Multiple Definition Linker Error for IID_IUnknown #193

chapterjason opened this issue Mar 4, 2024 · 10 comments
Assignees
Labels

Comments

@chapterjason
Copy link

bit7z version

4.0.x

Compilation options

No response

7-zip version

v23.01

7-zip shared library used

7z.dll / 7z.so

Compilers

MinGW

Compiler versions

MinGW 11.0 w64, bundles in CLion IDE, GCC 13.1.0

Architecture

x86_64

Operating system

Windows

Operating system versions

Windows 11

Bug description

The linker fails with a "multiple definition" error for IID_IUnknown. This symbol conflict arises because IID_IUnknown is defined both in the bit7z library (libbit7z64_d.a) and MinGW's libuuid.a.

Steps to reproduce

Nothing special, just added as following in CMake:

CPMAddPackage(
    NAME bit7z
    GIT_REPOSITORY "[email protected]:rikyoz/bit7z.git"
    GIT_TAG master
    OPTIONS
        "BIT7Z_BUILD_TESTS false"
        "BIT7Z_BUILD_DOCS false"
)

target_link_libraries(${PROJECT_NAME} [...] bit7z)

Expected behavior

No response

Relevant compilation output

-- CPM: Adding package bit7z@ (master)
-- Standard filesystem: NO (using ghc::filesystem)
-- Target Version: 1.0.0
-- Compiler ID: GNU
-- Compiler Version: 13.1.0
-- Architecture: x64
-- Build Type: Debug
-- Language Standard for bit7z: C++14
-- Auto format detection: OFF
-- Regex matching extraction: OFF
-- Use std::byte: OFF
-- Use native string: OFF
-- Generate Position Independent Code: OFF
-- Disable Zip ASCII password check: OFF
-- Disable using std::filesystem: OFF
-- 7-zip version: 23.01
-- Build tests: false
-- Build docs: false
-- Auto prefix long paths: OFF
-- Use the default codepage: OFF
-- Path sanitization: OFF
-- CPM: bit7z: Adding package [email protected] (v23.01)
-- 7-zip source code available at [...]/cmake-build-debug/_deps/7-zip-src
-- CPM: bit7z: Adding package ghc_filesystem@0 (c0dcd0b090da7dffc74b124a6f164f54dbbb5ccb)
-- ghc::filesystem source code available at [...]/cmake-build-debug/_deps/ghc_filesystem-src
-- Enable sanitizers: OFF
[...]mingw\bin/ld.exe:
[...]mingw/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/lib/../lib/libuuid.a(lib64_libuuid_a-uuid.o):uuid.c:(.rdata$IID_IUnknown[IID_IUnknown]+0x0):
multiple definition of `IID_IUnknown'; _deps/bit7z-src/lib/x64/libbit7z64_d.a(guids.cpp.obj):
[...]/cmake-build-debug/_deps/bit7z-src/src/internal/guids.cpp:19: first defined here


### Code of Conduct

- [X] By submitting this issue, I agree to follow bit7z's [Code of Conduct](https://github.com/rikyoz/bit7z/blob/master/CODE_OF_CONDUCT.md)
@chapterjason
Copy link
Author

This fixes the issue for me.

File guids.hpp

 #ifndef _MSC_VER
+#ifndef __MINGW32__
 extern const GUID IID_IUnknown;
+#endif
 #endif

File guids.cpp

 #ifndef _MSC_VER
+#ifndef __MINGW32__
 const GUID IID_IUnknown = {
     0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 }
 };
+#endif
 #endif

@rikyoz
Copy link
Owner

rikyoz commented Mar 4, 2024

Hi!
This is actually quite strange, as I cannot replicate the issue:

  • Toolchain (MinGW bundled with CLion 2024.1 EAP, still MinGW 11.0 and GCC 13.1.0):
    image

  • CMakeLists.txt:

cmake_minimum_required( VERSION 3.28 )
project( test_uuid_mingw )

set( CMAKE_CXX_STANDARD 17 )

add_executable( test_uuid_mingw main.cpp )

include( cmake/Dependencies.cmake )

CPMAddPackage(
        NAME bit7z
        GIT_REPOSITORY "https://github.com/rikyoz/bit7z.git"
        GIT_TAG master
        OPTIONS
            "BIT7Z_BUILD_TESTS false"
            "BIT7Z_BUILD_DOCS false"
)

target_link_libraries(${PROJECT_NAME} PRIVATE bit7z)
  • CMake output:
-- CPM: Adding package bit7z@ (master)
-- Standard filesystem: NO (using ghc::filesystem)
-- Target Version: 
-- Compiler ID: GNU
-- Compiler Version: 13.1.0
-- Architecture: x64
-- Build Type: Debug
-- Language Standard for bit7z: C++14
-- Auto format detection: OFF
-- Regex matching extraction: OFF
-- Use std::byte: OFF
-- Use native string: OFF
-- Generate Position Independent Code: OFF
-- Disable Zip ASCII password check: OFF
-- Disable using std::filesystem: OFF
-- 7-zip version: 23.01
-- Build tests: false
-- Build docs: false
-- Auto prefix long paths: OFF
-- Use the default codepage: OFF
-- Path sanitization: OFF
-- CPM: bit7z: Adding package [email protected] (v23.01)
-- 7-zip source code available at [...]/test_uuid_mingw/cmake-build-debug-mingw-bundled/_deps/7-zip-src
-- CPM: bit7z: Adding package ghc_filesystem@0 (c0dcd0b090da7dffc74b124a6f164f54dbbb5ccb)
-- ghc::filesystem source code available at [...]/test_uuid_mingw/cmake-build-debug-mingw-bundled/_deps/ghc_filesystem-src
-- Enable sanitizers: OFF
-- Configuring done (5.2s)
-- Generating done (0.0s)
-- Build files have been written to: [...]/test_uuid_mingw/cmake-build-debug-mingw-bundled
  • Source code:
#include <bit7z/bit7zlibrary.hpp>
#include <bit7z/bitmemcompressor.hpp>

int main() {
    bit7z::Bit7zLibrary lib{};
    bit7z::BitMemCompressor compressor{lib, bit7z::BitFormat::Zip};
    compressor.compressFile({'h', 'e', 'l', 'l', 'o'}, "hello.zip");
    return 0;
}
  • Build output:
[...]
[57/61] Building CXX object _deps/bit7z-build/CMakeFiles/bit7z64.dir/src/internal/renameditem.cpp.obj
[58/61] Building CXX object _deps/bit7z-build/CMakeFiles/bit7z64.dir/src/internal/stringutil.cpp.obj
[59/61] Building CXX object _deps/bit7z-build/CMakeFiles/bit7z64.dir/src/internal/updatecallback.cpp.obj
[60/61] Linking CXX static library _deps\bit7z-src\lib\x64\libbit7z64_d.a
[61/61] Linking CXX executable test_uuid_mingw.exe

Build finished

@chapterjason
Copy link
Author

That is really strange, let me try to create a reproducer.

@chapterjason
Copy link
Author

chapterjason commented Mar 4, 2024

This main file fails:

Usage of CLSID_* is the case #include <shobjidl.h> (https://learn.microsoft.com/en-us/windows/win32/api/shobjidl/)

#include <iostream>
#include <bit7z/bit7zlibrary.hpp>
#include <bit7z/bitmemcompressor.hpp>
#include <shobjidl.h>

int main() {
    const auto id = CLSID_FileOpenDialog;

    std::cout << id.Data1 << std::endl;

    bit7z::Bit7zLibrary lib{};
    bit7z::BitMemCompressor compressor{lib, bit7z::BitFormat::Zip};
    compressor.compressFile({'h', 'e', 'l', 'l', 'o'}, "hello.zip");
    return 0;
}

@chapterjason
Copy link
Author

chapterjason commented Mar 4, 2024

Looks like this chain: #include <shobjidl.h> -> #include <ole2.h> -> #include <objbase.h> -> #include <combaseapi.h> -> #include <unknwnbase.h> which contains the IID_IUnknown

But I am not sure TBH, couldn't get a smaller reproducer.

@rikyoz
Copy link
Owner

rikyoz commented Mar 5, 2024

I see. Thank you for the reproducer!
Unfortunately, the obvious fix of using #ifndef _WIN32 instead of #ifndef _MSC_VER breaks linking other programs:

libbit7z64_d.a(bufferextractcallback.cpp.obj):bufferextractcallback.cpp:(.rdata$.refptr.IID_IUnknown[.refptr.IID_IUnknown]+0x0): undefined reference to `IID_IUnknown'
collect2.exe: error: ld returned 1 exit status

I remember fixing this exact issue some years ago (24706ff), but that same fix is causing your issue.
So I'll need to come up with a better fix.
Thank you again for reporting this!

rikyoz added a commit that referenced this issue Mar 5, 2024
@rikyoz
Copy link
Owner

rikyoz commented Mar 5, 2024

I just pushed a fix to the branch hotfix/v4.0.6.
Basically, bit7z now defines IID_IUnknown inside a #ifndef _WIN32 condition, and more importantly, the CMakeLists.txt conditionally specifies the uuid library as a link dependency of bit7z, i.e.,

if( MINGW )
    target_link_libraries( ${LIB_TARGET} PUBLIC uuid )
endif()

This way, a project using bit7z will link against uuid, which will provide the (only) definition of IID_IUnknown.

@chapterjason
Copy link
Author

@rikyoz Works as expected! Thanks a lot. 👍🏼

@rikyoz
Copy link
Owner

rikyoz commented Mar 6, 2024

Perfect! You're welcome! 👍🏼

@rikyoz
Copy link
Owner

rikyoz commented Mar 17, 2024

Released on v4.0.6.

@rikyoz rikyoz closed this as completed Mar 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants