Opened 10 months ago

Last modified 10 months ago

#67773 new defect

mosh@1.4.0: numerous C++ compilation errors on 10.5.8 PPC (when building with nonstandard gcc12 compiler)

Reported by: acjones8 (Alex Jones) Owned by:
Priority: Normal Milestone:
Component: ports Version:
Keywords: ppc Cc:
Port: mosh

Description

When attempting to build mosh for OS X 10.5.8 (on ppc), using GCC 12.3, GCC starts off the build and gets through the protobuf section just fine, but completely falls apart once it tries to compile ocb_internal.cc . I'll attach the main.log file with all of the error messages, but here's a few examples:

cb_internal.cc:223:13: error: 'vector' does not name a type; did you mean 'vec_or'?
  223 |     typedef vector unsigned block;
      |             ^~~~~~
      |             vec_or
ocb_internal.cc:237:16: error: 'block' does not name a type
  237 |         static block gen_offset(uint64_t KtopStr[3], unsigned bot) {
      |                ^~~~~
ocb_internal.cc:259:23: error: 'block' does not name a type
  259 |         static inline block double_block(block b) {
      |                       ^~~~~
ocb_internal.cc:456:13: error: variable or field 'ecb_encrypt_blks' declared void
  456 | static void ecb_encrypt_blks(block *blks, unsigned nblks, KEY *key) {
      |             ^~~~~~~~~~~~~~~~
ocb_internal.cc:456:30: error: 'block' was not declared in this scope; did you mean 'clock'?
  456 | static void ecb_encrypt_blks(block *blks, unsigned nblks, KEY *key) {

I don't think it's GCC related, as I've had no issues compiling other programs (including GCC itself) with GCC 12. I'm a bit stumped at to what the issue is, but I'm more than happy to provide any additional info that might help.

Attachments (1)

mosh_fail.log (151.9 KB) - added by acjones8 (Alex Jones) 10 months ago.

Download all attachments as: .zip

Change History (10)

Changed 10 months ago by acjones8 (Alex Jones)

Attachment: mosh_fail.log added

comment:1 Changed 10 months ago by kencu (Ken)

Leopard running gcc12 is not presently a MacPorts-supported configuration, FYI, but you can try adding

configure.cppflags-append -faltivec

and if that doesn't work, add that flag to the configure.cflags and configure.cxxflags instead.

That should kick the headers into the right altivec-supporting mode.

By the way, if you add:

configure.args-append --disable-silent-rules

you should be able to see more completely what the actual compilation lines look like.

comment:2 Changed 10 months ago by acjones8 (Alex Jones)

Thanks for the tips! I didn't know about the disable silent rules option. I added the --disable-silent-rules flag and did configure.args-append -faltivec for cflags, cxxflags, and cppflags, but unfortunately none of them fixed the issue. Because of the disable-silent-rules flag, I can see that -faltivec is in the list of options passed to the compiler, so it doesn't seem like the build system is causing the issue.

/opt/local/bin/g++-mp-12 -std=gnu++11 -DHAVE_CONFIG_H -I. -I../../src/include  -I./../util -I/opt/local/libexec/openssl3/include -I/opt/local/include -faltivec -DGOOGLE_PROTOBUF_NO_THREADLOCAL -Wall  -fno-strict-overflow -D_FORTIFY_SOURCE=2 -fstack-protector-all -Wstack-protector --param ssp-buffer-size=1 -fPIE -fno-default-inline -pipe  -pipe -Os -std=c++11 -faltivec -D_GLIBCXX_USE_CXX11_ABI=0 -arch ppc -MT ocb_internal.o -MD -MP -MF .deps/ocb_internal.Tpo -c -o ocb_internal.o ocb_internal.cc
ocb_internal.cc:223:13: error: 'vector' does not name a type; did you mean 'vec_or'?
  223 |     typedef vector unsigned block;
      |             ^~~~~~
      |             vec_or

I looked up other options in the GCC manual related to altivec support, and I found a -maltivec option. I gave it a try just in case, but it didn't work either. I wondered if maybe something's wrong in how GCC handles altivec support, so I wrote a very short test program that uses vec_add() to add two vector ints together and prints the result. I've never worked with SIMD before, but it gives the correct results even after I tweak the input numbers, and it recognized #include <altivec.h> without me needing to manually pass in -faltivec. Plus, if OpenSSL uses altivec to accelerate encryption as well, I've been able to compile that without issues.

comment:3 Changed 10 months ago by kencu (Ken)

that fix came from this old ticket (I've been around here too long :> )

#55251

but - not sure why it wouldn't work for you here.

Last edited 10 months ago by kencu (Ken) (previous) (diff)

comment:4 Changed 10 months ago by kencu (Ken)

there is a slight difference about the way that Apple's gcc-4.2 handled adding the altivec header, and the way that mainstream gcc handles it... I'll see if I can find that ticket.

comment:5 Changed 10 months ago by kencu (Ken)

Summary: mosh@1.4.0: numerous C++ compilation errors on 10.5.8 PPCmosh@1.4.0: numerous C++ compilation errors on 10.5.8 PPC (when building with nonstandard gcc12 compiler)

comment:6 Changed 10 months ago by kencu (Ken)

I just tried to build mosh on 10.5 Intel running rosetta and it built through without trouble, although I see altivec was not enabled:

Making all in crypto
make[3]: Entering directory `/opt/localppc/var/macports/build/_opt_localppc_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_net_mosh/mosh/work/mosh-1.4.0/src/crypto'
/opt/localppc/bin/g++-mp-7 -std=gnu++11 -DHAVE_CONFIG_H -I. -I../../src/include  -I./../util -I/opt/localppc/libexec/openssl3/include -I/opt/localppc/include -DGOOGLE_PROTOBUF_NO_THREADLOCAL -Wall  -fno-strict-overflow -D_FORTIFY_SOURCE=2 -fstack-protector-all -Wstack-protector --param ssp-buffer-size=1 -fPIE -fno-default-inline -pipe  -pipe -Os -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -arch ppc -MT ocb_internal.o -MD -MP -MF .deps/ocb_internal.Tpo -c -o ocb_internal.o ocb_internal.cc
/opt/localppc/bin/g++-mp-7 -std=gnu++11 -DHAVE_CONFIG_H -I. -I../../src/include  -I./../util -I/opt/localppc/libexec/openssl3/include -I/opt/localppc/include -DGOOGLE_PROTOBUF_NO_THREADLOCAL -Wall  -fno-strict-overflow -D_FORTIFY_SOURCE=2 -fstack-protector-all -Wstack-protector --param ssp-buffer-size=1 -fPIE -fno-default-inline -pipe  -pipe -Os -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -arch ppc -MT base64.o -MD -MP -MF .deps/base64.Tpo -c -o base64.o base64.cc
/opt/localppc/bin/g++-mp-7 -std=gnu++11 -DHAVE_CONFIG_H -I. -I../../src/include  -I./../util -I/opt/localppc/libexec/openssl3/include -I/opt/localppc/include -DGOOGLE_PROTOBUF_NO_THREADLOCAL -Wall  -fno-strict-overflow -D_FORTIFY_SOURCE=2 -fstack-protector-all -Wstack-protector --param ssp-buffer-size=1 -fPIE -fno-default-inline -pipe  -pipe -Os -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -arch ppc -MT crypto.o -MD -MP -MF .deps/crypto.Tpo -c -o crypto.o crypto.cc
mv -f .deps/base64.Tpo .deps/base64.Po
mv -f .deps/ocb_internal.Tpo .deps/ocb_internal.Po
mv -f .deps/crypto.Tpo .deps/crypto.Po
rm -f libmoshcrypto.a
ar cru libmoshcrypto.a  ocb_internal.o base64.o crypto.o 
ranlib libmoshcrypto.a

comment:7 Changed 10 months ago by kencu (Ken)

I manually turned on Altivec with Rosetta like this

configure.cppflags-append -D__ALTIVEC__

and it builds through too...

Making all in crypto
make[3]: Entering directory `/opt/localppc/var/macports/build/_opt_localppc_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_net_mosh/mosh/work/mosh-1.4.0/src/crypto'
/opt/localppc/bin/g++-mp-7 -std=gnu++11 -DHAVE_CONFIG_H -I. -I../../src/include  -I./../util -I/opt/localppc/libexec/openssl3/include -I/opt/localppc/include -DGOOGLE_PROTOBUF_NO_THREADLOCAL -D__ALTIVEC__ -Wall  -fno-strict-overflow -D_FORTIFY_SOURCE=2 -fstack-protector-all -Wstack-protector --param ssp-buffer-size=1 -fPIE -fno-default-inline -pipe  -pipe -Os -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -arch ppc -MT ocb_internal.o -MD -MP -MF .deps/ocb_internal.Tpo -c -o ocb_internal.o ocb_internal.cc
/opt/localppc/bin/g++-mp-7 -std=gnu++11 -DHAVE_CONFIG_H -I. -I../../src/include  -I./../util -I/opt/localppc/libexec/openssl3/include -I/opt/localppc/include -DGOOGLE_PROTOBUF_NO_THREADLOCAL -D__ALTIVEC__ -Wall  -fno-strict-overflow -D_FORTIFY_SOURCE=2 -fstack-protector-all -Wstack-protector --param ssp-buffer-size=1 -fPIE -fno-default-inline -pipe  -pipe -Os -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -arch ppc -MT base64.o -MD -MP -MF .deps/base64.Tpo -c -o base64.o base64.cc
/opt/localppc/bin/g++-mp-7 -std=gnu++11 -DHAVE_CONFIG_H -I. -I../../src/include  -I./../util -I/opt/localppc/libexec/openssl3/include -I/opt/localppc/include -DGOOGLE_PROTOBUF_NO_THREADLOCAL -D__ALTIVEC__ -Wall  -fno-strict-overflow -D_FORTIFY_SOURCE=2 -fstack-protector-all -Wstack-protector --param ssp-buffer-size=1 -fPIE -fno-default-inline -pipe  -pipe -Os -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -arch ppc -MT crypto.o -MD -MP -MF .deps/crypto.Tpo -c -o crypto.o crypto.cc
mv -f .deps/base64.Tpo .deps/base64.Po
mv -f .deps/ocb_internal.Tpo .deps/ocb_internal.Po
mv -f .deps/crypto.Tpo .deps/crypto.Po
rm -f libmoshcrypto.a
ar cru libmoshcrypto.a  ocb_internal.o base64.o crypto.o 
ranlib libmoshcrypto.a

comment:8 Changed 10 months ago by acjones8 (Alex Jones)

Alright, I think I figured it out! Your gut instinct about different headers or header definitions seems to have been correct.

You mentioned that you were able to build mosh without any issues if you disabled AltiVec. We've been passing in -faltivec to enable it, so I thought... maybe -fno-altivec will disable it. Trying that solution, it actually works - mosh builds and functions perfectly as far as I can tell. I'm very relieved to have it back, but I wasn't really happy with not having AltiVec, since my understanding is it can make quite a decent performance improvement on these older processors.

So I dug a little deeper. I didn't realize what "vec_or" meant earlier, but I discovered that it's an intrinsic that does a logical or between two vectors. I figured GCC wouldn't be suggesting it as an alternative to "vector" if it wasn't defined, so it seemed like altivec.h was getting imported properly. So I dug around and found it at /opt/local/lib/gcc12/gcc/ppc-apple-darwin9/12.3.0/include/altivec.h. Upon examining it, I found this interesting chunk of code:

/* If __APPLE_ALTIVEC__ is defined, the compiler supports 'vector',
   'pixel' and 'bool' as context-sensitive AltiVec keywords (in 
   non-AltiVec contexts, they revert to their original meanings,
   if any), so we do not need to define them as macros.  Also,
   avoid defining them as macros for C++ with strict ANSI, as
   this is not compatible.  */

#if !defined(__APPLE_ALTIVEC__) \
    && (!defined(__STRICT_ANSI__) || !defined(__cplusplus))
#define vector __vector
#define pixel __pixel
#define bool __bool
#endif

I'm in a little over my head here, but it seems like GCC redefines vector to __vector on non-apple platforms (among other reasons). I tried passing in __APPLE_ALTIVEC__ like you did earlier with __ALTIVEC__ using configure-append, but that didn't help any. Then I thought, maybe I'll just try manually redefining vector to __vector in the altivec code block in mosh. And that's the trick - GCC has no further complaints after that, the code compiles without any errors. I haven't extensively stress tested it, but after logging into my server and editing for a couple of minutes, everything seems to work fine, it behaves exactly as it did above without altivec. I was a little suspicious, but by disassembling the mosh binary using otool -tvV, I can see a few vsplt instructions in it, which the altivec manual I found says are vector splat commands. So it doesn't seem like this "fixes" the problem by disabling altivec in a roundabout way, it *does* seem to actually be using altivec now.

So - with all that said, would it be okay if I offered a patch that fixes this problem? It would only need to add a single line of code, #define vector __vector at the top of the AltiVec block in ocb_internal.cc . I checked GCC 7's source code to look at its version of altivec.h, and it seems to lack the checks for ANSI or C++, it just straight up defines vector as __vector if __APPLE_ALTIVEC__ isn't set. It doesn't seem like this would break compatibility, as GCC 7 seems to already be doing that redefinition.

It's very strange that mosh seems to have this issue, since as mentioned, openssh and other programs seem to compile with AltiVec support just fine... which I verified by using otool to disassemble /opt/local/bin/ssh and seeing lots of vsplt and vperm instructions, just like how my own test program has vaddfp in it...

Last edited 10 months ago by acjones8 (Alex Jones) (previous) (diff)

comment:9 Changed 10 months ago by acjones8 (Alex Jones)

Wait, nevermind, I see the problem now. GCC 12's header disables the redefinition if it's running in a C++ environment, since vector is often short for std::vector. GCC 7's header never checked if it was running in C++ mode, it just unconditionally redefined vector to __vector on non-Apple systems, and seems to have expected the programmer to undefine it if need be.

#if !defined(__APPLE_ALTIVEC__)
/* You are allowed to undef these for C++ compatibility.  */
#define vector __vector
#define pixel __pixel
#define bool __bool
#endif

So then, maybe an upstream patch is more appropriate? Maybe I can ask them to stick the vector to __vector definition in there, since it seems like this is what it's doing most of the time anyway.

Note: See TracTickets for help on using tickets.