Compiling etr/libhttpserver (httpserver) in gcc 7.1.0 in which std::pair is unable to make friends any more

Reference

issues/118 of etr/libhttpserver

Patch

httpserver-0.9.0_gcc7_std_pair_cannot_make_friends_any_more.patch

*** libhttpserver-0.9.0/src/httpserver/details/http_endpoint.hpp~       2015-04-14 18:14:35.000000000 -0700
--- libhttpserver-0.9.0/src/httpserver/details/http_endpoint.hpp        2018-07-06 06:30:50.762024051 -0700
***************
*** 60,68 ****
  **/
  class http_endpoint
  {
!     private:
          /**
!          * Copy constructor. It is useful expecially to copy regex_t structure that contains dinamically allocated data.
           * @param h The http_endpoint to copy
          **/
          http_endpoint(const http_endpoint& h);
--- 60,71 ----
  **/
  class http_endpoint
  {
!     public:
          /**
!          * The maintenance constructors must be public in gcc C++17 so that std::is_constructible is true.
!          * A std::pair(ep, V) must be constructible, destructible and assignable.
!          * In C++17, with compatibility for C++11 and prior, struct std::pair is too complicated to simply be a friend.
!          * Copy constructor. It is useful expecially to copy regex_t structure that contains dynamically allocated data.
           * @param h The http_endpoint to copy
          **/
          http_endpoint(const http_endpoint& h);
***************
*** 83,88 ****
--- 86,92 ----
           * @return a reference to the http_endpoint obtained
          **/
          http_endpoint& operator =(const http_endpoint& h);
+     private:
          /**
           * Method indicating if this endpoint 'matches' with the one passed. A passed endpoint matches a registered endpoint if
           * the regex represented by the registered endpoint matches the passed one.
***************
*** 240,246 ****
--- 244,253 ----
                  details::http_resource_mirror&,
                  bool
          );
+         // See https://github.com/etr/libhttpserver/issues/118
+         // the friendship is pointless in C++17, gcc 7.1.0
          template friend struct std::pair;
+         // Pointless when operator< is public.
          template friend struct std::less;
  };

Build

Fedora 27 is still using libhttpserver-0.9.0 which was packaged in Fedora 24 era.

mkdir rpms
cp -i …/releases/27/Everything/source/tree/Packages/l/libhttpserver-0.9.0-3.fc24.src.rpm rpms/.
mkdir sources
rpm2cpio rpms/libhttpserver-0.9.0-3.fc24.src.rpm | ( cd sources && cpio --extract --make-directories )
tar -axf sources/v0.9.0.tar.gz
cd libhttpserver-0.9.0
./bootstrap
mkdir build
cd build
../configure --enable-cpp11 --prefix=/exp && make && make install

Diagnostic

Ahem … still gotta work on those C++ error messages, don’t we?

make  all-recursive
make[1]: Entering directory '/sandbox/httpserver/libhttpserver-0.9.0/build'
Making all in src
make[2]: Entering directory '/sandbox/httpserver/libhttpserver-0.9.0/build/src'
/bin/sh ../libtool  --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I../../src -I..  -I../ -I../../src/httpserver/  -O3 -fPIC -Wall  -DHTTPSERVER_COMPILATION -D_REENTRANT -I/usr/include/p11-kit-1   -MT libhttpserver_la-webserver.lo -MD -MP -MF .deps/libhttpserver_la-webserver.Tpo -c -o libhttpserver_la-webserver.lo `test -f 'webserver.cpp' || echo '../../src/'`webserver.cpp
/bin/sh ../libtool  --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I../../src -I..  -I../ -I../../src/httpserver/  -O3 -fPIC -Wall  -DHTTPSERVER_COMPILATION -D_REENTRANT -I/usr/include/p11-kit-1   -MT libhttpserver_la-http_response.lo -MD -MP -MF .deps/libhttpserver_la-http_response.Tpo -c -o libhttpserver_la-http_response.lo `test -f 'http_response.cpp' || echo '../../src/'`http_response.cpp
libtool: compile:  g++ -DHAVE_CONFIG_H -I. -I../../src -I.. -I../ -I../../src/httpserver/ -O3 -fPIC -Wall -DHTTPSERVER_COMPILATION -D_REENTRANT -I/usr/include/p11-kit-1 -MT libhttpserver_la-webserver.lo -MD -MP -MF .deps/libhttpserver_la-webserver.Tpo -c ../../src/webserver.cpp  -fPIC -DPIC -o .libs/libhttpserver_la-webserver.o
libtool: compile:  g++ -DHAVE_CONFIG_H -I. -I../../src -I.. -I../ -I../../src/httpserver/ -O3 -fPIC -Wall -DHTTPSERVER_COMPILATION -D_REENTRANT -I/usr/include/p11-kit-1 -MT libhttpserver_la-http_response.lo -MD -MP -MF .deps/libhttpserver_la-http_response.Tpo -c ../../src/http_response.cpp  -fPIC -DPIC -o .libs/libhttpserver_la-http_response.o
../../src/webserver.cpp:856:13: warning: Value MHD_HTTP_METHOD_NOT_ACCEPTABLE is deprecated, use MHD_HTTP_NOT_ACCEPTABLE
         MHD_HTTP_METHOD_NOT_ACCEPTABLE,
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~                                                      
../../src/webserver.cpp: In member function ‘bool httpserver::webserver::register_resource(const string&, httpserver::details::http_resource_mirror, bool)’:
../../src/webserver.cpp:255:88: error: no matching function for call to ‘std::pair::pair(httpserver::details::http_endpoint&, httpserver::details::http_resource_mirror&)’
         map::value_type(idx, hrm)
                                                                                        ^
In file included from /usr/include/c++/7/bits/stl_algobase.h:64:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/ios:40,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/c++/7/iostream:39,
                 from ../../src/webserver.cpp:23:
/usr/include/c++/7/bits/stl_pair.h:431:9: note: candidate: template std::pair::pair(std::tuple&, std::tuple&, std::_Index_tuple, std::_Index_tuple)
         pair(tuple&, tuple&,
         ^~~~
/usr/include/c++/7/bits/stl_pair.h:431:9: note:   template argument deduction/substitution failed:
../../src/webserver.cpp:255:88: note:   ‘httpserver::details::http_endpoint’ is not derived from ‘std::tuple’
         map::value_type(idx, hrm)
                                                                                        ^
In file included from /usr/include/c++/7/bits/stl_algobase.h:64:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/ios:40,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/c++/7/iostream:39,
                 from ../../src/webserver.cpp:23:
/usr/include/c++/7/bits/stl_pair.h:364:9: note: candidate: template std::pair::pair(std::piecewise_construct_t, std::tuple, std::tuple)
         pair(piecewise_construct_t, tuple, tuple);
         ^~~~
/usr/include/c++/7/bits/stl_pair.h:364:9: note:   template argument deduction/substitution failed:
../../src/webserver.cpp:255:88: note:   ‘httpserver::details::http_resource_mirror’ is not derived from ‘std::tuple’
         map::value_type(idx, hrm)
                                                                                        ^
In file included from /usr/include/c++/7/bits/stl_algobase.h:64:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/ios:40,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/c++/7/iostream:39,
                 from ../../src/webserver.cpp:23:
/usr/include/c++/7/bits/stl_pair.h:359:21: note: candidate: template::value) || (! std::is_same::value)), const httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>::_MoveConstructiblePair() && (! std::_PCC::value) || (! std::is_same::value)), const httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>::_ImplicitlyMoveConvertiblePair())), bool>::type  > constexpr std::pair::pair(std::pair&&)
  explicit constexpr pair(pair&& __p)
                     ^~~~
/usr/include/c++/7/bits/stl_pair.h:359:21: note:   template argument deduction/substitution failed:
../../src/webserver.cpp:255:88: note:   ‘httpserver::details::http_endpoint’ is not derived from ‘std::pair’
         map::value_type(idx, hrm)
                                                                                        ^
In file included from /usr/include/c++/7/bits/stl_algobase.h:64:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/ios:40,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/c++/7/iostream:39,
                 from ../../src/webserver.cpp:23:
/usr/include/c++/7/bits/stl_pair.h:349:12: note: candidate: template::value) || (! std::is_same::value)), const httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>::_MoveConstructiblePair() && std::_PCC::value) || (! std::is_same::value)), const httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>::_ImplicitlyMoveConvertiblePair()), bool>::type  > constexpr std::pair::pair(std::pair&&)
  constexpr pair(pair&& __p)
            ^~~~
/usr/include/c++/7/bits/stl_pair.h:349:12: note:   template argument deduction/substitution failed:
../../src/webserver.cpp:255:88: note:   ‘httpserver::details::http_endpoint’ is not derived from ‘std::pair’
         map::value_type(idx, hrm)
                                                                                        ^
In file included from /usr/include/c++/7/bits/stl_algobase.h:64:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/ios:40,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/c++/7/iostream:39,
                 from ../../src/webserver.cpp:23:
/usr/include/c++/7/bits/stl_pair.h:339:21: note: candidate: template() && (! _ImplicitlyMoveConvertiblePair())), bool>::type  > constexpr std::pair::pair(_U1&&, _U2&&)
  explicit constexpr pair(_U1&& __x, _U2&& __y)
                     ^~~~
/usr/include/c++/7/bits/stl_pair.h:339:21: note:   template argument deduction/substitution failed:
/usr/include/c++/7/bits/stl_pair.h:338:38: error: no type named ‘type’ in ‘struct std::enable_if’
                          bool>::type=false>
                                      ^~~~~
/usr/include/c++/7/bits/stl_pair.h:338:38: note: invalid template non-type parameter
/usr/include/c++/7/bits/stl_pair.h:330:12: note: candidate: template() && _ImplicitlyMoveConvertiblePair()), bool>::type  > constexpr std::pair::pair(_U1&&, _U2&&)
  constexpr pair(_U1&& __x, _U2&& __y)
            ^~~~
/usr/include/c++/7/bits/stl_pair.h:330:12: note:   template argument deduction/substitution failed:
/usr/include/c++/7/bits/stl_pair.h:329:38: error: no type named ‘type’ in ‘struct std::enable_if’
                          bool>::type=true>
                                      ^~~~
/usr/include/c++/7/bits/stl_pair.h:329:38: note: invalid template non-type parameter
/usr/include/c++/7/bits/stl_pair.h:321:17: note: candidate: template(), bool>::type  > std::pair::pair(const _T1&, _U2&&)
        explicit pair(const _T1& __x, _U2&& __y)
                 ^~~~
/usr/include/c++/7/bits/stl_pair.h:321:17: note:   template argument deduction/substitution failed:
/usr/include/c++/7/bits/stl_pair.h:320:38: error: no type named ‘type’ in ‘struct std::enable_if’
                          bool>::type=false>
                                      ^~~~~
/usr/include/c++/7/bits/stl_pair.h:320:38: note: invalid template non-type parameter
/usr/include/c++/7/bits/stl_pair.h:314:18: note: candidate: template(), bool>::type  > constexpr std::pair::pair(const _T1&, _U2&&)
        constexpr pair(const _T1& __x, _U2&& __y)
                  ^~~~
/usr/include/c++/7/bits/stl_pair.h:314:18: note:   template argument deduction/substitution failed:
/usr/include/c++/7/bits/stl_pair.h:313:38: error: no type named ‘type’ in ‘struct std::enable_if’
                          bool>::type=true>
                                      ^~~~
/usr/include/c++/7/bits/stl_pair.h:313:38: note: invalid template non-type parameter
/usr/include/c++/7/bits/stl_pair.h:307:27: note: candidate: template(), bool>::type  > constexpr std::pair::pair(_U1&&, const _T2&)
        explicit constexpr pair(_U1&& __x, const _T2& __y)
                           ^~~~
/usr/include/c++/7/bits/stl_pair.h:307:27: note:   template argument deduction/substitution failed:
/usr/include/c++/7/bits/stl_pair.h:306:38: error: no type named ‘type’ in ‘struct std::enable_if’
                          bool>::type=false>
                                      ^~~~~
/usr/include/c++/7/bits/stl_pair.h:306:38: note: invalid template non-type parameter
/usr/include/c++/7/bits/stl_pair.h:300:18: note: candidate: template(), bool>::type  > constexpr std::pair::pair(_U1&&, const _T2&)
        constexpr pair(_U1&& __x, const _T2& __y)
                  ^~~~
/usr/include/c++/7/bits/stl_pair.h:300:18: note:   template argument deduction/substitution failed:
/usr/include/c++/7/bits/stl_pair.h:299:38: error: no type named ‘type’ in ‘struct std::enable_if’
                          bool>::type=true>
                                      ^~~~
/usr/include/c++/7/bits/stl_pair.h:299:38: note: invalid template non-type parameter
/usr/include/c++/7/bits/stl_pair.h:293:17: note: candidate: std::pair::pair(std::pair&&) [with _T1 = const httpserver::details::http_endpoint; _T2 = httpserver::details::http_resource_mirror]
       constexpr pair(pair&&) = default;
                 ^~~~
/usr/include/c++/7/bits/stl_pair.h:293:17: note:   candidate expects 1 argument, 2 provided
/usr/include/c++/7/bits/stl_pair.h:292:17: note: candidate: std::pair::pair(const std::pair&) [with _T1 = const httpserver::details::http_endpoint; _T2 = httpserver::details::http_resource_mirror]
       constexpr pair(const pair&) = default;
                 ^~~~
/usr/include/c++/7/bits/stl_pair.h:292:17: note:   candidate expects 1 argument, 2 provided
/usr/include/c++/7/bits/stl_pair.h:289:21: note: candidate: template::value) || (! std::is_same::value)), const httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>::_ConstructiblePair() && (! std::_PCC::value) || (! std::is_same::value)), const httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>::_ImplicitlyConvertiblePair())), bool>::type  > constexpr std::pair::pair(const std::pair&)
  explicit constexpr pair(const pair& __p)
                     ^~~~
/usr/include/c++/7/bits/stl_pair.h:289:21: note:   template argument deduction/substitution failed:
../../src/webserver.cpp:255:88: note:   ‘httpserver::details::http_endpoint’ is not derived from ‘const std::pair’
         map::value_type(idx, hrm)
                                                                                        ^
In file included from /usr/include/c++/7/bits/stl_algobase.h:64:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/ios:40,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/c++/7/iostream:39,
                 from ../../src/webserver.cpp:23:
/usr/include/c++/7/bits/stl_pair.h:280:19: note: candidate: template::value) || (! std::is_same::value)), const httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>::_ConstructiblePair() && std::_PCC::value) || (! std::is_same::value)), const httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>::_ImplicitlyConvertiblePair()), bool>::type  > constexpr std::pair::pair(const std::pair&)
         constexpr pair(const pair& __p)
                   ^~~~
/usr/include/c++/7/bits/stl_pair.h:280:19: note:   template argument deduction/substitution failed:
../../src/webserver.cpp:255:88: note:   ‘httpserver::details::http_endpoint’ is not derived from ‘const std::pair’
         map::value_type(idx, hrm)
                                                                                        ^
In file included from /usr/include/c++/7/bits/stl_algobase.h:64:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/ios:40,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/c++/7/iostream:39,
                 from ../../src/webserver.cpp:23:
/usr/include/c++/7/bits/stl_pair.h:258:26: note: candidate: template() && (! _ImplicitlyConvertiblePair())), bool>::type  > constexpr std::pair::pair(const _T1&, const _T2&)
       explicit constexpr pair(const _T1& __a, const _T2& __b)
                          ^~~~
/usr/include/c++/7/bits/stl_pair.h:258:26: note:   template argument deduction/substitution failed:
/usr/include/c++/7/bits/stl_pair.h:257:38: error: no type named ‘type’ in ‘struct std::enable_if’
                          bool>::type=false>
                                      ^~~~~
/usr/include/c++/7/bits/stl_pair.h:257:38: note: invalid template non-type parameter
/usr/include/c++/7/bits/stl_pair.h:249:17: note: candidate: template() && _ImplicitlyConvertiblePair()), bool>::type  > constexpr std::pair::pair(const _T1&, const _T2&)
       constexpr pair(const _T1& __a, const _T2& __b)
                 ^~~~
/usr/include/c++/7/bits/stl_pair.h:249:17: note:   template argument deduction/substitution failed:
/usr/include/c++/7/bits/stl_pair.h:248:38: error: no type named ‘type’ in ‘struct std::enable_if’
                          bool>::type=true>
                                      ^~~~
/usr/include/c++/7/bits/stl_pair.h:248:38: note: invalid template non-type parameter
/usr/include/c++/7/bits/stl_pair.h:231:26: note: candidate: template, std::is_default_constructible, std::__not_<std::__and_<std::__is_implicitly_default_constructible, std::__is_implicitly_default_constructible > > >::value, bool>::type  > constexpr std::pair::pair()
       explicit constexpr pair()
                          ^~~~
/usr/include/c++/7/bits/stl_pair.h:231:26: note:   template argument deduction/substitution failed:
../../src/webserver.cpp:255:88: note:   candidate expects 0 arguments, 2 provided
         map::value_type(idx, hrm)
                                                                                        ^
In file included from /usr/include/c++/7/bits/stl_algobase.h:64:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/ios:40,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/c++/7/iostream:39,
                 from ../../src/webserver.cpp:23:
/usr/include/c++/7/bits/stl_pair.h:218:26: note: candidate: template, std::__is_implicitly_default_constructible >::value, bool>::type  > constexpr std::pair::pair()
       _GLIBCXX_CONSTEXPR pair()
                          ^~~~
/usr/include/c++/7/bits/stl_pair.h:218:26: note:   template argument deduction/substitution failed:
../../src/webserver.cpp:255:88: note:   candidate expects 0 arguments, 2 provided
         map::value_type(idx, hrm)
                                                                                        ^
libtool: compile:  g++ -DHAVE_CONFIG_H -I. -I../../src -I.. -I../ -I../../src/httpserver/ -O3 -fPIC -Wall -DHTTPSERVER_COMPILATION -D_REENTRANT -I/usr/include/p11-kit-1 -MT libhttpserver_la-http_response.lo -MD -MP -MF .deps/libhttpserver_la-http_response.Tpo -c ../../src/http_response.cpp -o libhttpserver_la-http_response.o >/dev/null 2>&1
make[2]: *** [Makefile:536: libhttpserver_la-webserver.lo] Error 1
make[2]: *** Waiting for unfinished jobs....
mv -f .deps/libhttpserver_la-http_response.Tpo .deps/libhttpserver_la-http_response.Plo
make[2]: Leaving directory '/sandbox/httpserver/libhttpserver-0.9.0/build/src'
make[1]: *** [Makefile:598: all-recursive] Error 1
make[1]: Leaving directory '/sandbox/httpserver/libhttpserver-0.9.0/build'
make: *** [Makefile:492: all] Error 2

GCC C++ Modules TS Branch in Git from the original Subversion service

Whereas

GCC for Modules TS is mastered in Subversion. It would be fun to have it copied and available in Git. Because that’s what the cool kids use nowadays.

Specimen

  • svn://gcc.gnu.org/svn/gcc/branches/c++-modules

References

Recipe

cd /…/vault/git/svn/org.gnu.gcc
mkdir c++-modules
svnadmin create c++-modules
cat > c++-modules/hooks/pre-revprop-change <<EOF
#!/bin/sh
exit 0;
EOF
chmod +x c++-modules/hooks/pre-revprop-change

svnsync init file:///…/vault/git/svn/org.gnu.gcc/c++-modules svn://gcc.gnu.org/svn/gcc/branches/c++-modules
# one line of output
# …quick…

svnsync sync file:///…/vault/git/svn/org.gnu.gcc/c++-modules
# …lots and lots of output…
# …long time passing…
# …think "five days" as 1 rev/sec is common and you need r25500…

cd /…/vault/git/clones
git svn clone file:///…/vault/git/svn/org.gnu.gcc/c++-modules -T trunk -b branches -t tags

Also, -s is the same as -T trunk -b branches -t tags

Previously,

gcc’s ‘#pragma once’ accounts for file timestamp and contents but not name

Nota Bene: gcc’s #pragma once takes into account the file timestamp and the file contents but does not take into account the file name or position in the tree. This is unfortunate.

Folklore

This can occur…

  • On very fast systems & filesystems such that file timestamps become “the same” (having the same per-second granularity).
  • [unusual] When files are copied OR
  • When files have substantially the same contents but because of their location in the build tree or searchpath, make visible different ancillary files.

Evidence

  • 52566#include with #pragma once and files’ contents is the same