fpagliughi / sockpp

Modern C++ socket library.
BSD 3-Clause "New" or "Revised" License
792 stars 126 forks source link

Error in cross-compiling for SH4 Linux #74

Closed habu1010 closed 1 year ago

habu1010 commented 1 year ago

When I try to cross-compile for use on an SH4 Linux system, I get a compile error.

After configuring with cmake as follows :

$ cmake -Bbuild -DSOCKPP_BUILD_SHARED=OFF -DSOCKPP_BUILD_STATIC=ON -DCMAKE_CXX_COMPILER="sh4-linux-g++" -DCMAKE_CXX_FLAGS="-Os -Wno-missing-field-intializers -DSO_REUSEPORT=2"
-- The C compiler identification is GNU 10.3.0
-- The CXX compiler identification is GNU 10.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /work/buildroot/output/host/usr/bin/sh4-linux-gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /work/buildroot/output/host/usr/bin/sh4-linux-g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Creating static library: sockpp-static
-- Configuring done
-- Generating done
-- Build files have been written to: /home/habu/sockpp/build

The following error message appears when performing a build.

[ 10%] Building CXX object src/CMakeFiles/sockpp-objs.dir/acceptor.cpp.o
In file included from /home/habu/sockpp/include/sockpp/stream_socket.h:50,
                 from /home/habu/sockpp/include/sockpp/acceptor.h:49,
                 from /home/habu/sockpp/src/acceptor.cpp:38:
/home/habu/sockpp/include/sockpp/socket.h:70:1: error: 'timeval' does not name a type
   70 | timeval to_timeval(const std::chrono::microseconds& dur);
      | ^~~~~~~
/home/habu/sockpp/include/sockpp/socket.h:78:1: error: 'timeval' does not name a type
   78 | timeval to_timeval(const std::chrono::duration<Rep,Period>& dur) {
      | ^~~~~~~
/home/habu/sockpp/include/sockpp/socket.h:87:52: error: 'timeval' does not name a type
   87 | inline std::chrono::microseconds to_duration(const timeval& tv)
      |                                                    ^~~~~~~
/home/habu/sockpp/include/sockpp/socket.h: In function 'std::chrono::microseconds sockpp::to_duration(const int&)':
/home/habu/sockpp/include/sockpp/socket.h:89:40: error: request for member 'tv_sec' in 'tv', which is of non-class type 'const int'
   89 |     auto dur = std::chrono::seconds{tv.tv_sec}
      |                                        ^~~~~~
/home/habu/sockpp/include/sockpp/socket.h:89:46: error: no matching function for call to 'std::chrono::duration<long long int>::duration(<brace-enclosed initializer list>)'
   89 |     auto dur = std::chrono::seconds{tv.tv_sec}
      |                                              ^
In file included from /home/habu/sockpp/include/sockpp/socket.h:51,
                 from /home/habu/sockpp/include/sockpp/stream_socket.h:50,
                 from /home/habu/sockpp/include/sockpp/acceptor.h:49,
                 from /home/habu/sockpp/src/acceptor.cpp:38:
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:478:14: note: candidate: 'template<class _Rep2, class _Period2, class> constexpr std::chrono::duration<_Rep, _Period>::duration(const std::chrono::duration<_Rep, _Period>&) [with _Rep2 = _Rep2; _Period2 = _Period2; <template-parameter-2-3> = <template-parameter-1-3>; _Rep = long long int; _Period = std::ratio<1>]'
  478 |    constexpr duration(const duration<_Rep2, _Period2>& __d)
      |              ^~~~~~~~
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:478:14: note:   template argument deduction/substitution failed:
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:470:23: note: candidate: 'template<class _Rep2, class> constexpr std::chrono::duration<_Rep, _Period>::duration(const _Rep2&) [with _Rep2 = _Rep2; <template-parameter-2-2> = <template-parameter-1-2>; _Rep = long long int; _Period = std::ratio<1>]'
  470 |    constexpr explicit duration(const _Rep2& __rep)
      |                       ^~~~~~~~
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:470:23: note:   template argument deduction/substitution failed:
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:463:2: note: candidate: 'constexpr std::chrono::duration<_Rep, _Period>::duration(const std::chrono::duration<_Rep, _Period>&) [with _Rep = long long int; _Period = std::ratio<1>]'
  463 |  duration(const duration&) = default;
      |  ^~~~~~~~
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:463:2: note:   conversion of argument 1 would be ill-formed:
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:461:12: note: candidate: 'std::chrono::duration<_Rep, _Period>::duration() [with _Rep = long long int; _Period = std::ratio<1>]'
  461 |  constexpr duration() = default;
      |            ^~~~~~~~
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:461:12: note:   candidate expects 0 arguments, 1 provided
In file included from /home/habu/sockpp/include/sockpp/stream_socket.h:50,
                 from /home/habu/sockpp/include/sockpp/acceptor.h:49,
                 from /home/habu/sockpp/src/acceptor.cpp:38:
/home/habu/sockpp/include/sockpp/socket.h:90:36: error: request for member 'tv_usec' in 'tv', which is of non-class type 'const int'
   90 |     + std::chrono::microseconds{tv.tv_usec};
      |                                    ^~~~~~~
/home/habu/sockpp/include/sockpp/socket.h:90:43: error: no matching function for call to 'std::chrono::duration<long long int, std::ratio<1, 1000000> >::duration(<brace-enclosed initializer list>)'
   90 |     + std::chrono::microseconds{tv.tv_usec};
      |                                           ^
In file included from /home/habu/sockpp/include/sockpp/socket.h:51,
                 from /home/habu/sockpp/include/sockpp/stream_socket.h:50,
                 from /home/habu/sockpp/include/sockpp/acceptor.h:49,
                 from /home/habu/sockpp/src/acceptor.cpp:38:
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:478:14: note: candidate: 'template<class _Rep2, class _Period2, class> constexpr std::chrono::duration<_Rep, _Period>::duration(const std::chrono::duration<_Rep, _Period>&) [with _Rep2 = _Rep2; _Period2 = _Period2; <template-parameter-2-3> = <template-parameter-1-3>; _Rep = long long int; _Period = std::ratio<1, 1000000>]'
  478 |    constexpr duration(const duration<_Rep2, _Period2>& __d)
      |              ^~~~~~~~
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:478:14: note:   template argument deduction/substitution failed:
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:470:23: note: candidate: 'template<class _Rep2, class> constexpr std::chrono::duration<_Rep, _Period>::duration(const _Rep2&) [with _Rep2 = _Rep2; <template-parameter-2-2> = <template-parameter-1-2>; _Rep = long long int; _Period = std::ratio<1, 1000000>]'
  470 |    constexpr explicit duration(const _Rep2& __rep)
      |                       ^~~~~~~~
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:470:23: note:   template argument deduction/substitution failed:
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:463:2: note: candidate: 'constexpr std::chrono::duration<_Rep, _Period>::duration(const std::chrono::duration<_Rep, _Period>&) [with _Rep = long long int; _Period = std::ratio<1, 1000000>]'
  463 |  duration(const duration&) = default;
      |  ^~~~~~~~
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:463:2: note:   conversion of argument 1 would be ill-formed:
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:461:12: note: candidate: 'std::chrono::duration<_Rep, _Period>::duration() [with _Rep = long long int; _Period = std::ratio<1, 1000000>]'
  461 |  constexpr duration() = default;
      |            ^~~~~~~~
/mnt/wsl/work/buildroot/output/host/opt/ext-toolchain/sh4-buildroot-linux-musl/include/c++/10.3.0/chrono:461:12: note:   candidate expects 0 arguments, 1 provided
In file included from /home/habu/sockpp/include/sockpp/stream_socket.h:50,
                 from /home/habu/sockpp/include/sockpp/acceptor.h:49,
                 from /home/habu/sockpp/src/acceptor.cpp:38:
/home/habu/sockpp/include/sockpp/socket.h: At global scope:
/home/habu/sockpp/include/sockpp/socket.h:99:65: error: 'timeval' does not name a type
   99 | inline std::chrono::system_clock::time_point to_timepoint(const timeval& tv)
      |                                                                 ^~~~~~~
cc1plus: note: unrecognized command-line option '-Wno-missing-field-intializers' may have been intended to silence earlier diagnostics
gmake[2]: *** [src/CMakeFiles/sockpp-objs.dir/build.make:76: src/CMakeFiles/sockpp-objs.dir/acceptor.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:126: src/CMakeFiles/sockpp-objs.dir/all] Error 2
gmake: *** [Makefile:136: all] Error 2

According to the error, the definition of the timeval type seems to be missing, so adding the following sys/time.h include near the beginning of include/sockpp/socket.h will enable compilation.

#include "sockpp/sock_address.h"
#include <sys/time.h> // <-- add
#include <chrono>
#include <string>
#include <tuple>

This should solve the problem on Linux-based systems, but I am not sure if this is a reasonable solution on non-Linux systems.

fpagliughi commented 1 year ago

Hey! Thanks for the report. Yes, it seems like you're right. We appear to be missing <sys/time.h> as an explicit include.

The proper place to add it would be in include/sockpp/platform.h in the #else (non-Windows) section, around line 102 or so:

#if defined(_WIN32)
  // ...
#else
    #include <unistd.h>
    #include <sys/socket.h>
    #include <sys/time.h> // <-- add
    #include <sys/uio.h>
    #include <arpa/inet.h>
    // ...
#endif

Let me know if that work to fix it for you, and if so, I will add it in for the next release.

habu1010 commented 1 year ago

Thanks for your reply!

I have verified that adding the inclusion of the sys/time.h header at your specified location compiles without problems. Hopefully this fix will be added to the next release.

Regards.

fpagliughi commented 1 year ago

In new Release v0.8.1