目前Embarcadero版本的C++ Builder(10.2.3)附带了Clang 32和64位C/C++编译器.据称Clang版本为3.3,(http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Win32_Clang-enhanced_Compilers).
我正在研究使用这些编译器和CMake编译VTK 8.0和其他库.
但是,CMake附带的"系统"CMake文件(Windows-Embarcadero.cmake)没有为Clang配置,而是为较旧的bcc32编译器配置.
Embarcadero建议将他们发布的"Windows-Embarcadero.cmake"文件(http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Using_CMake_with_C%2B%2B_Builder)复制到CMakes Modules/Platform文件夹,并覆盖Windows-随CMake一起提供的Embarcadero.cmake文件.我正在使用CMake 3.10.
但是,遵循Embarcaderos的建议不允许编译太多.除了不能正常工作之外,新的.cmake文件还断开了对旧bcc32编译器(!)的支持.
尝试使用CMake和bcc32x(clang32)编译器配置VTK8源时的第一个错误是:
CMake Error at CMake/vtkModuleMacros.cmake:586 (target_compile_features): target_compile_features no known features for CXX compiler "Embarcadero" version 7.30.36015. Call Stack (most recent call first): CMake/vtkModuleMacros.cmake:660 (vtk_add_library) Common/Core/CMakeLists.txt:399 (vtk_module_library)
在第586行深入了解CMake/vtkModuleMacros可显示错误发生的位置:
function(vtk_add_library name) add_library(${name} ${ARGN} ${headers}) # We use compile features to specify that VTK requires C++11. # We request a series of C++11 features that will conform to VTK's # desired minimum requirements. # - cxx_override enforces Intel 14+, and GCC 4.7+ # - cxx_nullptr as this a hard requirement for all compiler # CMake 3.8+ introduces the concept of meta language compiler features, and # also introduces the first compilers that are only meta language feature # aware. So if we have CMake 3.8+ we will also set the meta feature as # a private flag ( private so we don't force consumers to also use 3.8+ ) if(NOT VTK_IGNORE_CMAKE_CXX11_CHECKS) target_compile_features(${name} PUBLIC cxx_nullptr cxx_override) **This is line 586** if(NOT CMAKE_VERSION VERSION_LESS 3.8) target_compile_features(${name} PRIVATE cxx_std_11) endif() endif() if(NOT ARGV1 STREQUAL OBJECT) vtk_target(${name}) endif() endfunction()
这可能表明Embarcadero发布的CMake文件不正确/完整.Embarcaderos CMake文件看起来像这样:
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. set(_EMBT_CPP_PREPROCESSOR "cpp32") set(EMBT_TARGET Windows) if(CMAKE_BASE_NAME STREQUAL "bcc32x") set(BCC32X TRUE) set(_EMBT_CPP_PREPROCESSOR "cpp32x") set(CLANG_BASED TRUE) endif() if(CMAKE_BASE_NAME STREQUAL "bcc64") set(BCC64 TRUE) set(_EMBT_CPP_PREPROCESSOR "cpp64") set(CLANG_BASED TRUE) endif() if(CMAKE_BASE_NAME STREQUAL "bcc32c") set(BCC32C TRUE) set(_EMBT_CPP_PREPROCESSOR "cpp32c") endif() # This module is shared by multiple languages; use include blocker. if(__WINDOWS_EMBARCADERO) return() endif() set(__WINDOWS_EMBARCADERO 1) set(BORLAND 1) if("${CMAKE_${_lang}_COMPILER_VERSION}" VERSION_LESS 6.30) # Borland target type flags (bcc32 -h -t): set(_tW "-tW") # -tW GUI App (implies -U__CONSOLE__) set(_tC "-tWC") # -tWC Console App (implies -D__CONSOLE__=1) set(_tD "-tWD") # -tWD Build a DLL (implies -D__DLL__=1 -D_DLL=1) set(_tM "-tWM") # -tWM Enable threads (implies -D__MT__=1 -D_MT=1) set(_tR "-tWR -tW-") # -tWR Use DLL runtime (implies -D_RTLDLL, and '-tW' too!!) # Notes: # - The flags affect linking so we pass them to the linker. # - The flags affect preprocessing so we pass them to the compiler. # - Since '-tWR' implies '-tW' we use '-tWR -tW-' instead. # - Since '-tW-' disables '-tWD' we use '-tWR -tW- -tWD' for DLLs. else() set(EMBARCADERO 1) set(_tC "-tC") # Target is a console application set(_tD "-tD") # Target is a shared library set(_tM "-tM") # Target is multi-threaded set(_tR "-tR") # Target uses the dynamic RTL set(_tW "-tW") # Target is a Windows application set(_tV "-tV") # Target is a VCL application set(_tJ "-tJ") # Target uses the Delphi Runtime set(_tF "-tF") # Target is a FMX application set(_tP "-tP") # Target creates a Package set(_tU "-tU") # Target creates a Unicode endif() # if build type is not provided set it to debug mode if(NOT CMAKE_BUILD_TYPE) set (CMAKE_BUILD_TYPE DEBUG CACHE STRING "Choose the type of build, options are: DEBUG RELEASE RELWITHDEBINFO MINSIZEREL.") endif() # to get the latest version of Rad Studio Installed by passing _EMBT_SDK_DIR path. macro(_embt_getbdsversion result curdir) file(GLOB children RELATIVE ${curdir} ${curdir}/*) set(dirlist "") foreach(child ${children}) if(IS_DIRECTORY ${curdir}/${child}) list(APPEND dirlist ${child}) endif() endforeach() list(LENGTH dirlist dirlength) set(latest_dir_index ${dirlength}) math(EXPR latest_dir_index "${latest_dir_index}-1") list (GET dirlist ${latest_dir_index} latest_dir) set(${result} ${latest_dir}) endmacro() set(_EMBT_SDK_DIR "") if(NOT "$ENV{APPDATA}" STREQUAL "") set(_EMBT_SDK_DIR "$ENV{APPDATA}\\Embarcadero\\BDS") #have to pick up by path from %APPDATA% string(REGEX REPLACE "\\\\" "/" _EMBT_SDK_DIR "${_EMBT_SDK_DIR}") file(TO_CMAKE_PATH "${_EMBT_SDK_DIR}" _EMBT_SDK_DIR) endif() if(EXISTS ${_EMBT_SDK_DIR}) _embt_getbdsversion(LATESTVER ${_EMBT_SDK_DIR}) get_filename_component(ROOTDIR "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Embarcadero\\BDS\\${LATESTVER};RootDir]" ABSOLUTE CACHE) string(REGEX REPLACE "\\\\" "/" ROOTDIR ${ROOTDIR}) else() #if RAD Studio is not installed, find_path(BIN_DIR_PATH NAMES ${CMAKE_BASE_NAME}.exe) get_filename_component(ROOTDIR ${BIN_DIR_PATH} PATH) endif() include_directories(SYSTEM "${ROOTDIR}/include/windows/crtl") include_directories(SYSTEM "${ROOTDIR}/include/windows/sdk") include_directories(SYSTEM "${ROOTDIR}/include/windows/rtl") include_directories(SYSTEM "${ROOTDIR}/include/dinkumware64") if(BCC32X OR BCC32C) if(CMAKE_BUILD_TYPE MATCHES ".*DEB.*") set(linker_Path1 "${ROOTDIR}/lib/win32c/debug") set(linker_Path2 "${ROOTDIR}/lib/win32/debug") set(linker_Path3 "${ROOTDIR}/lib/win32/debug/psdk") set(windows_LIBRARY "${windows_LIBRARY} -L \"${linker_Path1}\"") set(windows_LIBRARY "${windows_LIBRARY} -L \"${linker_Path2}\"") set(windows_LIBRARY "${windows_LIBRARY} -L \"${linker_Path3}\"") endif() set(linker_Path1 "${ROOTDIR}/lib/win32c/release") set(linker_Path2 "${ROOTDIR}/lib/win32/release") set(linker_Path3 "${ROOTDIR}/lib/win32/release/psdk") set(windows_LIBRARY "${windows_LIBRARY} -L \"${linker_Path1}\"") set(windows_LIBRARY "${windows_LIBRARY} -L \"${linker_Path2}\"") set(windows_LIBRARY "${windows_LIBRARY} -L \"${linker_Path3}\"") endif() if(CLANG_BASED) if(BCC32X) set(CMAKE_C_COMPILER ${ROOTDIR}/bin/bcc32x.exe) set(CMAKE_CXX_COMPILER ${ROOTDIR}/bin/bcc32x.exe) endif() if(BCC64) if(CMAKE_BUILD_TYPE MATCHES ".*DEB.*") set(linker_Path1 "${ROOTDIR}/lib/win64/debug") set(linker_Path2 "${ROOTDIR}/lib/win64/debug/psdk") set(windows_LIBRARY "${windows_LIBRARY} -L \"${linker_Path1}\"") set(windows_LIBRARY "${windows_LIBRARY} -L \"${linker_Path2}\"") endif() set(linker_Path1 "${ROOTDIR}/lib/win64/release") set(linker_Path2 "${ROOTDIR}/lib/win64/release/psdk") set(CMAKE_C_COMPILER ${ROOTDIR}/bin/bcc64.exe) set(CMAKE_CXX_COMPILER ${ROOTDIR}/bin/bcc64.exe) set(windows_LIBRARY "${windows_LIBRARY} -L \"${linker_Path1}\"") set(windows_LIBRARY "${windows_LIBRARY} -L \"${linker_Path2}\"") endif() # Setting the Link Library Path in flag set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS ${windows_LIBRARY}) set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS ${windows_LIBRARY}) # setting the link library flag set(link_flags ${windows_LIBRARY}) set(CMAKE_EXE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "exe link flags") set(CMAKE_MODULE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "module link flags") set(CMAKE_SHARED_LINKER_FLAGS ${link_flags} CACHE INTERNAL "shared lnk flags") endif() set(_COMPILE_C "-c") set(_COMPILE_CXX "-P -c") set(CMAKE_LIBRARY_PATH_FLAG "-L") set(CMAKE_LINK_LIBRARY_FLAG "") set(CMAKE_FIND_LIBRARY_SUFFIXES "-bcc.lib" ".lib") # uncomment these out to debug makefiles #set(CMAKE_START_TEMP_FILE "") #set(CMAKE_END_TEMP_FILE "") #set(CMAKE_VERBOSE_MAKEFILE 1) # Borland cannot handle + in the file name, so mangle object file name set (CMAKE_MANGLE_OBJECT_FILE_NAMES "ON") # extra flags for a win32 exe set(CMAKE_CREATE_WIN32_EXE "${_tW}" ) # extra flags for a console app set(CMAKE_CREATE_CONSOLE_EXE "${_tC}" ) foreach(t EXE SHARED MODULE) string(APPEND CMAKE_${t}_LINKER_FLAGS_INIT " ${_tM} -lS:1048576 -lSc:4098 -lH:1048576 -lHc:8192 ") string(APPEND CMAKE_${t}_LINKER_FLAGS_DEBUG_INIT " -v") string(APPEND CMAKE_${t}_LINKER_FLAGS_RELWITHDEBINFO_INIT " -v") endforeach() # The Borland link tool does not support multiple concurrent # invocations within a single working directory. if(NOT DEFINED CMAKE_JOB_POOL_LINK) set(CMAKE_JOB_POOL_LINK BCC32LinkPool) get_property(_bccjp GLOBAL PROPERTY JOB_POOLS) if(NOT _bccjp MATCHES "BCC32LinkPool=") set_property(GLOBAL APPEND PROPERTY JOB_POOLS BCC32LinkPool=1) endif() unset(_bccjp) endif() macro(__embarcadero_language lang) set(CMAKE_${lang}_COMPILE_OPTIONS_DLL "${_tD}" ) # Note: This variable is a ';' separated list set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "${_tD}") # ... while this is a space separated string. set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 1) # compile a source file into an object file # placeoutside the response file because Borland refuses # to parse quotes from the response file. set(CMAKE_${lang}_COMPILE_OBJECT " -o ${_COMPILE_${lang}}
有谁知道如何配置CMake以便能够使用这些Embarcadero修改过的Clang编译器?这应该与使用这些编译器的任何人相关.