[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
This commit is contained in:
Jérôme Gardou 2020-09-10 23:23:14 +02:00 committed by Jérôme Gardou
parent d6d5caec7c
commit edc1f3ca56
5 changed files with 92 additions and 55 deletions

View file

@ -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)

View file

@ -705,7 +705,10 @@ endfunction()
function(get_defines OUTPUT_VAR)
get_directory_property(_defines COMPILE_DEFINITIONS)
foreach(arg ${_defines})
# Skip generator expressions
if (NOT arg MATCHES [[^\$<.*>$]])
list(APPEND __tmp_var -D${arg})
endif()
endforeach()
set(${OUTPUT_VAR} ${__tmp_var} PARENT_SCOPE)
endfunction()

View file

@ -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")
# 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")

View file

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

View file

@ -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)
# 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)
# 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()
set(CMAKE_C_CREATE_STATIC_LIBRARY "${CMAKE_AR} crT <TARGET> <LINK_FLAGS> <OBJECTS>")
if (DEFINED CLANG_VERSION)
set(CLANG_SUFFIX "-${CLANG_VERSION}")
else()
set(CLANG_SUFFIX "")
endif()
# Which tools to use
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_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()