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("$<$:__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("$<$>:-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("$<$:-Wold-style-declaration>") + endif() +else() add_compile_options("$<$:-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("$<$:-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 " set(CMAKE_ASM_COMPILE_OBJECT " ${_compress_debug_sections_flag} -x assembler-with-cpp -o -I${REACTOS_SOURCE_DIR}/sdk/include/asm -I${REACTOS_BINARY_DIR}/sdk/include/asm -D__ASM__ -c ") set(CMAKE_RC_COMPILE_OBJECT " -O coff -DRC_INVOKED -D__WIN32__=1 -D__FLAT__=1 ${I18N_DEFS} ") -set(CMAKE_DEPFILE_FLAGS_RC "--preprocessor \"${MINGW_TOOLCHAIN_PREFIX}gcc${MINGW_TOOLCHAIN_SUFFIX} -E -xc-header -MMD -MF -MT \" ") +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 -MT \" ") # Optional 3rd parameter: stdcall stack bytes function(set_entrypoint MODULE ENTRYPOINT) @@ -423,30 +431,41 @@ add_compile_options("$<$:$:$>,-fexceptions,-fno-exceptions>>") +# G++ shipped with ROSBE uses sjlj exceptions. Tell Clang it is so +if (CLANG) + add_compile_options("$<$,$>>:-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) - -# 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 ") +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 " crT ") 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()