termux-packages
termux-packages copied to clipboard
libc++ cmath math functions not found because of -isystem $PREFIX/include added by CMake
Nice work switching everything over to libc++, I've been recompiling llvm and the latest ldc to use it, mostly no problems so far. However, there is an older pure C++ version of ldc that we maintain and it has a problem compiling a C++ file that calls some llvm headers that ultimately invoke cmath
:
In file included from /data/data/com.termux/files/home/src/ldc/dmd2/mars.h:70:
In file included from /data/data/com.termux/files/home/src/llvm-4.0.1.src/include/llvm/ADT/Triple.h:13:
In file included from /data/data/com.termux/files/home/src/llvm-4.0.1.src/include/llvm/ADT/Twine.h:13:
In file included from /data/data/com.termux/files/home/src/llvm-4.0.1.src/include/llvm/ADT/SmallVector.h:20:
In file included from /data/data/com.termux/files/home/src/llvm-4.0.1.src/include/llvm/Support/MathExtras.h:18:
In file included from /data/data/com.termux/files/home/src/llvm-4.0.1.src/include/llvm/Support/SwapByteOrder.h:19:
In file included from /data/data/com.termux/files/home/src/llvm-4.0.1.src/build/include/llvm/Support/DataTypes.h:33:
/data/data/com.termux/files/usr/bin/../include/c++/v1/cmath:319:9: error: no
member named 'isgreater' in the global namespace
using ::isgreater;
~~^ /data/data/com.termux/files/usr/bin/../include/c++/v1/cmath:320:9: error: no
member named 'isgreaterequal' in the global namespace using ::isgreaterequal;
~~^
/data/data/com.termux/files/usr/bin/../include/c++/v1/cmath:321:9: error: no
member named 'isless' in the global namespace
using ::isless;
~~^ /data/data/com.termux/files/usr/bin/../include/c++/v1/cmath:322:9: error: no
member named 'islessequal' in the global namespace
using ::islessequal;
~~^
/data/data/com.termux/files/usr/bin/../include/c++/v1/cmath:323:9: error: no
member named 'islessgreater' in the global namespace using ::islessgreater;
~~^ /data/data/com.termux/files/usr/bin/../include/c++/v1/cmath:324:9: error: no
member named 'isunordered' in the global namespace
using ::isunordered;
~~^
/data/data/com.termux/files/usr/bin/../include/c++/v1/cmath:325:9: error: no
member named 'isunordered' in the global namespace using ::isunordered;
~~^
11 errors generated.
Tracking this down, I found that the CXX_INCLUDES
generated by CMake has this definition, removing it fixes the problem:
-isystem /data/data/com.termux/files/usr/include
I can't find much info on how CXX_INCLUDES
is generated. What's weird is that I don't see that particular -isystem
flag for ldc 1.3 when compiling in Termux, so CMake seems to be behaving differently there.
I can reproduce with this sample file compiled in Termux:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double number, squareRoot;
cout << "Enter a number: ";
cin >> number;
// sqrt() is a library function to calculate square root
squareRoot = sqrt(number);
cout << "Square root of " << number << " = " << squareRoot;
return 0;
}
Normal compilation, clang++ foo.cpp
, works, but this doesn't:
clang++ -isystem /data/data/com.termux/files/usr/include foo.cpp
I'm not sure if that should work or if CMake shouldn't be adding that flag, let me know.
yeah for c++ the first include should be include/c++/4.9.0 or include/c++/v1 or some variation. What can occur is that c++ includes in same dir as include. Cmake is changing the first include dir to onclude. Before we changed to libc++_shared cmake doing this likely had no effect so you wouldn't notice as it would find the right headers either first or second time round.
Then again i could be wrong...
Yeah, @its-pointless got it. It would try to get these functions from $PREFIX/include/c++/v1/math.h
normally, but with -isystem $PREFIX/include
appended, it's picking up the other math.h
from there first. I'll dig into why CMake is adding that extra -isystem
and see if it can be removed.
Does the recent update to cmake 3.9 improve things?
No, no difference with CMake 3.9.0. My guess is that CMake generates CXX_INCLUDES
by searching for header files and adds that directory automatically for the C++ version of ldc, but not for the mostly D version, which doesn't call those header files.
I just tried it on another phone on which I haven't upgraded Termux to use the latest ndk and libc++. It wasn't completely clean, as I didn't have an old CMake installed on there, so I had to install CMake 3.9 and libc++ but not the updated ndk packages, and I didn't hit this error there. Looks like CMake was adding -isystem $PREFIX/include
back then, but there was no math.h
in the C++ includes for clang to get confused by, only $PREFIX/include/math.h
and another $PREFIX/include/libandroid-support/math.h
that wasn't picked up.
It appears this issue is a consequence of adding another $PREFIX/include/c++/v1/math.h
when switching ndk-stl
over to libc++ and how that collides with this -isystem $PREFIX/include
that CMake always added, but is only causing a problem now.
@joakim-noah Does the patch in https://github.com/android-ndk/ndk/issues/467 fix the problem?
I don't think it will make a difference, as I originally ran into this problem with CMake 3.8.2 and his problem is that /usr/include
of the host system is being pulled into a cross-compile, whereas I'm natively compiling in Termux. I think the cause is having two different math.h
headers that are readily available now, I'll look into that.
Alright, spent some time tracking this down. The issue is that ldc's CMakeLists.txt
finds and includes the directory where libconfig.h
is located, which is $PREFIX/include
, since it uses the libconfig-dev
Termux package. It doesn't happen with the newer ldc 1.3, because an ldc contributor removed the dependency on libconfig by now.
As explained in android-ndk/ndk#452, adding that include_directories
in the old C++ version of ldc causes problems because it's placed first in the include search path, which the libc++ cmath
doesn't expect (the GNU STL cmath
didn't care, which is why it didn't matter before the switch). I tried setting CMAKE_SYSROOT
and CMAKE_SYSROOT_COMPILE
manually from the command-line, eg cmake -DCMAKE_SYSROOT=/data/data/com.termux/files
, and that makes CMake filter out CMAKE_SYSROOT/usr/include
from the CXX_INCLUDES
it generates, but it then fails because it adds a --sysroot=CMAKE_SYSROOT
.
I could work around this issue by simply removing the include_directories
line where $PREFIX/include
is added, but that's a hack, which will be a pain for others using CMake. Ideally, CMake should be able to filter out this path, we just need to figure out a way to make it do so, which won't break in other ways.
I no longer see this issue when compiling llvm
but still see it with cmake, can anyone else confirm?
Never saw it with llvm but with ldc, which was pulling in cmath
from an llvm header, but yeah, still happening with CMake.
I am seeing this issue while trying to compile opencv from their master on github. Removing -isystem /data/data/com.termux/files/usr/include
from the compiler command line fixes the issue but I can't find where cmake inserts it. My cmake is 3.10.1.
In my case, it is because of this line in the CmakeLists.txt
for the older C++ version of the project I'm building, which ends up trying to include /data/data/com.termux/files/usr/include
so it can use the libconfig-dev
header, as noted above. Commenting out that line fixes the issue for me, as it gets the header anyway.
Ideally, I guess CMake for Termux would be patched to ignore that system directory.
I just pushed out an updated version 16-4 of the ndk-stl package, which includes the following diff: https://github.com/termux/termux-packages/blob/master/packages/ndk-stl/math-header.diff
@joakim-noah @johncant @stephengroat @its-pointless Could you try it out and see if it fixes the problem here without causing new ones?
@fornwall, looks like that error is fixed now:
bash-4.4$ clang++ -isystem /data/data/com.termux/files/usr/include test.cpp
bash-4.4$ ./a.out
Enter a number: ^C
@fornwall i'm still getting the error on #1169 build system
[ 0%] Building CXX object lib/TableGen/CMakeFiles/LLVMTableGen.dir/Error.cpp.o
Scanning dependencies of target LLVMMC
In file included from /home/builder/.termux-build/libllvm/src/lib/BinaryFormat/Dwarf.cpp:14:
In file included from /home/builder/.termux-build/libllvm/src/include/llvm/BinaryFormat/Dwarf.h:24:
In file included from /home/builder/.termux-build/libllvm/build/include/llvm/Support/DataTypes.h:33:
/home/builder/.termux-build/_lib/16-aarch64-21-v3/lib/gcc/aarch64-linux-android/4.9.x/../../../../include/c++/4.9.x/cmath:313:9: error: no member named 'signbit' in
the global namespace
using ::signbit;
~~^
This patch fixes the issue for me with ldc, but it's just a workaround for the bigger issue: CMake needs to filter out the Termux $PREFIX/include when that include path is given higher priority by a CMakeLists.txt
. Otherwise, conflicts other than this math.h
one will likely crop up elsewhere.
on current system (as of 1/21/2018)
-- The C compiler identification is GNU 7.2.0
-- The CXX compiler identification is GNU 7.2.0
-- The ASM compiler identification is GNU
-- Found assembler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- broken
CMake Error at /home/builder/.termux-build/_cache/cmake-3.10.2/share/cmake-3.10/Modules/CMakeTestCCompiler.cmake:52 (message):
The C compiler
"/usr/bin/cc"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: /home/builder/.termux-build/libllvm/host-build/CMakeFiles/CMakeTmp
Run Build Command:"/usr/bin/make" "cmTC_d6752/fast"
/usr/bin/make -f CMakeFiles/cmTC_d6752.dir/build.make CMakeFiles/cmTC_d6752.dir/build
make[1]: Entering directory '/home/builder/.termux-build/libllvm/host-build/CMakeFiles/CMakeTmp'
Building C object CMakeFiles/cmTC_d6752.dir/testCCompiler.c.o
/usr/bin/cc -o CMakeFiles/cmTC_d6752.dir/testCCompiler.c.o -c /home/builder/.termux-build/libllvm/host-build/CMakeFiles/CMakeTmp/testCCompiler.c
Linking C executable cmTC_d6752
/home/builder/.termux-build/_cache/cmake-3.10.2/bin/cmake -E cmake_link_script CMakeFiles/cmTC_d6752.dir/link.txt --verbose=1
/usr/bin/cc CMakeFiles/cmTC_d6752.dir/testCCompiler.c.o -o cmTC_d6752
collect2: fatal error: ld terminated with signal 11 [Segmentation fault]
compilation terminated.
CMakeFiles/cmTC_d6752.dir/build.make:97: recipe for target 'cmTC_d6752' failed
make[1]: *** [cmTC_d6752] Error 1
make[1]: Leaving directory '/home/builder/.termux-build/libllvm/host-build/CMakeFiles/CMakeTmp'
Makefile:126: recipe for target 'cmTC_d6752/fast' failed
make: *** [cmTC_d6752/fast] Error 2
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt:54 (project)
-- Configuring incomplete, errors occurred!
See also "/home/builder/.termux-build/libllvm/host-build/CMakeFiles/CMakeOutput.log".
See also "/home/builder/.termux-build/libllvm/host-build/CMakeFiles/CMakeError.log".
This broke with the latest NDK update, @its-pointless forgot to move the patch over to ndk-sysroot?
@buttaface #3562 is this the only file that needs to be patched?
i guess this illustrates the benefits of regression testing.
Two math C++ includes, you got them both now.
This issue/PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Is this issue still relevant?
I don't think so, as I recently removed the workaround for this, 395e1c9a7, and nobody complained.