-
Notifications
You must be signed in to change notification settings - Fork 253
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
CMake toolchain file's CMAKE_CXX_COMPILER_ID_RUN=true
breaks compiler feature detection
#222
Comments
This may not be the ideal fix, but it seems to work fine, preserving cmake's ID and feature detection. --- a/android.toolchain.cmake
+++ b/android.toolchain.cmake
@@ -293,23 +293,21 @@
if(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows)
set(ANDROID_TOOLCHAIN_SUFFIX .exe)
endif()
+
+set(ANDROID_COMPILER_FLAGS)
+set(ANDROID_COMPILER_FLAGS_CXX)
+set(ANDROID_COMPILER_FLAGS_DEBUG)
+set(ANDROID_COMPILER_FLAGS_RELEASE)
+set(ANDROID_LINKER_FLAGS)
+set(ANDROID_LINKER_FLAGS_EXE)
+
if(ANDROID_TOOLCHAIN STREQUAL clang)
set(ANDROID_LLVM_TOOLCHAIN_PREFIX "${ANDROID_NDK}/toolchains/llvm/prebuilt/${ANDROID_HOST_TAG}/bin/")
set(ANDROID_C_COMPILER "${ANDROID_LLVM_TOOLCHAIN_PREFIX}clang${ANDROID_TOOLCHAIN_SUFFIX}")
set(ANDROID_CXX_COMPILER "${ANDROID_LLVM_TOOLCHAIN_PREFIX}clang++${ANDROID_TOOLCHAIN_SUFFIX}")
- # Clang can fail to compile if CMake doesn't correctly supply the target and
- # external toolchain, but to do so, CMake needs to already know that the
- # compiler is clang. Tell CMake that the compiler is really clang, but don't
- # use CMakeForceCompiler, since we still want compile checks. We only want
- # to skip the compiler ID detection step.
- set(CMAKE_C_COMPILER_ID_RUN TRUE)
- set(CMAKE_CXX_COMPILER_ID_RUN TRUE)
- set(CMAKE_C_COMPILER_ID Clang)
- set(CMAKE_CXX_COMPILER_ID Clang)
- set(CMAKE_C_COMPILER_TARGET ${ANDROID_LLVM_TRIPLE})
- set(CMAKE_CXX_COMPILER_TARGET ${ANDROID_LLVM_TRIPLE})
- set(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN "${ANDROID_TOOLCHAIN_ROOT}")
- set(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN "${ANDROID_TOOLCHAIN_ROOT}")
+ list(APPEND ANDROID_COMPILER_FLAGS
+ -target ${ANDROID_LLVM_TRIPLE}
+ -gcc-toolchain ${ANDROID_TOOLCHAIN_ROOT})
elseif(ANDROID_TOOLCHAIN STREQUAL gcc)
set(ANDROID_C_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}gcc${ANDROID_TOOLCHAIN_SUFFIX}")
set(ANDROID_CXX_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}g++${ANDROID_TOOLCHAIN_SUFFIX}")
@@ -323,13 +321,6 @@
message(FATAL_ERROR "Invalid Android sysroot: ${CMAKE_SYSROOT}.")
endif()
-set(ANDROID_COMPILER_FLAGS)
-set(ANDROID_COMPILER_FLAGS_CXX)
-set(ANDROID_COMPILER_FLAGS_DEBUG)
-set(ANDROID_COMPILER_FLAGS_RELEASE)
-set(ANDROID_LINKER_FLAGS)
-set(ANDROID_LINKER_FLAGS_EXE)
-
# Generic flags.
list(APPEND ANDROID_COMPILER_FLAGS
-g
|
This will require a custom toolchain file until android/ndk#222 is fixed.
It isn't clear to me how this avoids the problem mentioned in the deleted comment. My cmake-fu is weak though. I've passed this on to the person that owns our cmake toolchain, but he's OOO for a few more days. |
It avoids the problem of having CMake detect the target and external toolchain by manually supplying those values as part of CFLAGS/CXXFLAGS. With this change, CMake is able to automatically determine that the compiler is clang and perform its full set of compiler feature detection scripts. |
I believe configuring project in CMake to no language will skip the compiler detection, for example:
That way one can invoke |
The above proposed fix did not work for me when testing on Windows 10 :( EDIT: Nevermind, upon setting up a minimal example the above fix does work. However, I would use a slightly different fix: --- a/android.toolchain.cmake
+++ b/android.toolchain.cmake
if(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows)
set(ANDROID_TOOLCHAIN_SUFFIX .exe)
endif()
if(ANDROID_TOOLCHAIN STREQUAL clang)
set(ANDROID_LLVM_TOOLCHAIN_PREFIX "${ANDROID_NDK}/toolchains/llvm/prebuilt/${ANDROID_HOST_TAG}/bin/")
set(ANDROID_C_COMPILER "${ANDROID_LLVM_TOOLCHAIN_PREFIX}clang${ANDROID_TOOLCHAIN_SUFFIX}")
set(ANDROID_CXX_COMPILER "${ANDROID_LLVM_TOOLCHAIN_PREFIX}clang++${ANDROID_TOOLCHAIN_SUFFIX}")
- # Clang can fail to compile if CMake doesn't correctly supply the target and
- # external toolchain, but to do so, CMake needs to already know that the
- # compiler is clang. Tell CMake that the compiler is really clang, but don't
- # use CMakeForceCompiler, since we still want compile checks. We only want
- # to skip the compiler ID detection step.
- set(CMAKE_C_COMPILER_ID_RUN TRUE)
- set(CMAKE_CXX_COMPILER_ID_RUN TRUE)
- set(CMAKE_C_COMPILER_ID Clang)
- set(CMAKE_CXX_COMPILER_ID Clang)
set(CMAKE_C_COMPILER_TARGET ${ANDROID_LLVM_TRIPLE})
set(CMAKE_CXX_COMPILER_TARGET ${ANDROID_LLVM_TRIPLE})
set(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN "${ANDROID_TOOLCHAIN_ROOT}")
set(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN "${ANDROID_TOOLCHAIN_ROOT}")
elseif(ANDROID_TOOLCHAIN STREQUAL gcc)
set(ANDROID_C_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}gcc${ANDROID_TOOLCHAIN_SUFFIX}")
set(ANDROID_CXX_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}g++${ANDROID_TOOLCHAIN_SUFFIX}")
@@ -323,13 +321,6 @@
message(FATAL_ERROR "Invalid Android sysroot: ${CMAKE_SYSROOT}.")
endif() As far as I can tell, the removed comment is false for all versions of CMake since at least 3.0. Both # This section does the work to set up CMAKE_CXX_COMPILER_ID, CMAKE_CXX_COMPILER_VERSION, and other useful variables.
if(NOT CMAKE_CXX_COMPILER_ID_RUN)
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
CMAKE_DETERMINE_COMPILER_ID(CXX CXXFLAGS CMakeCXXCompilerId.cpp)
endif()
# Sole reference to CMAKE_CXX_COMPILER_TARGET
if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
if(CMAKE_CXX_COMPILER_TARGET)
set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_CXX_COMPILER_TARGET}-)
endif()
endif()
endif()
# CMakeFindBinUtils.cmake includes the sole reference to CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN
include(CMakeFindBinUtils) So As a quick overview, this bug:
EDIT: Submitted a patch at https://android-review.googlesource.com/#/c/326383/ |
Thanks to @ligfx for fixing this! https://android-review.googlesource.com/c/326383/ |
We had to revert because it breaks the following test (caught by Studio's testing) https://android-review.googlesource.com/c/328500/ |
Full details in the conversation on https://android-review.googlesource.com/c/328404/, but tl;dr this needed a fix to be upstreamed to cmake. It's been committed for 3.9, but until we set that as the minimum supported cmake version we can't fix this. Moving to the unplanned bucket until we can do that. |
CXX_STANDARD flag seems to be working as intended on NDK r14. |
There's a partial fix. This bug is still open to track removing all the cruft some day when CMake 3.9 is our minimum so we can pick up @ligfx's fixes instead. |
Thanks for response. |
Bug: android/ndk#222 : CMake toolchain file's `CMAKE_CXX_COMPILER_ID_RUN=true` breaks compiler feature detection Bug: android/ndk#253 : cmake toolchain file does not set CMAKE_CXX_COMPILER_VERSION Bug: https://gitlab.kitware.com/cmake/cmake/issues/16587 : Adding "-march=" to flags breaks determining compiler ID when cross-compiling with Clang The current comment reads: > Clang can fail to compile if CMake doesn't correctly supply the target > and external toolchain, but to do so, CMake needs to already know > that the compiler is clang. Tell CMake that the compiler is really > clang, but don't use CMakeForceCompiler, since we still want > compile checks. We only want to skip the compiler ID detection > step. The issue arises in CMakeDetermineCompilerId.cmake, which passes along user-specified flags like `-march=armv5te` but not the specified compiler target. On Clang, this fails, since the validity of `-march` depends on the current target. I've filed a bug for CMake to fix this (allow determining the compiler ID without using user flags). In the meantime, I think a more robust solution than overriding CMAKE_CXX_COMPILER_ID_RUN is to run the compiler ID checks before passing along any flags. The CMakeDetermineCCompiler.cmake and CMakeDetermineCXXCompiler.cmake modules are not marked for internal-use-only, and this method takes a more proactive approach to the problem. Change-Id: I2c250ebc2999b3f251417a9e3730b5e093e446d1 (cherry picked from commit 15909f2)
Bug: android/ndk#222 : CMake toolchain file's `CMAKE_CXX_COMPILER_ID_RUN=true` breaks compiler feature detection Bug: android/ndk#253 : cmake toolchain file does not set CMAKE_CXX_COMPILER_VERSION Bug: https://gitlab.kitware.com/cmake/cmake/issues/16587 : Adding "-march=" to flags breaks determining compiler ID when cross-compiling with Clang The current comment reads: > Clang can fail to compile if CMake doesn't correctly supply the target > and external toolchain, but to do so, CMake needs to already know > that the compiler is clang. Tell CMake that the compiler is really > clang, but don't use CMakeForceCompiler, since we still want > compile checks. We only want to skip the compiler ID detection > step. The issue arises in CMakeDetermineCompilerId.cmake, which passes along user-specified flags like `-march=armv5te` but not the specified compiler target. On Clang, this fails, since the validity of `-march` depends on the current target. I've filed a bug for CMake to fix this (allow determining the compiler ID without using user flags). In the meantime, I think a more robust solution than overriding CMAKE_CXX_COMPILER_ID_RUN is to run the compiler ID checks before passing along any flags. The CMakeDetermineCCompiler.cmake and CMakeDetermineCXXCompiler.cmake modules are not marked for internal-use-only, and this method takes a more proactive approach to the problem. Change-Id: I2c250ebc2999b3f251417a9e3730b5e093e446d1
#463 is the real fix for this. |
The ndk cmake toolchain file currently sets
CMAKE_CXX_COMPILER_ID_RUN=true
, which causes the CMake compiler feature detection to be skipped. This causes statements like:to have no effect because CMake doesn't know what the compiler supports. I realize that everything breaks when
CMAKE_CXX_COMPILER_ID_RUN=true
is omitted, so is there any other workaround that doesn't involve disabling feature checks?Thanks!
Snippet of
CMakeFiles/3.6.2/CMakeCXXCompiler.cmake
in my build directory showing that compiler features are not detected:The text was updated successfully, but these errors were encountered: