[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. # 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}) 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 # Thankfully, GCC has this
add_compile_options(-ffile-prefix-map=${REACTOS_SOURCE_DIR}=) add_compile_options(-ffile-prefix-map=${REACTOS_SOURCE_DIR}=)
add_compile_options(-ffile-prefix-map=${_PATH_PREFIX}=) add_compile_options(-ffile-prefix-map=${_PATH_PREFIX}=)
@ -63,7 +64,7 @@ else()
string(LENGTH ${_PATH_PREFIX} _PATH_PREFIX_LENGTH) string(LENGTH ${_PATH_PREFIX} _PATH_PREFIX_LENGTH)
string(LENGTH ${REACTOS_SOURCE_DIR} REACTOS_SOURCE_DIR_LENGTH) string(LENGTH ${REACTOS_SOURCE_DIR} REACTOS_SOURCE_DIR_LENGTH)
math(EXPR REACTOS_SOURCE_DIR_LENGTH "${REACTOS_SOURCE_DIR_LENGTH} + 1") 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() endif()
if(MSVC_IDE) if(MSVC_IDE)

View file

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

View file

@ -40,7 +40,12 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
set(GCC TRUE CACHE BOOL "The compiler is GCC") set(GCC TRUE CACHE BOOL "The compiler is GCC")
set(CLANG FALSE CACHE BOOL "The compiler is LLVM Clang") set(CLANG FALSE CACHE BOOL "The compiler is LLVM Clang")
elseif(CMAKE_C_COMPILER_ID STREQUAL "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") set(CLANG TRUE CACHE BOOL "The compiler is LLVM Clang")
elseif(MSVC) # aka CMAKE_C_COMPILER_ID STEQUAL "MSVC" elseif(MSVC) # aka CMAKE_C_COMPILER_ID STEQUAL "MSVC"
set(GCC FALSE CACHE BOOL "The compiler is GCC") 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 # The case for C++ is handled through the reactos_c++ INTERFACE library
add_compile_options("$<$<NOT:$<COMPILE_LANGUAGE:CXX>>:-nostdinc>") 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("$<$<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_LINK_DEF_FILE_FLAG "")
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a") set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
set(CMAKE_LINK_LIBRARY_SUFFIX "") set(CMAKE_LINK_LIBRARY_SUFFIX "")
@ -62,12 +70,6 @@ if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_FLAGS_DEBUG "") set(CMAKE_CXX_FLAGS_DEBUG "")
endif() endif()
if(DBG)
if(NOT CMAKE_C_COMPILER_ID STREQUAL "Clang")
add_compile_options("$<$<COMPILE_LANGUAGE:C>:-Wold-style-declaration>")
endif()
endif()
# Debugging # Debugging
if(NOT CMAKE_BUILD_TYPE STREQUAL "Release") if(NOT CMAKE_BUILD_TYPE STREQUAL "Release")
if(SEPARATE_DBG) 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_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_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 # Optional 3rd parameter: stdcall stack bytes
function(set_entrypoint MODULE ENTRYPOINT) 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 # We disable exceptions, unless said so
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:$<IF:$<BOOL:$<TARGET_PROPERTY:WITH_CXX_EXCEPTIONS>>,-fexceptions,-fno-exceptions>>") 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 # 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) 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) string(STRIP ${LIBGCC_LOCATION} LIBGCC_LOCATION)
set_target_properties(libgcc PROPERTIES IMPORTED_LOCATION ${LIBGCC_LOCATION}) set_target_properties(libgcc PROPERTIES IMPORTED_LOCATION ${LIBGCC_LOCATION})
# libgcc needs kernel32 imports, a CRT and msvcrtex # libgcc needs kernel32 imports, a CRT and msvcrtex
target_link_libraries(libgcc INTERFACE libkernel32 libmsvcrt msvcrtex) target_link_libraries(libgcc INTERFACE libkernel32 libmsvcrt msvcrtex)
add_library(libsupc++ STATIC IMPORTED GLOBAL) 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) string(STRIP ${LIBSUPCXX_LOCATION} LIBSUPCXX_LOCATION)
set_target_properties(libsupc++ PROPERTIES IMPORTED_LOCATION ${LIBSUPCXX_LOCATION}) set_target_properties(libsupc++ PROPERTIES IMPORTED_LOCATION ${LIBSUPCXX_LOCATION})
# libsupc++ requires libgcc # libsupc++ requires libgcc
target_link_libraries(libsupc++ INTERFACE libgcc) target_link_libraries(libsupc++ INTERFACE libgcc)
add_library(libmingwex STATIC IMPORTED) 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) string(STRIP ${LIBMINGWEX_LOCATION} LIBMINGWEX_LOCATION)
set_target_properties(libmingwex PROPERTIES IMPORTED_LOCATION ${LIBMINGWEX_LOCATION}) set_target_properties(libmingwex PROPERTIES IMPORTED_LOCATION ${LIBMINGWEX_LOCATION})
# libmingwex requires a CRT and imports from kernel32 # libmingwex requires a CRT and imports from kernel32
target_link_libraries(libmingwex INTERFACE libmsvcrt libkernel32) target_link_libraries(libmingwex INTERFACE libmsvcrt libkernel32)
add_library(libstdc++ STATIC IMPORTED GLOBAL) 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) string(STRIP ${LIBSTDCCXX_LOCATION} LIBSTDCCXX_LOCATION)
set_target_properties(libstdc++ PROPERTIES IMPORTED_LOCATION ${LIBSTDCCXX_LOCATION}) set_target_properties(libstdc++ PROPERTIES IMPORTED_LOCATION ${LIBSTDCCXX_LOCATION})
# libstdc++ requires libsupc++ and mingwex provided by GCC # libstdc++ requires libsupc++ and mingwex provided by GCC

View file

@ -3,53 +3,62 @@ if(NOT ARCH)
set(ARCH i386) set(ARCH i386)
endif() endif()
# Choose the right MinGW toolchain prefix if(DEFINED ENV{_ROSBE_ROSSCRIPTDIR})
if(NOT DEFINED MINGW_TOOLCHAIN_PREFIX) set(CMAKE_SYSROOT $ENV{_ROSBE_ROSSCRIPTDIR}/$ENV{ROS_ARCH})
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")
endif() endif()
# The name of the target operating system # The name of the target operating system
set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR i686) # The processor we are targeting
if (ARCH STREQUAL "i386")
# Which tools to use set(CMAKE_SYSTEM_PROCESSOR i686)
set(CMAKE_C_COMPILER clang) elseif (ARCH STREQUAL "amd64")
set(CMAKE_CXX_COMPILER ${MINGW_TOOLCHAIN_PREFIX}g++${MINGW_TOOLCHAIN_SUFFIX}) set(CMAKE_SYSTEM_PROCESSOR x86_64)
set(CMAKE_ASM_COMPILER ${MINGW_TOOLCHAIN_PREFIX}gcc${MINGW_TOOLCHAIN_SUFFIX}) elseif(ARCH STREQUAL "arm")
set(CMAKE_ASM_COMPILER_ID "GNU") set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_MC_COMPILER ${MINGW_TOOLCHAIN_PREFIX}windmc) else()
set(CMAKE_RC_COMPILER ${MINGW_TOOLCHAIN_PREFIX}windres) message(ERROR "Unsupported ARCH: ${ARCH}")
set(CMAKE_DLLTOOL ${MINGW_TOOLCHAIN_PREFIX}dlltool)
if(CMAKE_HOST_WIN32)
set(CMAKE_AR ar)
endif() 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_CXX_CREATE_STATIC_LIBRARY ${CMAKE_C_CREATE_STATIC_LIBRARY})
set(CMAKE_ASM_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") 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_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_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") 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()