Bug 188483

Summary: Cannot build for i386 architecture
Product: WebKit Reporter: karogyoker2+webkit
Component: WebKitGTKAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: berto, bugs-noreply, mcatanzaro
Priority: P2    
Version: WebKit Nightly Build   
Hardware: PC   
OS: Linux   

Description karogyoker2+webkit 2018-08-11 07:49:41 PDT
Hi,

I tried to build with:
cmake -DPORT=GTK -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-march=i386" -DCMAKE_CXX_FLAGS="-march=i386" -DUSE_WOFF2=OFF -GNinja
ninja

But I got this:
[1550/3276] Linking CXX executable bin/WebKitWebDriver
FAILED: bin/WebKitWebDriver 
: && /usr/bin/c++  -fdiagnostics-color=always -Wno-expansion-to-defined -Wno-attributes -Wno-noexcept-type -Wno-maybe-uninitialized -Wwrite-strings -Wundef -Wpointer-arith -Wmissing-format-attribute -Wformat-security -Wcast-align -Wextra -Wall -march=i386 -fno-strict-aliasing -fno-exceptions -fno-rtti -std=c++14 -O3 -DNDEBUG  -fuse-ld=gold -Wl,--disable-new-dtags   -rdynamic Source/WebDriver/CMakeFiles/WebDriver.dir/CommandResult.cpp.o Source/WebDriver/CMakeFiles/WebDriver.dir/HTTPServer.cpp.o Source/WebDriver/CMakeFiles/WebDriver.dir/Session.cpp.o Source/WebDriver/CMakeFiles/WebDriver.dir/SessionHost.cpp.o Source/WebDriver/CMakeFiles/WebDriver.dir/WebDriverMain.cpp.o Source/WebDriver/CMakeFiles/WebDriver.dir/WebDriverService.cpp.o Source/WebDriver/CMakeFiles/WebDriver.dir/__/__/DerivedSources/WebDriver/WebDriverAtoms.cpp.o Source/WebDriver/CMakeFiles/WebDriver.dir/glib/SessionHostGlib.cpp.o Source/WebDriver/CMakeFiles/WebDriver.dir/glib/WebDriverServiceGLib.cpp.o Source/WebDriver/CMakeFiles/WebDriver.dir/gtk/WebDriverServiceGtk.cpp.o Source/WebDriver/CMakeFiles/WebDriver.dir/soup/HTTPServerSoup.cpp.o  -o bin/WebKitWebDriver  lib/libWTFGTK.a /usr/lib/i386-linux-gnu/libsoup-2.4.so lib/libbmalloc.a -ldl /usr/lib/i386-linux-gnu/libicudata.so /usr/lib/i386-linux-gnu/libicui18n.so /usr/lib/i386-linux-gnu/libicuuc.so -lpthread /usr/lib/i386-linux-gnu/libgio-2.0.so /usr/lib/i386-linux-gnu/libgobject-2.0.so /usr/lib/i386-linux-gnu/libglib-2.0.so /usr/lib/i386-linux-gnu/libz.so && :
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/Assertions.cpp.o):Assertions.cpp:function WTFLoggingAccumulator::accumulate(WTF::String const&): error: undefined reference to '__atomic_compare_exchange_1'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/Assertions.cpp.o):Assertions.cpp:function WTFLoggingAccumulator::accumulate(WTF::String const&): error: undefined reference to '__atomic_compare_exchange_1'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/Assertions.cpp.o):Assertions.cpp:function WTFLoggingAccumulator::resetAccumulatedLogs(): error: undefined reference to '__atomic_compare_exchange_1'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/Assertions.cpp.o):Assertions.cpp:function WTFLoggingAccumulator::resetAccumulatedLogs(): error: undefined reference to '__atomic_compare_exchange_1'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/ParkingLot.cpp.o):ParkingLot.cpp:function WTF::ThreadSpecific<WTF::RefPtr<WTF::(anonymous namespace)::ThreadData, WTF::DumbPtrTraits<WTF::(anonymous namespace)::ThreadData> >, (WTF::CanBeGCThread)1>::destroy(void*): error: undefined reference to '__atomic_fetch_sub_4'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/ParkingLot.cpp.o):ParkingLot.cpp:function WTF::ThreadSpecific<WTF::RefPtr<WTF::(anonymous namespace)::ThreadData, WTF::DumbPtrTraits<WTF::(anonymous namespace)::ThreadData> >, (WTF::CanBeGCThread)1>::destroy(void*): error: undefined reference to '__atomic_compare_exchange_4'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/ParkingLot.cpp.o):ParkingLot.cpp:function WTF::ThreadSpecific<WTF::RefPtr<WTF::(anonymous namespace)::ThreadData, WTF::DumbPtrTraits<WTF::(anonymous namespace)::ThreadData> >, (WTF::CanBeGCThread)1>::destroy(void*): error: undefined reference to '__atomic_fetch_sub_4'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/ParkingLot.cpp.o):ParkingLot.cpp:function WTF::(anonymous namespace)::ensureHashtable(): error: undefined reference to '__atomic_compare_exchange_4'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/ParkingLot.cpp.o):ParkingLot.cpp:function WTF::(anonymous namespace)::ensureHashtable(): error: undefined reference to '__atomic_compare_exchange_4'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/ParkingLot.cpp.o):ParkingLot.cpp:function WTF::(anonymous namespace)::ensureHashtable(): error: undefined reference to '__atomic_compare_exchange_4'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/ParkingLot.cpp.o):ParkingLot.cpp:function WTF::ParkingLot::parkConditionallyImpl(void const*, WTF::ScopedLambda<bool ()> const&, WTF::ScopedLambda<void ()> const&, WTF::TimeWithDynamicClockType const&): error: undefined reference to '__atomic_fetch_sub_4'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/ParkingLot.cpp.o):ParkingLot.cpp:function WTF::ParkingLot::parkConditionallyImpl(void const*, WTF::ScopedLambda<bool ()> const&, WTF::ScopedLambda<void ()> const&, WTF::TimeWithDynamicClockType const&): error: undefined reference to '__atomic_fetch_sub_4'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/Threading.cpp.o):Threading.cpp:function WTF::Thread::removeFromThreadGroup(WTF::AbstractLocker const&, WTF::ThreadGroup&): error: undefined reference to '__atomic_fetch_add_4'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/Threading.cpp.o):Threading.cpp:function WTF::Thread::removeFromThreadGroup(WTF::AbstractLocker const&, WTF::ThreadGroup&): error: undefined reference to '__atomic_fetch_add_4'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/Threading.cpp.o):Threading.cpp:function WTF::Thread::removeFromThreadGroup(WTF::AbstractLocker const&, WTF::ThreadGroup&): error: undefined reference to '__atomic_fetch_add_4'
lib/libWTFGTK.a(lib/../Source/WTF/wtf/CMakeFiles/WTF.dir/Threading.cpp.o):Threading.cpp:function WTF::Thread::removeFromThreadGroup(WTF::AbstractLocker const&, WTF::ThreadGroup&): error: undefined reference to '__atomic_fetch_add_4'
collect2: error: ld returned 1 exit status
[1552/3276] Generate bindings (WebCoreBindings)
ninja: build stopped: subcommand failed.

Although, it compiled if the -march was i686. Is this OK? Because it seems that the Debian packages are built for i386 here:
https://packages.debian.org/stretch/i386/libwebkitgtk-3.0-dev/download
Comment 1 Alberto Garcia 2018-08-14 02:44:18 PDT
As far as I'm aware Debian i386 packages are built for 686-class processors. See https://lists.debian.org/debian-devel/2015/09/msg00589.html

Those atomic primitives need CPU instructions not available in older
processors. You can try the following test.cpp file:

    #include <atomic>
    int main()
    {
         std::atomic<int64_t> i(0);
         i++;
         return 0;
    }

And now:

    $ g++ -o test test.cpp

    $ g++ -o test test.cpp -march=i386
    /usr/bin/ld: /tmp/ccJF5W0r.o: in function `std::__atomic_base<long long>::operator++(int)':
    test.cpp:(.text._ZNSt13__atomic_baseIxEppEi[_ZNSt13__atomic_baseIxEppEi]+0x41): undefined reference to `__atomic_fetch_add_8'
    collect2: error: ld returned 1 exit status

You need to add -latomic:

    $ g++ -o test test.cpp -march=i386 -latomic

There's a test in Source/cmake/WebKitCompilerFlags.cmake that should
detect automatically whether you need to pass -latomic or not. If that
doesn't work in your case it must be because you're building with
-march=i386 but the test is built for a more recent CPU.

If you debug this issue and find a problem with the test, please tell us.

That said, I'm not sure how well a recent WebKitGTK+ will work in such
an old CPU (if at all).
Comment 2 karogyoker2+webkit 2018-08-15 06:44:35 PDT
When I built like this:
cmake -DPORT=GTK -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-march=i386 -latomic" -DCMAKE_CXX_FLAGS="-march=i386 -latomic" -DUSE_WOFF2=OFF -GNinja

It built, and WebKit is also working.

"Those atomic primitives need CPU instructions not available in older
processors."

Which instructions are these? After a quick search I found these atomic operations are using the lock instruction[1,2] but that's available since the 8086[3]. Maybe the 80386 doesn't support a hardware implementation for __atomic_fetch_sub and __atomic_compare_exchange but it only does for other atomic operations?

We could fix the test in WebKitCompilerFlags.cmake by setting the CXX flags before running the test to include the flags which are provided by the user when it was initially starting cmake. This way "-march=i386" would be used by the compiler and it would fail the test. But this would only make sense if the 80386 would be able to run the compiled code. Currently I don't see why it could not.

[1]: http://www.mohawksoft.org/?q=node/78
[2]: https://stackoverflow.com/questions/38447226/atomicity-on-x86
[3]: https://en.wikipedia.org/wiki/X86_instruction_listings#Original_8086/8088_instructions
Comment 3 Alberto Garcia 2018-08-15 06:51:54 PDT
(In reply to karogyoker2+webkit from comment #2)
> We could fix the test [...] But this would only make sense if the
> 80386 would be able to run the compiled code. Currently I don't see
> why it could not.

I suppose my questions are:

- Did you try it? Is it usable? Does it even run? :-)

- What's the use case? Is there an actual machine where you are
  planning to run this?
Comment 4 karogyoker2+webkit 2018-08-15 08:29:14 PDT
> - Did you try it? Is it usable? Does it even run? :-)
> 
> - What's the use case? Is there an actual machine where you are
>   planning to run this?

Sadly, I don't have a 386 yet, but then it is time to have one, so I can test this. I'm gonna buy one and try this out. Or, maybe it is easier to test this in Bochs with an emulated 386. I'll come back with the results.
Comment 5 Alberto Garcia 2018-08-15 08:55:23 PDT
(In reply to karogyoker2+webkit from comment #4)
> > - Did you try it? Is it usable? Does it even run? :-)
> >
> > - What's the use case? Is there an actual machine where you are
> >   planning to run this?

> Sadly, I don't have a 386 yet, but then it is time to have one, so I
> can test this.

You still didn't tell me the use case :-)

Why do you need to make WebKitGTK+ work on a 386?

Who is using a 386 in 2018, and why would anyone get one?
Comment 6 karogyoker2+webkit 2018-08-15 09:03:16 PDT
> You still didn't tell me the use case :-)
> 
> Why do you need to make WebKitGTK+ work on a 386?
> 
> Who is using a 386 in 2018, and why would anyone get one?

The use case would be that I do a google search on a 386 (and possibly other things), for the same reason I did it on a Nokia 6030. It was fun, so the use case would be recreation, like watching cat videos, just much better. WebKit would be much usable because it is up to date, on the Nokia 6030 a lot of pages didn't load due to it didn't support modern TLS protocols.
Comment 7 Alberto Garcia 2018-08-15 09:56:55 PDT
(In reply to karogyoker2+webkit from comment #6)
> > Why do you need to make WebKitGTK+ work on a 386?
> The use case would be that I do a google search on a 386 (and
> possibly other things), for the same reason I did it on a Nokia
> 6030. It was fun, so the use case would be recreation, like watching
> cat videos, just much better.

Ok, if it's for personal recreation then you can make it work by
passing -latomic manually as we saw earlier.

If you think the compiler flag tests can be improved and you have a
patch that does it we'll be happy to have a look at it, but please
realize that detecting whether to use the -latomic flags properly in
all supported architectures has been a small source of headaches for a
while, so you'll need to convince me that it won't break anything :-)

I'm closing this bug, you can reopen it if/when you have a patch.
Comment 8 karogyoker2+webkit 2018-08-15 10:33:32 PDT
Yes, I absolutely agree, I can build it for myself and if somebody else wants to do the same in the future he will find the solution here. Do not risk to break something if it is working fine now, just because of this unimportant edge case.
Comment 9 karogyoker2+webkit 2018-08-16 06:26:41 PDT
It seems it wouldn't work anyways: https://hothardware.com/news/sorry-intel-386dxsx-owners-no-new-linux-for-you