Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libc++ cmath math functions not found because of -isystem $PREFIX/include added by CMake #1149

Closed
joakim-noah opened this issue Jul 18, 2017 · 23 comments
Labels
bug report Something is not working properly

Comments

@joakim-noah
Copy link
Contributor

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.

@its-pointless
Copy link
Contributor

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...

@joakim-noah
Copy link
Contributor Author

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.

@Neo-Oli Neo-Oli added the bug report Something is not working properly label Jul 19, 2017
@fornwall
Copy link
Member

Does the recent update to cmake 3.9 improve things?

@joakim-noah
Copy link
Contributor Author

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.

@fornwall
Copy link
Member

@joakim-noah Does the patch in android/ndk#467 fix the problem?

@joakim-noah
Copy link
Contributor Author

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.

@joakim-noah
Copy link
Contributor Author

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#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.

@stephengroat
Copy link
Contributor

stephengroat commented Nov 29, 2017

I no longer see this issue when compiling llvm but still see it with cmake, can anyone else confirm?

@joakim-noah
Copy link
Contributor Author

Never saw it with llvm but with ldc, which was pulling in cmath from an llvm header, but yeah, still happening with CMake.

@johncant
Copy link

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.

@joakim-noah
Copy link
Contributor Author

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.

@fornwall
Copy link
Member

fornwall commented Jan 3, 2018

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?

@ghost
Copy link

ghost commented Jan 3, 2018

@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

@stephengroat
Copy link
Contributor

@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;
      ~~^

@joakim-noah
Copy link
Contributor Author

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.

fornwall added a commit that referenced this issue Jan 14, 2018
@stephengroat
Copy link
Contributor

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".

@finagolfin
Copy link
Member

This broke with the latest NDK update, @its-pointless forgot to move the patch over to ndk-sysroot?

@its-pointless
Copy link
Contributor

@buttaface
#3562 is this the only file that needs to be patched?

@its-pointless
Copy link
Contributor

i guess this illustrates the benefits of regression testing.

@finagolfin
Copy link
Member

Two math C++ includes, you got them both now.

@stale
Copy link

stale bot commented Nov 18, 2021

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.

@stale stale bot added the wontfix Issue won't be fixed label Nov 18, 2021
@finagolfin finagolfin added not stale and removed wontfix Issue won't be fixed labels Nov 19, 2021
Grimler91 added a commit that referenced this issue Feb 18, 2022
Build fails with similar error as in
#1149
@xtkoba xtkoba removed the not stale label Dec 24, 2022
@stale stale bot added the inactive No activity in a certain period of time label Mar 9, 2023
@twaik
Copy link
Member

twaik commented Mar 14, 2024

Is this issue still relevant?

@stale stale bot removed the inactive No activity in a certain period of time label Mar 14, 2024
@finagolfin
Copy link
Member

I don't think so, as I recently removed the workaround for this, 395e1c9, and nobody complained.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug report Something is not working properly
Projects
None yet
Development

No branches or pull requests

9 participants