https://git.reactos.org/?p=reactos.git;a=commitdiff;h=edc1f3ca56bb67213c613…
commit edc1f3ca56bb67213c613e7215ad6e44d8075bc6
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Thu Sep 10 23:23:14 2020 +0200
Commit: Jérôme Gardou <zefklop(a)users.noreply.github.com>
CommitDate: Mon Nov 16 16:58:10 2020 +0100
[CMAKE] Fix use of CLang
- Updated toolchain file
- set GCC variable when using CLang in "GCC mode"
- Properly retrieve GCC support libraries
- Various flags needed to get this going
---
CMakeLists.txt | 5 +--
sdk/cmake/CMakeMacros.cmake | 5 ++-
sdk/cmake/config.cmake | 7 +++-
sdk/cmake/gcc.cmake | 45 +++++++++++++++++--------
toolchain-clang.cmake | 81 +++++++++++++++++++++++++--------------------
5 files changed, 90 insertions(+), 53 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 103b1c5bf90..e3dff10c6c1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -55,7 +55,8 @@ add_definitions(-D__REACTOS__)
# There doesn't seem to be a standard for __FILE__ being relative or absolute, so
detect it at runtime.
file(RELATIVE_PATH _PATH_PREFIX ${REACTOS_BINARY_DIR} ${REACTOS_SOURCE_DIR})
-if (GCC AND (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0"))
+if (GCC AND ((CMAKE_C_COMPILER_ID STREQUAL "GNU") AND (CMAKE_C_COMPILER_VERSION
VERSION_GREATER_EQUAL "8.0.0")
+ OR ((CMAKE_C_COMPILER_ID STREQUAL "Clang") AND (CMAKE_C_COMPILER_VERSION
VERSION_GREATER_EQUAL "10.0.0"))))
# Thankfully, GCC has this
add_compile_options(-ffile-prefix-map=${REACTOS_SOURCE_DIR}=)
add_compile_options(-ffile-prefix-map=${_PATH_PREFIX}=)
@@ -63,7 +64,7 @@ else()
string(LENGTH ${_PATH_PREFIX} _PATH_PREFIX_LENGTH)
string(LENGTH ${REACTOS_SOURCE_DIR} REACTOS_SOURCE_DIR_LENGTH)
math(EXPR REACTOS_SOURCE_DIR_LENGTH "${REACTOS_SOURCE_DIR_LENGTH} + 1")
- add_compile_definitions("__RELFILE__=&__FILE__[__FILE__[0] == '.' ?
${_PATH_PREFIX_LENGTH} : ${REACTOS_SOURCE_DIR_LENGTH}]")
+
add_compile_definitions("$<$<COMPILE_LANGUAGE:C,CXX>:__RELFILE__=&__FILE__[__FILE__[0]
== '.' ? ${_PATH_PREFIX_LENGTH} : ${REACTOS_SOURCE_DIR_LENGTH}]>")
endif()
if(MSVC_IDE)
diff --git a/sdk/cmake/CMakeMacros.cmake b/sdk/cmake/CMakeMacros.cmake
index 6458e75fdaf..6c72d553c22 100644
--- a/sdk/cmake/CMakeMacros.cmake
+++ b/sdk/cmake/CMakeMacros.cmake
@@ -705,7 +705,10 @@ endfunction()
function(get_defines OUTPUT_VAR)
get_directory_property(_defines COMPILE_DEFINITIONS)
foreach(arg ${_defines})
- list(APPEND __tmp_var -D${arg})
+ # Skip generator expressions
+ if (NOT arg MATCHES [[^\$<.*>$]])
+ list(APPEND __tmp_var -D${arg})
+ endif()
endforeach()
set(${OUTPUT_VAR} ${__tmp_var} PARENT_SCOPE)
endfunction()
diff --git a/sdk/cmake/config.cmake b/sdk/cmake/config.cmake
index 01c1ac760db..37a6f949901 100644
--- a/sdk/cmake/config.cmake
+++ b/sdk/cmake/config.cmake
@@ -40,7 +40,12 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
set(GCC TRUE CACHE BOOL "The compiler is GCC")
set(CLANG FALSE CACHE BOOL "The compiler is LLVM Clang")
elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang")
- set(GCC FALSE CACHE BOOL "The compiler is GCC")
+ # We can use LLVM Clang mimicking CL or GCC. Account for this
+ if (MSVC)
+ set(GCC FALSE CACHE BOOL "The compiler is GCC")
+ else()
+ set(GCC TRUE CACHE BOOL "The compiler is GCC")
+ endif()
set(CLANG TRUE CACHE BOOL "The compiler is LLVM Clang")
elseif(MSVC) # aka CMAKE_C_COMPILER_ID STEQUAL "MSVC"
set(GCC FALSE CACHE BOOL "The compiler is GCC")
diff --git a/sdk/cmake/gcc.cmake b/sdk/cmake/gcc.cmake
index 5fac4f059f4..278e8b5f092 100644
--- a/sdk/cmake/gcc.cmake
+++ b/sdk/cmake/gcc.cmake
@@ -45,10 +45,18 @@ add_compile_options(-pipe -fms-extensions -fno-strict-aliasing)
# The case for C++ is handled through the reactos_c++ INTERFACE library
add_compile_options("$<$<NOT:$<COMPILE_LANGUAGE:CXX>>:-nostdinc>")
-add_compile_options(-mstackrealign -fno-aggressive-loop-optimizations)
+add_compile_options(-mstackrealign)
-if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
+if(NOT CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ add_compile_options(-fno-aggressive-loop-optimizations)
+ if (DBG)
+
add_compile_options("$<$<COMPILE_LANGUAGE:C>:-Wold-style-declaration>")
+ endif()
+else()
add_compile_options("$<$<COMPILE_LANGUAGE:C>:-std=gnu99;-Wno-microsoft>")
+ add_compile_options(-Wno-pragma-pack)
+ add_compile_options(-fno-associative-math)
+ add_compile_options(-fcommon)
set(CMAKE_LINK_DEF_FILE_FLAG "")
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
set(CMAKE_LINK_LIBRARY_SUFFIX "")
@@ -62,12 +70,6 @@ if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_FLAGS_DEBUG "")
endif()
-if(DBG)
- if(NOT CMAKE_C_COMPILER_ID STREQUAL "Clang")
-
add_compile_options("$<$<COMPILE_LANGUAGE:C>:-Wold-style-declaration>")
- endif()
-endif()
-
# Debugging
if(NOT CMAKE_BUILD_TYPE STREQUAL "Release")
if(SEPARATE_DBG)
@@ -252,7 +254,13 @@ set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER>
<DEFINES> <INCLUDES> <FLAGS>
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER>
${_compress_debug_sections_flag} -x assembler-with-cpp -o <OBJECT>
-I${REACTOS_SOURCE_DIR}/sdk/include/asm -I${REACTOS_BINARY_DIR}/sdk/include/asm
<INCLUDES> <FLAGS> <DEFINES> -D__ASM__ -c <SOURCE>")
set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <INCLUDES>
<FLAGS> -DRC_INVOKED -D__WIN32__=1 -D__FLAT__=1 ${I18N_DEFS} <DEFINES>
<SOURCE> <OBJECT>")
-set(CMAKE_DEPFILE_FLAGS_RC "--preprocessor
\"${MINGW_TOOLCHAIN_PREFIX}gcc${MINGW_TOOLCHAIN_SUFFIX} -E -xc-header -MMD -MF
<DEPFILE> -MT <OBJECT>\" ")
+if (CLANG)
+ set(GCC_EXECUTABLE ${CMAKE_C_COMPILER_TARGET}-gcc)
+else()
+ set(GCC_EXECUTABLE ${CMAKE_C_COMPILER})
+endif()
+
+set(CMAKE_DEPFILE_FLAGS_RC "--preprocessor \"${GCC_EXECUTABLE} -E -xc-header
-MMD -MF <DEPFILE> -MT <OBJECT>\" ")
# Optional 3rd parameter: stdcall stack bytes
function(set_entrypoint MODULE ENTRYPOINT)
@@ -423,30 +431,41 @@
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:$<IF:$<BOOL:$<TARGET_PROPERTY:WIT
# We disable exceptions, unless said so
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:$<IF:$<BOOL:$<TARGET_PROPERTY:WITH_CXX_EXCEPTIONS>>,-fexceptions,-fno-exceptions>>")
+# G++ shipped with ROSBE uses sjlj exceptions. Tell Clang it is so
+if (CLANG)
+
add_compile_options("$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<BOOL:$<TARGET_PROPERTY:WITH_CXX_EXCEPTIONS>>>:-fsjlj-exceptions>")
+endif()
+
# Find default G++ libraries
+if (CLANG)
+ set(GXX_EXECUTABLE ${CMAKE_CXX_COMPILER_TARGET}-g++)
+else()
+ set(GXX_EXECUTABLE ${CMAKE_CXX_COMPILER})
+endif()
+
add_library(libgcc STATIC IMPORTED)
-execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libgcc.a OUTPUT_VARIABLE
LIBGCC_LOCATION)
+execute_process(COMMAND ${GXX_EXECUTABLE} -print-file-name=libgcc.a OUTPUT_VARIABLE
LIBGCC_LOCATION)
string(STRIP ${LIBGCC_LOCATION} LIBGCC_LOCATION)
set_target_properties(libgcc PROPERTIES IMPORTED_LOCATION ${LIBGCC_LOCATION})
# libgcc needs kernel32 imports, a CRT and msvcrtex
target_link_libraries(libgcc INTERFACE libkernel32 libmsvcrt msvcrtex)
add_library(libsupc++ STATIC IMPORTED GLOBAL)
-execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libsupc++.a
OUTPUT_VARIABLE LIBSUPCXX_LOCATION)
+execute_process(COMMAND ${GXX_EXECUTABLE} -print-file-name=libsupc++.a OUTPUT_VARIABLE
LIBSUPCXX_LOCATION)
string(STRIP ${LIBSUPCXX_LOCATION} LIBSUPCXX_LOCATION)
set_target_properties(libsupc++ PROPERTIES IMPORTED_LOCATION ${LIBSUPCXX_LOCATION})
# libsupc++ requires libgcc
target_link_libraries(libsupc++ INTERFACE libgcc)
add_library(libmingwex STATIC IMPORTED)
-execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libmingwex.a
OUTPUT_VARIABLE LIBMINGWEX_LOCATION)
+execute_process(COMMAND ${GXX_EXECUTABLE} -print-file-name=libmingwex.a OUTPUT_VARIABLE
LIBMINGWEX_LOCATION)
string(STRIP ${LIBMINGWEX_LOCATION} LIBMINGWEX_LOCATION)
set_target_properties(libmingwex PROPERTIES IMPORTED_LOCATION ${LIBMINGWEX_LOCATION})
# libmingwex requires a CRT and imports from kernel32
target_link_libraries(libmingwex INTERFACE libmsvcrt libkernel32)
add_library(libstdc++ STATIC IMPORTED GLOBAL)
-execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libstdc++.a
OUTPUT_VARIABLE LIBSTDCCXX_LOCATION)
+execute_process(COMMAND ${GXX_EXECUTABLE} -print-file-name=libstdc++.a OUTPUT_VARIABLE
LIBSTDCCXX_LOCATION)
string(STRIP ${LIBSTDCCXX_LOCATION} LIBSTDCCXX_LOCATION)
set_target_properties(libstdc++ PROPERTIES IMPORTED_LOCATION ${LIBSTDCCXX_LOCATION})
# libstdc++ requires libsupc++ and mingwex provided by GCC
diff --git a/toolchain-clang.cmake b/toolchain-clang.cmake
index da3ffc782e7..826f45f6b9a 100644
--- a/toolchain-clang.cmake
+++ b/toolchain-clang.cmake
@@ -3,53 +3,62 @@ if(NOT ARCH)
set(ARCH i386)
endif()
-# Choose the right MinGW toolchain prefix
-if(NOT DEFINED MINGW_TOOLCHAIN_PREFIX)
- if(ARCH STREQUAL "i386")
-
- if(CMAKE_HOST_WIN32)
- set(MINGW_TOOLCHAIN_PREFIX "" CACHE STRING "MinGW Toolchain
Prefix")
- else()
- set(MINGW_TOOLCHAIN_PREFIX "i686-w64-mingw32-" CACHE STRING
"MinGW-W64 Toolchain Prefix")
- endif()
-
- elseif(ARCH STREQUAL "amd64")
- set(MINGW_TOOLCHAIN_PREFIX "x86_64-w64-mingw32-" CACHE STRING
"MinGW Toolchain Prefix")
- elseif(ARCH STREQUAL "arm")
- set(MINGW_TOOLCHAIN_PREFIX "arm-mingw32ce-" CACHE STRING "MinGW
Toolchain Prefix")
- endif()
-endif()
-
-if(NOT DEFINED MINGW_TOOLCHAIN_SUFFIX)
- set(MINGW_TOOLCHAIN_SUFFIX "" CACHE STRING "MinGW Toolchain
Suffix")
+if(DEFINED ENV{_ROSBE_ROSSCRIPTDIR})
+ set(CMAKE_SYSROOT $ENV{_ROSBE_ROSSCRIPTDIR}/$ENV{ROS_ARCH})
endif()
# The name of the target operating system
set(CMAKE_SYSTEM_NAME Windows)
-set(CMAKE_SYSTEM_PROCESSOR i686)
+# The processor we are targeting
+if (ARCH STREQUAL "i386")
+ set(CMAKE_SYSTEM_PROCESSOR i686)
+elseif (ARCH STREQUAL "amd64")
+ set(CMAKE_SYSTEM_PROCESSOR x86_64)
+elseif(ARCH STREQUAL "arm")
+ set(CMAKE_SYSTEM_PROCESSOR arm)
+else()
+ message(ERROR "Unsupported ARCH: ${ARCH}")
+endif()
+
+if (DEFINED CLANG_VERSION)
+ set(CLANG_SUFFIX "-${CLANG_VERSION}")
+else()
+ set(CLANG_SUFFIX "")
+endif()
# Which tools to use
-set(CMAKE_C_COMPILER clang)
-set(CMAKE_CXX_COMPILER ${MINGW_TOOLCHAIN_PREFIX}g++${MINGW_TOOLCHAIN_SUFFIX})
-set(CMAKE_ASM_COMPILER ${MINGW_TOOLCHAIN_PREFIX}gcc${MINGW_TOOLCHAIN_SUFFIX})
-set(CMAKE_ASM_COMPILER_ID "GNU")
-set(CMAKE_MC_COMPILER ${MINGW_TOOLCHAIN_PREFIX}windmc)
-set(CMAKE_RC_COMPILER ${MINGW_TOOLCHAIN_PREFIX}windres)
-set(CMAKE_DLLTOOL ${MINGW_TOOLCHAIN_PREFIX}dlltool)
-
-if(CMAKE_HOST_WIN32)
- set(CMAKE_AR ar)
+set(triplet ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32)
+if (CMAKE_HOST_WIN32)
+ set(GCC_TOOLCHAIN_PREFIX "")
+else()
+ set(GCC_TOOLCHAIN_PREFIX "${triplet}-")
endif()
-set(CMAKE_C_CREATE_STATIC_LIBRARY "${CMAKE_AR} crT <TARGET> <LINK_FLAGS>
<OBJECTS>")
+set(CMAKE_C_COMPILER clang${CLANG_SUFFIX})
+set(CMAKE_C_COMPILER_TARGET ${triplet})
+set(CMAKE_CXX_COMPILER clang++${CLANG_SUFFIX})
+set(CMAKE_CXX_COMPILER_TARGET ${triplet})
+set(CMAKE_ASM_COMPILER ${GCC_TOOLCHAIN_PREFIX}gcc)
+set(CMAKE_ASM_COMPILER_ID GNU)
+set(CMAKE_MC_COMPILER ${GCC_TOOLCHAIN_PREFIX}windmc)
+set(CMAKE_RC_COMPILER ${GCC_TOOLCHAIN_PREFIX}windres)
+# set(CMAKE_AR ${triplet}-ar)
+# set(CMAKE_DLLTOOL ${triplet}-dlltool)
+
+# This allows to have CMake test the compiler without linking
+set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+
+set(CMAKE_C_CREATE_STATIC_LIBRARY "<CMAKE_AR> crT <TARGET>
<LINK_FLAGS> <OBJECTS>")
set(CMAKE_CXX_CREATE_STATIC_LIBRARY ${CMAKE_C_CREATE_STATIC_LIBRARY})
set(CMAKE_ASM_CREATE_STATIC_LIBRARY ${CMAKE_C_CREATE_STATIC_LIBRARY})
-# Don't link with anything by default unless we say so
set(CMAKE_C_STANDARD_LIBRARIES "-lgcc" CACHE STRING "Standard C
Libraries")
-
-#MARK_AS_ADVANCED(CLEAR CMAKE_CXX_STANDARD_LIBRARIES)
set(CMAKE_CXX_STANDARD_LIBRARIES "-lgcc" CACHE STRING "Standard C++
Libraries")
-set(CMAKE_SHARED_LINKER_FLAGS_INIT "-nostdlib
-Wl,--enable-auto-image-base,--disable-auto-import")
-set(CMAKE_MODULE_LINKER_FLAGS_INIT "-nostdlib
-Wl,--enable-auto-image-base,--disable-auto-import")
+set(CMAKE_SHARED_LINKER_FLAGS_INIT "-nostdlib
-Wl,--enable-auto-image-base,--disable-auto-import
-fuse-ld=${CMAKE_SYSROOT}/bin/${triplet}-ld")
+set(CMAKE_MODULE_LINKER_FLAGS_INIT "-nostdlib
-Wl,--enable-auto-image-base,--disable-auto-import
-fuse-ld=${CMAKE_SYSROOT}/bin/${triplet}-ld")
+if (DEFINED CMAKE_SYSROOT)
+ set(CMAKE_EXE_LINKER_FLAGS_INIT "-nostdlib
-fuse-ld=${CMAKE_SYSROOT}/bin/${GCC_TOOLCHAIN_PREFIX}ld")
+else()
+ set(CMAKE_EXE_LINKER_FLAGS_INIT "-nostdlib
-fuse-ld=${GCC_TOOLCHAIN_PREFIX}ld")
+endif()