zeroc-ice / ice

All-in-one solution for creating networked applications with RPC, pub/sub, server deployment, and more.
https://zeroc.com
GNU General Public License v2.0
2.05k stars 593 forks source link

Bogus compiler flags set for multi platform linux builds #3168

Open pepone opened 3 hours ago

pepone commented 3 hours ago

https://github.com/zeroc-ice/ice/blob/f9b8b96fd82ec7e0ab9012fd8e4c11a93aa0c6fb/config/Make.rules.Linux#L38-L53

Ice always pass CXXFLAGS to the compiler, the Makefile above sets additional x64_cppflags for 64bits builds and x86_cppflags for 32bit builds.

This works well if CXXFLAGS are compatible with both 32 and 64 bit builds. With RHEL9 the RPM build for x86 arch sets -march=i686 which is not compatible with -m64 added to x64_flags.

From /usr/lib/rpm/redhat/rpmrc in rhel9:

optflags: i686 %{__global_compiler_flags} -m32 -march=i686 -mtune=generic -msse2 -mfpmath=sse -mstackrealign -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection

When we build the x86 RPMs, the build still needs slice2cpp and try to build it as a 64bit executable, ending-up with conflicting flags:

g++ -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m32 -march=i686 -mtune=generic -msse2 -mfpmath=sse -mstackrealign -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -MT src/Slice/build/x64/static/JavaUtil.o -MMD -MP -MF  src/Slice/build/x64/static/JavaUtil.Td -Wall -Wextra -Wredundant-decls -Wshadow -Wdeprecated -Werror -pthread -DNDEBUG -Isrc -Isrc/Slice/generated -Iinclude -Iinclude/generated -DICE_BUILDING_SRC -m64 -DICE_STATIC_LIBS  -c src/Slice/JavaUtil.cpp -o src/Slice/build/x64/static/JavaUtil.o

Notice -m64 and -m32. Here seems the last setting has precedence and then the build fails because -march=i686 is not compatible with 64 bits.

cc1plus: error: CPU you selected does not support x86-64 instruction set
cc1plus: error: '-fcf-protection=full' is not supported for this target
cc1plus: error: CPU you selected does not support x86-64 instruction set
cc1plus: error: '-fcf-protection=full' is not supported for this target
make[1]: *** [Makefile:25: src/Slice/build/x64/static/Grammar.o] Error 1

This didn't cause any issues with the RHEL8 and RHEL7 x86 RPM builds, because they use to set -m32 -march=x86-64

pepone commented 3 hours ago

A second issue here is when CXXFLAGS are not set, for example a regular build instead of a packaging build.

If you try to a x86 build with make PLATFORMS=x86 the default flags report by setarch i386 rpm --eval %optflags vary depending on the installed package.

With a fresh rhel9 install this reports -O2 -g -march=i386 -mtune=i686 which breaks the usage of std::atomic.

/usr/include/c++/11/bits/atomic_base.h:393: undefined reference to `__atomic_fetch_sub_4'

With readhat-rpm-config installed, it overrides this and reports.

-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1  -m32 -march=i686 -mtune=generic -msse2 -mfpmath=sse -mstackrealign -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection

The net result of this second issue is that the x86 build doesn't work without installing readhat-rpm-config