Closed russel closed 7 years ago
Is this on a standard intel cpu?
Can you run the make command using verbose=1
so something like:
make verbose=1
instead of
make
and paste the output here?
Its going to be a lot more output. At the moment, I'm most interested in verifying that the -mcx16
flag is being passed to cc
when building.
also, can you run
getconf LONG_BIT
in the terminal and report the result here? i'm expecting to see 64.
Just the end of the output, confirming the hypothesis.:
cc -MMD -MP -march=native -mtune=generic -Werror -Wconversion -Wno-sign-conversion -Wextra -Wall -mcx16 -O3 -DNDEBUG -std=gnu11 -fexceptions -DPONY_VERSION=\"0.11.4-077c27605\" -DLLVM_VERSION=\"3.9.1\" -DPONY_COMPILER=\"cc\" -DPONY_ARCH=\"native\" -DBUILD_COMPILER=\""cc (GCC) 7.0.1 20170309 (Red Hat 7.0.1-0.12)"\" -DPONY_BUILD_CONFIG=\"release\" -D_FILE_OFFSET_BITS=64 -fpic -c -o build/release/obj/libponyrt-pic/gc/cycle.o src/libponyrt/gc/cycle.c -I src/common/ -I src/libponyrt/
gc.c
cc -MMD -MP -march=native -mtune=generic -Werror -Wconversion -Wno-sign-conversion -Wextra -Wall -mcx16 -O3 -DNDEBUG -std=gnu11 -fexceptions -DPONY_VERSION=\"0.11.4-077c27605\" -DLLVM_VERSION=\"3.9.1\" -DPONY_COMPILER=\"cc\" -DPONY_ARCH=\"native\" -DBUILD_COMPILER=\""cc (GCC) 7.0.1 20170309 (Red Hat 7.0.1-0.12)"\" -DPONY_BUILD_CONFIG=\"release\" -D_FILE_OFFSET_BITS=64 -fpic -c -o build/release/obj/libponyrt-pic/gc/gc.o src/libponyrt/gc/gc.c -I src/common/ -I src/libponyrt/
Linking libponyrt-pic
gcc-ar rcs build/release/libponyrt-pic.a build/release/obj/libponyrt-pic/actor/actor.o build/release/obj/libponyrt-pic/actor/messageq.o build/release/obj/libponyrt-pic/ds/fun.o build/release/obj/libponyrt-pic/ds/hash.o build/release/obj/libponyrt-pic/ds/stack.o build/release/obj/libponyrt-pic/ds/list.o build/release/obj/libponyrt-pic/options/options.o build/release/obj/libponyrt-pic/mem/pool.o build/release/obj/libponyrt-pic/mem/heap.o build/release/obj/libponyrt-pic/mem/pagemap.o build/release/obj/libponyrt-pic/mem/alloc.o build/release/obj/libponyrt-pic/asio/event.o build/release/obj/libponyrt-pic/asio/epoll.o build/release/obj/libponyrt-pic/asio/asio.o build/release/obj/libponyrt-pic/platform/threads.o build/release/obj/libponyrt-pic/platform/ponyassert.o build/release/obj/libponyrt-pic/lang/lsda.o build/release/obj/libponyrt-pic/lang/posix_except.o build/release/obj/libponyrt-pic/lang/io.o build/release/obj/libponyrt-pic/lang/time.o build/release/obj/libponyrt-pic/lang/stdfd.o build/release/obj/libponyrt-pic/lang/socket.o build/release/obj/libponyrt-pic/lang/paths.o build/release/obj/libponyrt-pic/lang/directory.o build/release/obj/libponyrt-pic/lang/ssl.o build/release/obj/libponyrt-pic/lang/stat.o build/release/obj/libponyrt-pic/sched/mpmcq.o build/release/obj/libponyrt-pic/sched/scheduler.o build/release/obj/libponyrt-pic/sched/cpu.o build/release/obj/libponyrt-pic/sched/start.o build/release/obj/libponyrt-pic/gc/trace.o build/release/obj/libponyrt-pic/gc/actormap.o build/release/obj/libponyrt-pic/gc/serialise.o build/release/obj/libponyrt-pic/gc/objectmap.o build/release/obj/libponyrt-pic/gc/delta.o build/release/obj/libponyrt-pic/gc/cycle.o build/release/obj/libponyrt-pic/gc/gc.o
gtest-all.cc
g++ -MMD -MP -march=native -mtune=generic -Werror -Wall -mcx16 -O3 -DNDEBUG -std=gnu++11 -fno-rtti -c -o build/release/obj/libgtest/gtest-all.o lib/gtest/gtest-all.cc -isystem lib/gtest/
Linking libgtest
gcc-ar rcs build/release/libgtest.a build/release/obj/libgtest/gtest-all.o
gbenchmark_main.cc
g++ -MMD -MP -march=native -mtune=generic -Werror -Wall -mcx16 -O3 -DNDEBUG -std=gnu++11 -fno-rtti -DHAVE_POSIX_REGEX -c -o build/release/obj/libgbenchmark/gbenchmark_main.o lib/gbenchmark/gbenchmark_main.cc -isystem lib/gbenchmark/include/
gbenchmark-all.cc
g++ -MMD -MP -march=native -mtune=generic -Werror -Wall -mcx16 -O3 -DNDEBUG -std=gnu++11 -fno-rtti -DHAVE_POSIX_REGEX -c -o build/release/obj/libgbenchmark/gbenchmark-all.o lib/gbenchmark/gbenchmark-all.cc -isystem lib/gbenchmark/include/
Linking libgbenchmark
gcc-ar rcs build/release/libgbenchmark.a build/release/obj/libgbenchmark/gbenchmark_main.o build/release/obj/libgbenchmark/gbenchmark-all.o
main.c
cc -MMD -MP -march=native -mtune=generic -Werror -Wconversion -Wno-sign-conversion -Wextra -Wall -mcx16 -O3 -DNDEBUG -std=gnu11 -fexceptions -DPONY_VERSION=\"0.11.4-077c27605\" -DLLVM_VERSION=\"3.9.1\" -DPONY_COMPILER=\"cc\" -DPONY_ARCH=\"native\" -DBUILD_COMPILER=\""cc (GCC) 7.0.1 20170309 (Red Hat 7.0.1-0.12)"\" -DPONY_BUILD_CONFIG=\"release\" -D_FILE_OFFSET_BITS=64 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -c -o build/release/obj/ponyc/main.o src/ponyc/main.c -I src/common/ -I src/libponyrt/
Linking ponyc
g++ -o build/release/ponyc build/release/obj/ponyc/main.o -march=native -mtune=generic -mcx16 -L build/release -L/usr/lib64 -lponyc -lponyrt -lLLVM-3.9 -lz -lncurses -lpthread -ldl -rdynamic
build/release/libponyrt.a(pool.o): In function `pool_get.constprop.5':
pool.c:(.text+0x56b): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_alloc':
pool.c:(.text+0x6eb): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_free':
pool.c:(.text+0x8a3): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_alloc_size':
pool.c:(.text+0xc5f): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_free_size':
pool.c:(.text+0x1065): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o):pool.c:(.text+0x1132): more undefined references to `__atomic_compare_exchange_16' follow
collect2: error: ld returned 1 exit status
make: *** [Makefile:662: build/release/ponyc] Error 1
Output as requested:
|> getconf LONG_BIT
64
Thanks @russel. Well, that is all very confusing.
If you have a gcc 6/debian machine available could you build pony on that with verbose=1
and paste the "linking" portion here so we can compare it to the fedora/gcc 7 version:
g++ -o build/release/ponyc build/release/obj/ponyc/main.o -march=native -mtune=generic -mcx16 -L build/release -L/usr/lib64 -lponyc -lponyrt -lLLVM-3.9 -lz -lncurses -lpthread -ldl -rdynamic
Also can you try:
g++ -o build/release/ponyc build/release/obj/ponyc/main.o -march=native -mtune=generic -mcx16 -L build/release -L/usr/lib64 -lponyc -lponyrt -lLLVM-3.9 -lz -lncurses -lpthread -latomic -ldl -rdynamic
on Fedora and see if linking is successful.
The Fedora experiment on a compiled up repository:
|> make verbose=1
Linking ponyc
g++ -o build/release/ponyc build/release/obj/ponyc/main.o -march=native -mtune=generic -mcx16 -L build/release -L/usr/lib64 -lponyc -lponyrt -lLLVM-3.9 -lz -lncurses -lpthread -ldl -rdynamic
build/release/libponyrt.a(pool.o): In function `pool_get.constprop.5':
pool.c:(.text+0x56b): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_alloc':
pool.c:(.text+0x6eb): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_free':
pool.c:(.text+0x8a3): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_alloc_size':
pool.c:(.text+0xc5f): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_free_size':
pool.c:(.text+0x1065): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o):pool.c:(.text+0x1132): more undefined references to `__atomic_compare_exchange_16' follow
collect2: error: ld returned 1 exit status
make: *** [Makefile:662: build/release/ponyc] Error 1
1011 anglides:/home/Checkouts/Git/PonyC (git:master)
|> g++ -o build/release/ponyc build/release/obj/ponyc/main.o -march=native -mtune=generic -mcx16 -L build/release -L/usr/lib64 -lponyc -lponyrt -lLLVM-3.9 -lz -lncurses -lpthread -latomic -ldl -rdynamic
/usr/bin/ld: cannot find /usr/lib64/libatomic.so.1.2.0
collect2: error: ld returned 1 exit status
install the libatomic package and:
|> make verbose=1
Linking ponyc
g++ -o build/release/ponyc build/release/obj/ponyc/main.o -march=native -mtune=generic -mcx16 -L build/release -L/usr/lib64 -lponyc -lponyrt -lLLVM-3.9 -lz -lncurses -lpthread -ldl -rdynamic
build/release/libponyrt.a(pool.o): In function `pool_get.constprop.5':
pool.c:(.text+0x56b): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_alloc':
pool.c:(.text+0x6eb): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_free':
pool.c:(.text+0x8a3): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_alloc_size':
pool.c:(.text+0xc5f): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_free_size':
pool.c:(.text+0x1065): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o):pool.c:(.text+0x1132): more undefined references to `__atomic_compare_exchange_16' follow
collect2: error: ld returned 1 exit status
make: *** [Makefile:662: build/release/ponyc] Error 1
1013 anglides:/home/Checkouts/Git/PonyC (git:master)
|> g++ -o build/release/ponyc build/release/obj/ponyc/main.o -march=native -mtune=generic -mcx16 -L build/release -L/usr/lib64 -lponyc -lponyrt -lLLVM-3.9 -lz -lncurses -lpthread -latomic -ldl -rdynamic
So, what I'm thinking you might have to install libatomic on Fedora.
https://www.rpmfind.net/linux/rpm2html/search.php?query=libatomic
But really, I'm mostly guessing here. The g++ atomics support should have those functions. The only errors I can see people hitting are on non-intel platforms and then the -mcx16
should solve that.
So my guess would be is that Fedora is doing something interesting with atomics support with gcc and packaging it differently than other platforms and that you have to explicitly install libatomic and you need to explicitly link against it, but, I could be very wrong on that. At the moment, it seems to be the most reasonable explanation.
Do you want me to ask the RedHat GCC folk to take a peek?
I can't do the Debian test just yet I'm afraid, long story. I will as soon as I can.
@russel if you are in a position to ask them where you think they might respond, by all means. I don't have access to a fedora system so I'm flying blind here.
If you don't have a libatomic installed, I'd first try installing it and trying the last g++
command again. In an attempt to quickly disprove my idea. If that isn't it, then I'm at a loss at this point in time. Hopefully either RH GCC folks or someone in pony community who uses Fedora could assist further.
I have sent email to a person I know will either know the answer or know the person to ask to get a definitive answer.
I don't know what Debian does, but Fedora's GCC is fairly close to the upstream GCC config. There is a separate package for libatomic though.
dnf install libatomic
but you might also need to add -latomic
to the linker flags.
Note that the -mcx16
flag is ABI changing, so creates objects that are incompatible with objects compiled without it. It could be that your hardware doesn't support CMPXCHG16B and so gcc is issuing calls to libatomic that other people aren't getting, because they have different hardware.
OK, I have now rebooted to Debian Sid. I have libatomic1 installed automatically because I have TBB and libgcc-6-dev installed, both of which require the atomics. I am guessing Fedora doesn't have an equivalent for this so libatomics must be installed manually. Interestingly I have TBB installed on Fedora, but atomics didn't get installed as a dependency. Oh well.
For the same data as provided earlier for Fedora but now for Debian:
|> getconf LONG_BIT
64
Linking ponyc
g++ -o build/release/ponyc build/release/obj/ponyc/main.o -march=native -mtune=generic -mcx16 -L build/release -L/usr/lib/llvm-3.9/lib -lponyc -lponyrt -lLLVM-3.9 -lz -lncurses -lpthread -ldl -rdynamic
use.cc
so no -latomics, and no error.
@russel is libatomic installed on Fedora?
@jwakely thank you for the info!
I have now manually install libatomic on Fedora, but this is now a different computer, a laptop rather than a workstation. This is though a good test since it is a different processor and memory architecture. Just running "make verbose=1" on the Fedora Rawhide laptop results in the same behaviour as before even with libatomic installed:
Linking ponyc
g++ -o build/release/ponyc build/release/obj/ponyc/main.o -march=native -mtune=generic -mcx16 -L build/release -L/usr/lib64 -lponyc -lponyrt -lLLVM-3.9 -lz -lncurses -lpthread -ldl -rdynamic
build/release/libponyrt.a(pool.o): In function `pool_get.constprop.5':
pool.c:(.text+0x56b): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_alloc':
pool.c:(.text+0x6eb): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_free':
pool.c:(.text+0x8a3): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_alloc_size':
pool.c:(.text+0xc5f): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_free_size':
pool.c:(.text+0x1065): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o):pool.c:(.text+0x1132): more undefined references to `__atomic_compare_exchange_16' follow
collect2: error: ld returned 1 exit status
make: *** [Makefile:662: build/release/ponyc] Error 1
1006 lavaine:/home/Checkouts/Git/PonyC (git:master)
|> g++ -o build/release/ponyc build/release/obj/ponyc/main.o -march=native -mtune=generic -mcx16 -L build/release -L/usr/lib64 -lponyc -lponyrt -lLLVM-3.9 -latomic -lz -lncurses -lpthread -ldl -rdynamic
so whilst an explicit -latomic is needed on Fedora it is not on Debian. I wonder if using CMake, SCons or Meson, would get rid of the problem as the use of pkg-config should get all the dependencies right. Of course this can be done in Make, but it is a lot harder.
The real concern though, given the separateness of the atomics library, how did this ever work on Debian?
So to verify, @russel. If libatomics
is installed and -latomic
is added to the linking, it works.
Correct?
It definitely seems that way. If you make the change to the build, I can check on Debian and Fedora to make sure no change on Debian and success on Fedora.
The real concern though, given the separateness of the atomics library, how did this ever work on Debian?
GCC will try to lower the C atomic operations to hardware instructions instead of library calls when it can. Maybe GCC is configured differently on Debian and Fedora, with only one being able to detect that the hardware supports the relevant atomic operations.
@sylvanc thinks this is a GCC 7.0 issue. we need to do a travis run with gcc 7.0 and see what goes boom.
We can't get gcc 7 on travis. At this time, we don't support gcc 7 yet.
I finally got this working on Archlinux with GCC 7.1.1
$ ponyc -v
0.14.0-f70dba091 [release]
compiled with: llvm 3.9.1 -- cc (GCC) 7.1.1 20170516
diff --git a/Makefile b/Makefile
index a795d8f57..dd8923b97 100644
--- a/Makefile
+++ b/Makefile
@@ -437,11 +437,11 @@ libponyc.benchmarks.links = libgbenchmark libponyc libponyrt llvm
libponyrt.benchmarks.links = libgbenchmark libponyrt
ifeq ($(OSTYPE),linux)
- ponyc.links += libpthread libdl
- libponyc.tests.links += libpthread libdl
- libponyrt.tests.links += libpthread libdl
- libponyc.benchmarks.links += libpthread libdl
- libponyrt.benchmarks.links += libpthread libdl
+ ponyc.links += libpthread libdl libatomic
+ libponyc.tests.links += libpthread libdl libatomic
+ libponyrt.tests.links += libpthread libdl libatomic
+ libponyc.benchmarks.links += libpthread libdl libatomic
+ libponyrt.benchmarks.links += libpthread libdl libatomic
endif
I could install both gcc6 an gcc7 on a debian sid docker container and got the same error with CC=gcc-7
. Given that travis allows the use of containers, it worth it building such a docker to test gcc-7 – and even most of major linux distro incoming releases (at least once in a while)–. I could make the gcc-7 Dockerfile, if needed.
EDIT: this ponyc itself cannot link pony programs, now as libatomic is also needed (I'm sure it's NOT the correct way but it works for me):
diff --git a/src/libponyc/codegen/genexe.c b/src/libponyc/codegen/genexe.c
index 304a6f675..a063818d8 100644
--- a/src/libponyc/codegen/genexe.c
+++ b/src/libponyc/codegen/genexe.c
@@ -277,7 +277,7 @@ static bool link_exe(compile_t* c, ast_t* program,
#ifdef PONY_USE_LTO
"-flto -fuse-linker-plugin "
#endif
- "%s %s %s %s -lpthread %s -lm %s",
+ "%s %s %s %s -lpthread -latomic %s -lm %s",
linker, file_exe, arch, mcx16_arg, fuseld, file_o, lib_args, ponyrt, ldl,
export
);
@lisael That would be the correct way for the code changes. Would you be up for doing a PR with those changes?
I think the only question remaining is whether we need to setup a test environment with GCC 7. @ponylang/committer Thoughts?
Test environment for GCC 7 seems like a good idea
I'd like to suggest raising the priority on this one, if I may. Whilst this used to be a Rawhide only problem, it is now a Debian Sid problem: Debian Sid has just moved from GCC 6 to GCC 7 as the default compiler suite, so the bug originally reported as not being a problem on Debian Sid is now a problem, on Debian Sid:
build/release/libponyrt.a(pool.o): In function `pool_get.constprop.5':
pool.c:(.text+0x4aa): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_alloc':
pool.c:(.text+0x5da): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_free':
pool.c:(.text+0x73e): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_alloc_size':
pool.c:(.text+0x871): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o): In function `ponyint_pool_free_size':
pool.c:(.text+0xaee): undefined reference to `__atomic_compare_exchange_16'
build/release/libponyrt.a(pool.o):pool.c:(.text+0xdee): more undefined references to `__atomic_compare_exchange_16' follow
collect2: error: ld returned 1 exit status
Makefile:704: recipe for target 'build/release/ponyc' failed
make: *** [build/release/ponyc] Error 1
I looked into this. It's a gcc bug. Woo hoo! I'm going to PR this and hope it doesn't break anything else.
PR opened: https://github.com/ponylang/ponyc/pull/2134
@russel @lisael can you test out this PR: https://github.com/ponylang/ponyc/pull/2134
I pulled the Git repository to 499a1dfffa479d54f0069fc21d901b58235496d9 on Debian Sid. I then did my usual:
make -j 8 install prefix=$HOME/Built config=release
and the resulting ~/Built/bin/ponyc seems to behave admirably.
|> ponyc --version
0.16.1-499a1dfff [release]
compiled with: llvm 3.9.1 -- cc (Debian 7.1.0-12) 7.1.0
Thanks @russel !
No problem. I am just worrying about the:
make default_pic=true
in the updated instructions on the front page, I haven't set the Make option default_pic.
@russel you dont have set it. it just means you no longer have to do
ponyc --pic
when compiling pony programs. its a new feature in 0.17.0 (which is being released tonight or tomorrow)
a99a1dfff compiles correctly for me too on archlinux. Thanks! (sorry I was on vacation and did not check my github notifications for a month or so)
@SeanTAllen Aha being able to lose the --pic option is good. :-)
@russel ya, it's "small" but we think it will be a big usability win. it was a great idea on @dipinhora's part.
Building Pony on Debian Sid works fine. When I try to build Pony on Fedora Rawhide, I get:
everything before this is fine. I am guessing this is a GCC version thing. Debian Sid has GCC 6.3 where Fedora Rawhide has GCC 7.0.
Update 2017-08-05: This is now a problem on Debian Sid as it has just switched to GCC 7 as the default compiler suite.