martin-olivier / dylib

C++ cross-platform wrapper around dynamic loading of shared libraries (dll, so, dylib)
https://conan.io/center/recipes/dylib
MIT License
293 stars 44 forks source link

Building on Mingw64 (Windows) #62

Closed lonnietc closed 2 years ago

lonnietc commented 2 years ago

[BUG] [Subject of the issue]

Does not seem to build using Mingw64 on Windows 11

lonni@DESKTOP10 MINGW64 ~/dynlibs/dylib
$ cmake . -B build -DBUILD_TESTS=ON
CMake Warning (dev) at C:/msys64/mingw64/share/cmake/Modules/FetchContent.cmake:1264 (message):
  The DOWNLOAD_EXTRACT_TIMESTAMP option was not given and policy CMP0135 is
  not set.  The policy's OLD behavior will be used.  When using a URL
  download, the timestamps of extracted files should preferably be that of
  the time of extraction, otherwise code that depends on the extracted
  contents might not be rebuilt if the URL changes.  The OLD behavior
  preserves the timestamps from the archive instead, but this is usually not
  what you want.  Update your project to the NEW behavior or specify the
  DOWNLOAD_EXTRACT_TIMESTAMP option with a value of true to avoid this
  robustness issue.
Call Stack (most recent call first):
  CMakeLists.txt:25 (FetchContent_Declare)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Configuring done
-- Generating done
-- Build files have been written to: C:/msys64/home/lonni/dynlibs/dylib/build

then I tried

lonni@DESKTOP10 MINGW64 ~/dynlibs/dylib
$ cmake --build build
[1/8] Building CXX object CMakeFiles/dynamic_lib.dir/tests/lib.cpp.obj
FAILED: CMakeFiles/dynamic_lib.dir/tests/lib.cpp.obj
C:\msys64\mingw64\bin\c++.exe -Ddynamic_lib_EXPORTS  /W4 -std=gnu++11 -MD -MT CMakeFiles/dynamic_lib.dir/tests/lib.cpp.obj -MF CMakeFiles\dynamic_lib.dir\tests\lib.cpp.obj.d -o CMakeFiles/dynamic_lib.dir/tests/lib.cpp.obj -c C:/msys64/home/lonni/dynlibs/dylib/tests/lib.cpp
c++.exe: warning: /W4: linker input file unused because linking not done
c++.exe: error: /W4: linker input file not found: No such file or directory
[2/8] Building CXX object CMakeFiles/unit_tests.dir/tests/tests.cpp.obj
FAILED: CMakeFiles/unit_tests.dir/tests/tests.cpp.obj
C:\msys64\mingw64\bin\c++.exe  -IC:/msys64/home/lonni/dynlibs/dylib/include -isystem C:/msys64/home/lonni/dynlibs/dylib/build/_deps/googletest-src/googletest/include -isystem C:/msys64/home/lonni/dynlibs/dylib/build/_deps/googletest-src/googletest /W4 -std=gnu++11 -MD -MT CMakeFiles/unit_tests.dir/tests/tests.cpp.obj -MF CMakeFiles\unit_tests.dir\tests\tests.cpp.obj.d -o CMakeFiles/unit_tests.dir/tests/tests.cpp.obj -c C:/msys64/home/lonni/dynlibs/dylib/tests/tests.cpp
c++.exe: warning: /W4: linker input file unused because linking not done
c++.exe: error: /W4: linker input file not found: No such file or directory
[3/8] Linking CXX static library lib\libgtest.a
ninja: build stopped: subcommand failed.

Any thoughts?

martin-olivier commented 2 years ago

Hello, Thank you for reporting this bug. The build error is caused by the fact that I was setting the compiler flags depending on the current os and not on the compiler. My friend @MaximeHouis recently made a pull request that fixes that. Can you re-try to build the unit tests of the library on the latest commit ?

cmake . -B build -DDYLIB_BUILD_TESTS=ON
cmake --build build

Let me know if it fixed your issue :)

lonnietc commented 2 years ago

Hello,

I just tried the latest version.

lonni@DESKTOP10 MINGW64 ~/dylib
$ git clone https://github.com/martin-olivier/dylib.git

Cloning into 'dylib'...
remote: Enumerating objects: 556, done.
remote: Counting objects: 100% (272/272), done.
remote: Compressing objects: 100% (115/115), done.
remote: Total 556 (delta 208), reused 183 (delta 144), pack-reused 284
Receiving objects: 100% (556/556), 129.08 KiB | 5.61 MiB/s, done.
Resolving deltas: 100% (301/301), done.

lonni@DESKTOP10 MINGW64 ~/dylib
$ cd dylib/

lonni@DESKTOP10 MINGW64 ~/dylib/dylib
$ cmake . -B build -DDYLIB_BUILD_TESTS=ON
-- Building for: Ninja
-- The CXX compiler identification is GNU 12.1.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/mingw64/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Warning (dev) at C:/msys64/mingw64/share/cmake/Modules/FetchContent.cmake:1264 (message):
  The DOWNLOAD_EXTRACT_TIMESTAMP option was not given and policy CMP0135 is
  not set.  The policy's OLD behavior will be used.  When using a URL
  download, the timestamps of extracted files should preferably be that of
  the time of extraction, otherwise code that depends on the extracted
  contents might not be rebuilt if the URL changes.  The OLD behavior
  preserves the timestamps from the archive instead, but this is usually not
  what you want.  Update your project to the NEW behavior or specify the
  DOWNLOAD_EXTRACT_TIMESTAMP option with a value of true to avoid this
  robustness issue.
Call Stack (most recent call first):
  CMakeLists.txt:25 (FetchContent_Declare)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- The C compiler identification is GNU 12.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/msys64/mingw64/bin/cc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Found Python: C:/Python310/python.exe (found version "3.10.0") found components: Interpreter
-- Configuring done
-- Generating done
-- Build files have been written to: C:/msys64/home/lonni/dylib/dylib/build

lonni@DESKTOP10 MINGW64 ~/dylib/dylib
$ cmake --build build

[1/12] Building CXX object CMakeFiles/dynamic_lib.dir/tests/lib.cpp.obj
[2/12] Linking CXX shared library libdynamic_lib.dll
[3/12] Building CXX object _deps/googletest-build/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.obj
[4/12] Building CXX object _deps/googletest-build/googlemock/CMakeFiles/gmock_main.dir/src/gmock_main.cc.obj
[5/12] Building CXX object _deps/googletest-build/googlemock/CMakeFiles/gmock.dir/src/gmock-all.cc.obj
[6/12] Building CXX object CMakeFiles/unit_tests.dir/tests/tests.cpp.obj
C:/msys64/home/lonni/dylib/dylib/tests/tests.cpp: In member function 'virtual void handle_management_basic_test_Test::TestBody()':
C:/msys64/home/lonni/dylib/dylib/tests/tests.cpp:171:17: warning: cast between incompatible function types from 'long long int (*)()' to 'double (*)(double, double)' [-Wcast-function-type]
  171 |     auto res = ((double (*)(double, double))(sym))(10, 10);
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from C:/msys64/home/lonni/dylib/dylib/tests/tests.cpp:3:
C:/msys64/home/lonni/dylib/dylib/include/dylib.hpp: In instantiation of 'T* dylib::get_function(const char*) const [with T = double(double, double)]':
C:/msys64/home/lonni/dylib/dylib/tests/tests.cpp:35:58:   required from here
C:/msys64/home/lonni/dylib/dylib/include/dylib.hpp:205:16: warning: cast between incompatible function types from 'dylib::native_symbol_type' {aka 'long long int (*)()'} to 'double (*)(double, double)' [-Wcast-function-type]
  205 |         return reinterpret_cast<T *>(get_symbol(symbol_name));
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:/msys64/home/lonni/dylib/dylib/include/dylib.hpp: In instantiation of 'T* dylib::get_function(const char*) const [with T = long unsigned int()]':
C:/msys64/home/lonni/dylib/dylib/tests/tests.cpp:178:30:   required from here
C:/msys64/home/lonni/dylib/dylib/include/dylib.hpp:205:16: warning: cast between incompatible function types from 'dylib::native_symbol_type' {aka 'long long int (*)()'} to 'long unsigned int (*)()' [-Wcast-function-type]
[7/12] Building CXX object _deps/googletest-build/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.obj
[8/12] Linking CXX static library lib\libgtest.a
[9/12] Linking CXX static library lib\libgtest_main.a
[10/12] Linking CXX static library lib\libgmock.a
[11/12] Linking CXX static library lib\libgmock_main.a
[12/12] Linking CXX executable unit_tests.exe

Then it looks like it compiles reasonably well.

lonni@DESKTOP10 MINGW64 ~/dylib/dylib/build
$ ./unit_tests.exe
[==========] Running 12 tests from 11 test suites.
[----------] Global test environment set-up.
[----------] 1 test from exemple
[ RUN      ] exemple.exemple_test
unknown file: Failure
C++ exception with description "Could not load library "./dynamic_lib.dll"
The specified module could not be found.
" thrown in the test body.
[  FAILED  ] exemple.exemple_test (2 ms)
[----------] 1 test from exemple (2 ms total)

[----------] 1 test from ctor
[ RUN      ] ctor.bad_library
[       OK ] ctor.bad_library (0 ms)
[----------] 1 test from ctor (0 ms total)

[----------] 1 test from multiple_handles
[ RUN      ] multiple_handles.basic_test
unknown file: Failure
C++ exception with description "Could not load library "./dynamic_lib.dll"
The specified module could not be found.
" thrown in the test body.
[  FAILED  ] multiple_handles.basic_test (0 ms)
[----------] 1 test from multiple_handles (0 ms total)

[----------] 1 test from get_function
[ RUN      ] get_function.bad_symbol
unknown file: Failure
C++ exception with description "Could not load library "./dynamic_lib.dll"
The specified module could not be found.
" thrown in the test body.
[  FAILED  ] get_function.bad_symbol (0 ms)
[----------] 1 test from get_function (0 ms total)

[----------] 2 tests from get_variable
[ RUN      ] get_variable.bad_symbol
unknown file: Failure
C++ exception with description "Could not load library "./dynamic_lib.dll"
The specified module could not be found.
" thrown in the test body.
[  FAILED  ] get_variable.bad_symbol (0 ms)
[ RUN      ] get_variable.alter_variables
unknown file: Failure
C++ exception with description "Could not load library "./dynamic_lib.dll"
The specified module could not be found.
" thrown in the test body.
[  FAILED  ] get_variable.alter_variables (0 ms)
[----------] 2 tests from get_variable (0 ms total)

[----------] 1 test from invalid_argument
[ RUN      ] invalid_argument.null_pointer
unknown file: Failure
C++ exception with description "Could not load library "./dynamic_lib.dll"
The specified module could not be found.
" thrown in the test body.
[  FAILED  ] invalid_argument.null_pointer (0 ms)
[----------] 1 test from invalid_argument (0 ms total)

[----------] 1 test from manual_decorations
[ RUN      ] manual_decorations.basic_test
unknown file: Failure
C++ exception with description "Could not load library "./dynamic_lib.dll"
The specified module could not be found.
" thrown in the test body.
[  FAILED  ] manual_decorations.basic_test (0 ms)
[----------] 1 test from manual_decorations (0 ms total)

[----------] 1 test from std_move
[ RUN      ] std_move.basic_test
unknown file: Failure
C++ exception with description "Could not load library "./dynamic_lib.dll"
The specified module could not be found.
" thrown in the test body.
[  FAILED  ] std_move.basic_test (0 ms)
[----------] 1 test from std_move (0 ms total)

[----------] 1 test from has_symbol
[ RUN      ] has_symbol.basic_test
unknown file: Failure
C++ exception with description "Could not load library "./dynamic_lib.dll"
The specified module could not be found.
" thrown in the test body.
[  FAILED  ] has_symbol.basic_test (0 ms)
[----------] 1 test from has_symbol (0 ms total)

[----------] 1 test from handle_management
[ RUN      ] handle_management.basic_test
unknown file: Failure
C++ exception with description "Could not load library "./dynamic_lib.dll"
The specified module could not be found.
" thrown in the test body.
[  FAILED  ] handle_management.basic_test (0 ms)
[----------] 1 test from handle_management (0 ms total)

[----------] 1 test from system_lib
[ RUN      ] system_lib.basic_test
[       OK ] system_lib.basic_test (0 ms)
[----------] 1 test from system_lib (0 ms total)

[----------] Global test environment tear-down
[==========] 12 tests from 11 test suites ran. (6 ms total)
[  PASSED  ] 2 tests.
[  FAILED  ] 10 tests, listed below:
[  FAILED  ] exemple.exemple_test
[  FAILED  ] multiple_handles.basic_test
[  FAILED  ] get_function.bad_symbol
[  FAILED  ] get_variable.bad_symbol
[  FAILED  ] get_variable.alter_variables
[  FAILED  ] invalid_argument.null_pointer
[  FAILED  ] manual_decorations.basic_test
[  FAILED  ] std_move.basic_test
[  FAILED  ] has_symbol.basic_test
[  FAILED  ] handle_management.basic_test

10 FAILED TESTS

So then, how do I make the example to see if it works even though a couple of tests seems to fail? Thanks again

rmaxi-me commented 2 years ago

Hello, sorry for the delay.

Can you try previous version and tell me if it works? (Commit 0bdef6c)

Other thing I can notice: [2/12] Linking CXX shared library libdynamic_lib.dll vs C++ exception with description "Could not load library "./dynamic_lib.dll"

Edit: Was able to reproduce. Will try to fix when I can! :)

rmaxi-me commented 2 years ago

@lonnietc well I found a fix, please let me know if it works on your end so I know if it's the right fix.

Also, probably need to add mingw to actions.

lonnietc commented 2 years ago

Thanks and I will give it a test over the weekend.

martin-olivier commented 2 years ago

Hello @lonnietc, Your issue has been fixed by this pull request https://github.com/martin-olivier/dylib/pull/64 that includes the following changes:

fix: removed prefix of MinGW shared libraries generated for unit tests fix: warnings when building with MinGW feat: added MinGW checks on main CI