vectorgraphics / asymptote

2D & 3D TeX-Aware Vector Graphics Language
https://asymptote.sourceforge.io/
GNU General Public License v3.0
533 stars 89 forks source link

2.86 build error on Darwin: error: 'std::ios_base::__mpls_seekdir' has not been declared #386

Closed barracuda156 closed 10 months ago

barracuda156 commented 11 months ago

Any idea what goes wrong here?

/opt/local/bin/g++-mp-12 -DHAVE_CONFIG_H -D_FILE_OFFSET_BIS=64 -DUSEGC  -D_THREAD_SAFE -pthread -DFFTWPP_SINGLE_THREAD -Wall -isystem/opt/local/include/LegacySupport -I/opt/local/include -I. -I/opt/local/include/gc -I/usr/include/gc -D_DARWIN_C_SOURCE -DNCURSES_WIDECHAR  -I/opt/local/include/eigen3  -pipe -Os -std=c++14 -D_GLIBCXX_USE_CXX11_ABI=0 -arch ppc -pipe -Os -arch ppc -fno-var-tracking -ILspCpp/include -o util.o -c util.cc
In file included from util.cc:26:
/opt/local/include/gcc12/c++/powerpc-apple-darwin10/bits/basic_file.h:123:42: error: 'std::ios_base::__mpls_seekdir' has not been declared
  123 |       seekoff(streamoff __off, ios_base::seekdir __way) throw ();
      |                                          ^~~~~~~
/opt/local/include/gcc12/c++/fstream:421:41: error: 'std::ios_base::__mpls_seekdir' has not been declared
  421 |       seekoff(off_type __off, ios_base::seekdir __way,
      |                                         ^~~~~~~
/opt/local/include/gcc12/c++/fstream:430:41: error: 'std::ios_base::__mpls_seekdir' has not been declared
  430 |       _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state);
      |                                         ^~~~~~~
/opt/local/include/gcc12/c++/bits/fstream.tcc:833:39: error: 'std::ios_base::__mpls_seekdir' has not been declared
  833 |     seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
      |                                       ^~~~~~~
/opt/local/include/gcc12/c++/bits/fstream.tcc:908:39: error: 'std::ios_base::__mpls_seekdir' has not been declared
  908 |     _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
      |                                       ^~~~~~~
make: *** [util.o] Error 1
johncbowman commented 11 months ago

That means your operating system forgot to define seekdir in /usr/include/dirent.h Check man seekdir in case it is defined in a nonstandard location.

barracuda156 commented 11 months ago

@johncbowman Thank you! We had a recent update to legacy-support which is used on old systems, and now we know where to look.

macportsraf commented 11 months ago

seekdir is defined in legacysupport's <dirent.h> as a macro to __mpls_seekdir which is also declared in that file as a static inline function (between extern "C" { and } in C++). @tavianator, do you have any suggestion for how to fix this? Maybe it would help to move all of the static inline function definitions into the fdopendir.c file, and replace the static inline function definitions to just be extern function declarations? I don't know how it will play with std::ios_base. At least it's something to try. I'll submit a pull request in legacysupport that does that and someone can test it.

johncbowman commented 11 months ago

Yes, I was wondering if it was an extern "C" issue. In that case, something like this should solve the problem. Let us know:

`diff --git a/util.cc b/util.cc index df33e29b..db1ded7d 100644 --- a/util.cc +++ b/util.cc @@ -9,6 +9,10 @@

define _POSIX_C_SOURCE 200809L

endif

+#ifdef APPLE +extern "C" void seekdir(DIR *dirp, long loc); +#endif +

include

include

include

`

johncbowman commented 11 months ago

Actually you probably have to make that change directly to the system include file dirent.h once DIR has been defined. So this seems like an issue that should be reported to your vendor.

tavianator commented 11 months ago

The issue is the C++ standard library using seekdir as a type name (meaning "seek direction"), while legacysupport has done #define seekdir __mpls_seekdir. The type is declared before dirent.h is included, but then used afterwards, so the name doesn't match up any more.

I'm not sure what the best fix would be in legacysupport. If it can't redefine seekdir then it'll have to use some other mechanism to get a hold of the underlying seekdir implementation, maybe RTLD_NEXT.

johncbowman commented 11 months ago

Why not simply #undef seekdir before including dirent.h?

barracuda156 commented 11 months ago

@macportsraf For the record, just got identical error when building TileDB, which has no such error before.

[ 32%] Building CXX object tiledb/sm/query_plan/CMakeFiles/query_plan.dir/query_plan.cc.o
cd /opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_databases_tiledb/tiledb/work/build/tiledb/tiledb/sm/query_plan && /opt/local/bin/g++-mp-12 -DFMT_SHARED -DSPDLOG_COMPILED_LIB -DSPDLOG_FMT_EXTERNAL -DSPDLOG_SHARED_LIB -D_DEBUG -D_FILE_OFFSET_BITS=64 -I/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_databases_tiledb/tiledb/work/TileDB-2.16.0 -isystem /opt/local/include -isystem /opt/local/include/libfmt10 -pipe -I/opt/local/libexec/openssl3/include -Os -DNDEBUG -I/opt/local/libexec/openssl3/include -isystem/opt/local/include/LegacySupport -isystem/opt/local/include -D_GLIBCXX_USE_CXX11_ABI=0 -g -std=c++17 -arch ppc -isysroot /Developer/SDKs/MacOSX10.6.sdk -mmacosx-version-min=10.6 -fvisibility=hidden -Wall -Wextra -DDEBUG -O0 -g3 -ggdb3 -gdwarf-3 -Wno-literal-suffix -MD -MT tiledb/sm/query_plan/CMakeFiles/query_plan.dir/query_plan.cc.o -MF CMakeFiles/query_plan.dir/query_plan.cc.o.d -o CMakeFiles/query_plan.dir/query_plan.cc.o -c /opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_databases_tiledb/tiledb/work/TileDB-2.16.0/tiledb/sm/query_plan/query_plan.cc
In file included from /opt/local/include/gcc12/c++/fstream:42,
                 from /opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_databases_tiledb/tiledb/work/TileDB-2.16.0/tiledb/sm/filesystem/posix.cc:51:
/opt/local/include/gcc12/c++/powerpc-apple-darwin10/bits/basic_file.h:123:32: error: 'std::ios_base::__mpls_seekdir' has not been declared
  123 |       seekoff(streamoff __off, ios_base::seekdir __way) throw ();
      |                                ^~~~~~~~
/opt/local/include/gcc12/c++/fstream:421:31: error: 'std::ios_base::__mpls_seekdir' has not been declared
  421 |       seekoff(off_type __off, ios_base::seekdir __way,
      |                               ^~~~~~~~
/opt/local/include/gcc12/c++/fstream:430:31: error: 'std::ios_base::__mpls_seekdir' has not been declared
  430 |       _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state);
      |                               ^~~~~~~~
In file included from /opt/local/include/gcc12/c++/fstream:1298:
/opt/local/include/gcc12/c++/bits/fstream.tcc:833:29: error: 'std::ios_base::__mpls_seekdir' has not been declared
  833 |     seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode)
      |                             ^~~~~~~~
/opt/local/include/gcc12/c++/bits/fstream.tcc:908:29: error: 'std::ios_base::__mpls_seekdir' has not been declared
  908 |     _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state)
      |                             ^~~~~~~~
macportsraf commented 11 months ago

My original changes to <dirent.h> involved macros that took arguments. Perhaps we should go back to that. Then, seekdir without parentheses wouldn't be interpreted as the macro to the C function __mpls_seekdir, and would instead be interpreted as part of the C++ typename ios_base::seekdir. But of course that might a problem for other reasons (e.g. any code trying to take the address of the seekdir function wouldn't be able to - but if nobody does that it might be OK). The C++ code that invokes the C seekdir function should still work because it would be passing arguments which would invoke the macro expansion. At least, that's what I'm hoping. Maybe we can have it both ways: for C define argumentless macros and for C++ define macros with arguments so as not to clash with the use of seekdir in a typename.

I've just created a pull request that tries this. https://github.com/macports/macports-legacy-support/pull/62. Does it help?

macportsraf commented 11 months ago

I've changed <dirent.h> so that the inline functions are no longer inline. It looked like they might be causing a compilation problem with libgit2 https://github.com/macports/macports-ports/pull/19611

barracuda156 commented 11 months ago

@macportsraf I have been getting errors with a few other ports as well, but they looked similar and I did not want to spam too much :)

P. S. I hope we do not just revert to an earlier version, which was broken with capnproto and rawhide? That fix was very much needed, it just needs a bit of further improvement. I can test tomorrow with relevant ports, just let me know which branch to use.

macportsraf commented 11 months ago

@barracuda156 Update: I can't test it properly until Tuesday but it's looking good. We won't have to revert to an earlier version. I stupidly thought that maybe the C++ seekdir type was for seekdir-like functions which could have been a problem, but it isn't. It's almost certainly just an enum containing the values beg, cur, and end for use with the seekg method in <iostream>. See https://en.cppreference.com/w/cpp/io/ios_base/seekdir

That means that changing the seekdir macro in <dirent.h> to one that takes arguments will be enough to stop it from being invoked when the std::ios_base::seekdir typename occurs in C++ code. I'm just making this change for C++ only and leaving the macros as they are for C.

It still means that C++ code won't be able to take the address of the seekdir function (etc.) but I think that the need for that is vanishingly small.

The branch to test with will be https://github.com/macports/macports-legacy-support/pull/62. I'll let you know when I've tested it on macos-10.6.

macportsraf commented 11 months ago

I've just tested it on my macos-10.6.8 laptop with a new C++ compatibility test, and it's working there. Yay!

macportsraf commented 10 months ago

This is fixed now by https://github.com/macports/macports-legacy-support/pull/62