2

I am building Swift compiler from source on CentOS 6, and am running into a library issue. After fighting with the build script for a while I have got where running ./utils/build-script eventually gives:

+ /home/src/cmake-3.4.1-Linux-x86_64/bin/cmake --build /home/src/swift/build/Ninja-DebugAssert/cmark-linux-x86_64 -- all
ninja: no work to do.
llvm: using standard linker
+ cd /home/src/swift/build/Ninja-DebugAssert/llvm-linux-x86_64
+ /home/src/cmake-3.4.1-Linux-x86_64/bin/cmake -G Ninja -DCMAKE_C_COMPILER:PATH=clang -DCMAKE_CXX_COMPILER:PATH=clang++ '-DCMAKE_C_FLAGS= ' '-DCMAKE_CXX_FLAGS= ' -DCMAKE_BUILD_TYPE:STRING=Debug -DLLVM_ENABLE_ASSERTIONS:BOOL=TRUE -DLLVM_TOOL_SWIFT_BUILD:BOOL=NO '-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64' -DLLVM_INCLUDE_TESTS:BOOL=TRUE -LLVM_INCLUDE_DOCS:BOOL=TRUE -DCMAKE_INSTALL_PREFIX:PATH=/usr -DINTERNAL_INSTALL_PREFIX=local /home/src/swift/llvm
CMake Error at cmake/modules/CheckAtomic.cmake:36 (message):
  Host compiler appears to require libatomic, but cannot find it.
Call Stack (most recent call first):
  cmake/config-ix.cmake:296 (include)
  CMakeLists.txt:403 (include)


-- Configuring incomplete, errors occurred!
See also "/home/src/swift/build/Ninja-DebugAssert/llvm-linux-x86_64/CMakeFiles/CMakeOutput.log".
See also "/home/src/swift/build/Ninja-DebugAssert/llvm-linux-x86_64/CMakeFiles/CMakeError.log".
./utils/build-script: command terminated with a non-zero exit status 1, aborting

(gcc-4.8.2 was what I compiled llvm with)

libatomic is there:

$ locate libatomic
/opt/gcc-4.8.2/lib64/libatomic.a
/opt/gcc-4.8.2/lib64/libatomic.la
/opt/gcc-4.8.2/lib64/libatomic.so
/opt/gcc-4.8.2/lib64/libatomic.so.1
/opt/gcc-4.8.2/lib64/libatomic.so.1.0.0

I just don't know how to tell the build system where to look. I have tried the usual CMAKE_LIBRARY_PATH (exporting on the command line - I am not sure if cmake works like the way LD_LIBRARY_PATH, LIBRARY_PATH work) but it can't seem to find it.

I also don't have root on the machine.

Trevor
  • 1,111
  • 2
  • 18
  • 30
sgldiv
  • 623
  • 6
  • 16
  • 1
    I have been able to build Swift on CentOS 6.7 with partial success. Please see http://www.swiftprogrammer.info/swift_centos_2.html. Hope that helps! – Anatoli P Dec 27 '15 at 01:28

2 Answers2

1

CheckAtomic.cmake seems to be part of LLVM. I found a file at Github and it tries to find '__atomic_fetch_add_4' from libatomic

check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)

This fails for you. Check CMakeFiles/CMakeError.log to get more details why this test failed. Or try this line in a new project.

usr1234567
  • 21,601
  • 16
  • 108
  • 128
  • i think it fails because it can't find libatomic to link against. somehow it needs to be told where libatomic is – sgldiv Dec 15 '15 at 21:00
  • You are right, I missed one level of indention. Updated my answer. – usr1234567 Dec 16 '15 at 04:56
  • It first fails to compile the C++ file that includes , then tries this check_library_exists() unsuccessfully. If the C++ compilation succeeded, check_library_exists() wouldn't even be tried. BTW, I checked the log on CentOS 7.1, where it was build OK, and there the C++ file was compiled. If it got to the library test, it would have failed because even though libatomic.so can be found as part of 4.8.2 install from the repository, the content is bogus. – Anatoli P Dec 16 '15 at 05:25
  • With the 4.8.2 built from source, libatomic.so is not bogus and has the function being checked for, but the lib can't be found. That's with 4.4.7 still on the system. The only found and selected GCC is 4.4.7. With 4.4.7 uninstalled, no candidate GCC is found, and CMake fails well before the atomic test. – Anatoli P Dec 16 '15 at 06:27
  • @OmniProg You are aware that you can pass the path to your compiler via `CMAKE_CXX_COMPILER`? – usr1234567 Dec 16 '15 at 06:54
  • I sure am. However, the correct compiler, Clang, is selected by the script via that flag as can be seen from the original question. So, we are fine with the compiler selection. Yet Clang is highly dependent on GCC and Co. for headers and libraries, and those are picked incorrectly. – Anatoli P Dec 16 '15 at 07:12
1

I had not tried building from source on CentOS 6 until I saw this question, but I have been able to build Swift 2.2 on CentOS 7.1 and Ubuntu 14.04, with partial success. A few things to think about:

  • You will need numerous dependencies required to build Swift, and unless they happen to be already on the system, you will need root access to install them.
  • Use -R flag with the build-script to create a release build. Building in DebugAssert (the default) will require a lot of memory. In my case even 14 GB was not sufficient. A release build
    can be done with about 6 GB.

As for your specific problem, it is related to Clang's dependency on GCC-related packages for headers and libraries. See, for example, Fedora 21 with clang, without gcc.

Even if you installed GCC 4.8.2 and adjusted the path to use gcc and g++ from 4.8.2, Clang may still be looking in the old GCC directories for headers and libraries. CMake first tries to compile a C++ test file that includes the header atomic, which does not exist in the old GCC. So, it then tries to link a C test program that uses the library libatomic, which again doesn't exist in the old GCC. You can see this by looking at llvm/cmake/modules/CheckAtomic.cmake mentioned by usr1234567. CMakeError.log and CMakeOutput.log can also provide valuable insight. BTW, when I was building Swift on CentOS 7.1, I didn't run into this problem because GCC 4.8.2 was used by Clang for headers and libraries and the atomic header was found, so the C++ file got compiled. However, had the libatomic check been done, it would have failed, because libatomic.so in the repository-provided 4.8.2 has INPUT ( <name of some non-existent file> ), so trying to link with libatomic errors out.

I'm sure there are various ways of dealing with this issue, but what solved the problem for me was setting the following environment variables, please adjust to your specific setup:

export CPLUS_INCLUDE_PATH=/opt/gcc-4.8.2/include/c++/4.8.2:/opt/gcc-4.8.2/include/c++/4.8.2/x86_64-unknown-linux-gnu

export LIBRARY_PATH=/opt/gcc-4.8.2/lib64:/opt/gcc-4.8.2/lib/gcc/x86_64-unknown-linux-gnu/4.8.2

Also make sure that your 4.8.2 version of libstdc++.so is available to the dynamic linker at runtime. Since you don't have root, do

export LD_LIBRARY_PATH=/opt/gcc-4.8.2/lib64

If you had root, you could use ldconfig.

Before you start building Swift, you may want to try building, using Clang, a simple C program linking it with libatomic (the code doesn't actually have to use any symbols from the lib) and a simple C++ program that includes the <atomic> header. When compiling the C++ program, use the -std=c++11 compiler flag. If the C++ program compiles successfully, then it is not necessary for the libatomic linking test to be successful.

Interestingly, the CMakeOutput.log file still did not report finding GCC 4.8.2 as a candidate GCC installation, but the configuration/build worked well past the error.

Hopefully this helps. Please let us know if you run into something else.

Community
  • 1
  • 1
Anatoli P
  • 4,791
  • 1
  • 18
  • 22
  • clang is 3.8. i built it with llvm. if i recall right it wanted gcc 4.7 at least to compile swift. i am building it on a fat server so memory is not that big of deal. so far i have been able to get away with installing the dependencies and just sticking them on the path... (by the way, launching the buildscript with -m allows you to sidestep ninja, i still have some problems that way) – sgldiv Dec 15 '15 at 21:03
  • OK, thanks for the additional info. Clang built from source may have its own idiosyncrasies. Since I started playing with this last night, will continue tonight and let you know. Looks like a good exploration project. – Anatoli P Dec 15 '15 at 23:42
  • 1
    BTW, what's the last error in the CMakeError.log referred to in your original question? Does the problem occur when you use make files (-m option to the build script)? Did it happen when using ninja? Can you compile, using clang++, the C++ file, mentioned by another responder, that includes ? Does it compile if you use the -std=c++11 flag? – Anatoli P Dec 16 '15 at 01:24
  • CMakeError.log has CMakeError.log has FAILED: : && clang -DCHECK_FUNCTION_EXISTS=__atomic_fetch_add_4 CMakeFiles/cmTC_679a4.dir/CheckFunctionExists.c.o -o cmTC_679a4 -rdynamic -latomic -lm && : /usr/bin/ld: cannot find -latomic clang: error: linker command failed with exit code 1 (use -v to see invocation) ninja: build stopped. With -m I get.. + cmake --build /Unix_Makefiles-DebugAssert/llvm-linux-x86_64 -- -j64 all gmake: *** No rule to make target `all'. – sgldiv Dec 16 '15 at 04:14
  • In the CMakeOutput.log, in the same dir as CMakeError.log, there should be log messages about candidate GCC installations found and which of them was selected. Did it find *and* select your 4.8.2 installation? I just finally got my 4.8.2 built from source, so will take it for a spin. Devtools-2 didn't work. – Anatoli P Dec 16 '15 at 05:00
  • Thanks for the latest update. I can successfully link against libatomic after setting paths for Clang with export. However, the build script still fails with the same error. For some reason the build script is not picking up these. The raw cmake commands also don't have CMAKE_INCLUDE_PATH, CMAKE_LIBRARY_PATH set to what I have exported in the environment variables, and it doen't look to be picking up variables set from the command line. Anyway, thanks for looking deeply into this. – sgldiv Dec 17 '15 at 23:21
  • Strange. My build is almost half way done now... See what exactly CMakeError.log says. It should not even try to link with libatomic, but should successfully compile the C++ file that includes . Try to compile that file using clang++ directly. As for those CMAKE_* variables, I understand they are only used if CMake build files use certain functions; otherwise they are ignored. – Anatoli P Dec 18 '15 at 02:08