https://git.reactos.org/?p=reactos.git;a=commitdiff;h=edc1f3ca56bb67213c613e7215ad6e44d8075bc6
commit edc1f3ca56bb67213c613e7215ad6e44d8075bc6 Author: Jérôme Gardou <jerome.gar...@reactos.org> AuthorDate: Thu Sep 10 23:23:14 2020 +0200 Commit: Jérôme Gardou <zefk...@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()