aboutsummaryrefslogtreecommitdiff
path: root/rcc/cmake/modules
diff options
context:
space:
mode:
Diffstat (limited to 'rcc/cmake/modules')
-rw-r--r--rcc/cmake/modules/AddOCaml.cmake239
-rw-r--r--rcc/cmake/modules/AddRCC.cmake184
-rw-r--r--rcc/cmake/modules/CMakeLists.txt47
-rw-r--r--rcc/cmake/modules/CheckAtomic.cmake125
-rw-r--r--rcc/cmake/modules/CheckCompilerVersion.cmake110
-rw-r--r--rcc/cmake/modules/CheckProblematicConfigurations.cmake19
-rw-r--r--rcc/cmake/modules/DetermineGCCCompatible.cmake13
-rw-r--r--rcc/cmake/modules/FindFFI.cmake106
-rw-r--r--rcc/cmake/modules/FindLibEdit.cmake65
-rw-r--r--rcc/cmake/modules/FindLibpfm.cmake37
-rw-r--r--rcc/cmake/modules/FindOCaml.cmake103
-rw-r--r--rcc/cmake/modules/GetErrcMessages.cmake45
-rw-r--r--rcc/cmake/modules/GetHostTriple.cmake98
-rw-r--r--rcc/cmake/modules/HandleRCCOptions.cmake1182
-rw-r--r--rcc/cmake/modules/HandleRCCStdlib.cmake54
-rw-r--r--rcc/cmake/modules/RCCConfig.cmake.in27
-rw-r--r--rcc/cmake/modules/RCCConfigVersion.cmake.in13
17 files changed, 2467 insertions, 0 deletions
diff --git a/rcc/cmake/modules/AddOCaml.cmake b/rcc/cmake/modules/AddOCaml.cmake
new file mode 100644
index 0000000..01fb5a1
--- /dev/null
+++ b/rcc/cmake/modules/AddOCaml.cmake
@@ -0,0 +1,239 @@
+# CMake build rules for the OCaml language.
+# Assumes FindOCaml is used.
+# http://ocaml.org/
+#
+# Example usage:
+#
+# add_ocaml_library(pkg_a OCAML mod_a OCAMLDEP pkg_b C mod_a_stubs PKG ctypes RCC core)
+#
+# Unnamed parameters:
+#
+# * Library name.
+#
+# Named parameters:
+#
+# OCAML OCaml module names. Imply presence of a corresponding .ml and .mli files.
+# OCAMLDEP Names of libraries this library depends on.
+# C C stub sources. Imply presence of a corresponding .c file.
+# CFLAGS Additional arguments passed when compiling C stubs.
+# PKG Names of ocamlfind packages this library depends on.
+# RCC Names of RCC libraries this library depends on.
+# NOCOPY Do not automatically copy sources (.c, .ml, .mli) from the source directory,
+# e.g. if they are generated.
+#
+
+function(add_ocaml_library name)
+ CMAKE_PARSE_ARGUMENTS(ARG "NOCOPY" "" "OCAML;OCAMLDEP;C;CFLAGS;PKG;RCC" ${ARGN})
+
+ set(src ${CMAKE_CURRENT_SOURCE_DIR})
+ set(bin ${CMAKE_CURRENT_BINARY_DIR})
+
+ set(ocaml_pkgs)
+ foreach( ocaml_pkg ${ARG_PKG} )
+ list(APPEND ocaml_pkgs "-package" "${ocaml_pkg}")
+ endforeach()
+
+ set(sources)
+
+ set(ocaml_inputs)
+
+ set(ocaml_outputs "${bin}/${name}.cma")
+ if( ARG_C )
+ list(APPEND ocaml_outputs
+ "${bin}/lib${name}${CMAKE_STATIC_LIBRARY_SUFFIX}")
+ if ( BUILD_SHARED_LIBS )
+ list(APPEND ocaml_outputs
+ "${bin}/dll${name}${CMAKE_SHARED_LIBRARY_SUFFIX}")
+ endif()
+ endif()
+ if( HAVE_OCAMLOPT )
+ list(APPEND ocaml_outputs
+ "${bin}/${name}.cmxa"
+ "${bin}/${name}${CMAKE_STATIC_LIBRARY_SUFFIX}")
+ endif()
+
+ set(ocaml_flags "-lstdc++" "-ldopt" "-L${RCC_LIBRARY_DIR}"
+ "-ccopt" "-L\\$CAMLORIGIN/../.."
+ "-ccopt" "-Wl,-rpath,\\$CAMLORIGIN/../.."
+ ${ocaml_pkgs})
+
+ set(ocaml_dep_inputs)
+ foreach( ocaml_dep ${ARG_OCAMLDEP} )
+ get_target_property(dep_ocaml_flags "ocaml_${ocaml_dep}" OCAML_FLAGS)
+ list(APPEND ocaml_flags ${dep_ocaml_flags})
+ get_target_property(dep_ocaml_outputs "ocaml_${ocaml_dep}" OCAML_OUTPUTS)
+ list(APPEND ocaml_dep_inputs ${dep_ocaml_outputs})
+ endforeach()
+
+ if( NOT BUILD_SHARED_LIBS )
+ list(APPEND ocaml_flags "-custom")
+ endif()
+
+ if(RCC_LINK_RCC_DYLIB)
+ list(APPEND ocaml_flags "-lRCC")
+ else()
+ explicit_map_components_to_libraries(rcc_libs ${ARG_RCC})
+ foreach( rcc_lib ${rcc_libs} )
+ list(APPEND ocaml_flags "-l${rcc_lib}" )
+ endforeach()
+
+ get_property(system_libs TARGET RCCSupport PROPERTY RCC_SYSTEM_LIBS)
+ foreach(system_lib ${system_libs})
+ if (system_lib MATCHES "^-")
+ # If it's an option, pass it without changes.
+ list(APPEND ocaml_flags "${system_lib}" )
+ else()
+ # Otherwise assume it's a library name we need to link with.
+ list(APPEND ocaml_flags "-l${system_lib}" )
+ endif()
+ endforeach()
+ endif()
+
+ string(REPLACE ";" " " ARG_CFLAGS "${ARG_CFLAGS}")
+ set(c_flags "${ARG_CFLAGS} ${RCC_DEFINITIONS}")
+ foreach( include_dir ${RCC_INCLUDE_DIR} ${RCC_MAIN_INCLUDE_DIR} )
+ set(c_flags "${c_flags} -I${include_dir}")
+ endforeach()
+ # include -D/-UNDEBUG to match dump function visibility
+ # regex from HandleRCCOptions.cmake
+ string(REGEX MATCH "(^| )[/-][UD] *NDEBUG($| )" flag_matches
+ "${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${CMAKE_C_FLAGS}")
+ set(c_flags "${c_flags} ${flag_matches}")
+
+ foreach( ocaml_file ${ARG_OCAML} )
+ list(APPEND sources "${ocaml_file}.mli" "${ocaml_file}.ml")
+
+ list(APPEND ocaml_inputs "${bin}/${ocaml_file}.mli" "${bin}/${ocaml_file}.ml")
+
+ list(APPEND ocaml_outputs "${bin}/${ocaml_file}.cmi" "${bin}/${ocaml_file}.cmo")
+
+ list(APPEND ocaml_outputs "${bin}/${ocaml_file}.cmti" "${bin}/${ocaml_file}.cmt")
+
+ if( HAVE_OCAMLOPT )
+ list(APPEND ocaml_outputs
+ "${bin}/${ocaml_file}.cmx"
+ "${bin}/${ocaml_file}${CMAKE_C_OUTPUT_EXTENSION}")
+ endif()
+ endforeach()
+
+ foreach( c_file ${ARG_C} )
+ list(APPEND sources "${c_file}.c")
+
+ list(APPEND c_inputs "${bin}/${c_file}.c")
+ list(APPEND c_outputs "${bin}/${c_file}${CMAKE_C_OUTPUT_EXTENSION}")
+ endforeach()
+
+ if( NOT ARG_NOCOPY )
+ foreach( source ${sources} )
+ add_custom_command(
+ OUTPUT "${bin}/${source}"
+ COMMAND "${CMAKE_COMMAND}" "-E" "copy" "${src}/${source}" "${bin}"
+ DEPENDS "${src}/${source}"
+ COMMENT "Copying ${source} to build area")
+ endforeach()
+ endif()
+
+ foreach( c_input ${c_inputs} )
+ get_filename_component(basename "${c_input}" NAME_WE)
+ add_custom_command(
+ OUTPUT "${basename}${CMAKE_C_OUTPUT_EXTENSION}"
+ COMMAND "${OCAMLFIND}" "ocamlc" "-c" "${c_input}" -ccopt ${c_flags}
+ DEPENDS "${c_input}"
+ COMMENT "Building OCaml stub object file ${basename}${CMAKE_C_OUTPUT_EXTENSION}"
+ VERBATIM)
+ endforeach()
+
+ set(ocaml_params)
+ foreach( ocaml_input ${ocaml_inputs} ${c_outputs})
+ get_filename_component(filename "${ocaml_input}" NAME)
+ list(APPEND ocaml_params "${filename}")
+ endforeach()
+
+ if( APPLE )
+ set(ocaml_rpath "@executable_path/../../../lib${RCC_LIBDIR_SUFFIX}")
+ elseif( UNIX )
+ set(ocaml_rpath "\\$ORIGIN/../../../lib${RCC_LIBDIR_SUFFIX}")
+ endif()
+ list(APPEND ocaml_flags "-ldopt" "-Wl,-rpath,${ocaml_rpath}")
+
+ add_custom_command(
+ OUTPUT ${ocaml_outputs}
+ COMMAND "${OCAMLFIND}" "ocamlmklib" "-ocamlcflags" "-bin-annot"
+ "-o" "${name}" ${ocaml_flags} ${ocaml_params}
+ DEPENDS ${ocaml_inputs} ${ocaml_dep_inputs} ${c_outputs}
+ COMMENT "Building OCaml library ${name}"
+ VERBATIM)
+
+ add_custom_command(
+ OUTPUT "${bin}/${name}.odoc"
+ COMMAND "${OCAMLFIND}" "ocamldoc"
+ "-I" "${bin}"
+ "-I" "${RCC_LIBRARY_DIR}/ocaml/rcc/"
+ "-dump" "${bin}/${name}.odoc"
+ ${ocaml_pkgs} ${ocaml_inputs}
+ DEPENDS ${ocaml_inputs} ${ocaml_dep_inputs} ${ocaml_outputs}
+ COMMENT "Building OCaml documentation for ${name}"
+ VERBATIM)
+
+ add_custom_target("ocaml_${name}" ALL DEPENDS ${ocaml_outputs} "${bin}/${name}.odoc")
+ get_subproject_title(subproject_title)
+ set_target_properties("ocaml_${name}" PROPERTIES FOLDER "${subproject_title}/Bindings/OCaml")
+
+ set_target_properties("ocaml_${name}" PROPERTIES
+ OCAML_FLAGS "-I;${bin}")
+ set_target_properties("ocaml_${name}" PROPERTIES
+ OCAML_ODOC "${bin}/${name}.odoc")
+ set_target_properties("ocaml_${name}" PROPERTIES
+ OCAML_OUTPUTS "${ocaml_outputs}")
+
+ foreach( ocaml_dep ${ARG_OCAMLDEP} )
+ add_dependencies("ocaml_${name}" "ocaml_${ocaml_dep}")
+ endforeach()
+
+ if( NOT RCC_OCAML_OUT_OF_TREE )
+ foreach( rcc_lib ${rcc_libs} )
+ add_dependencies("ocaml_${name}" "${rcc_lib}")
+ endforeach()
+ endif()
+
+ add_dependencies("ocaml_all" "ocaml_${name}")
+
+ set(install_files)
+ set(install_shlibs)
+ foreach( ocaml_output ${ocaml_inputs} ${ocaml_outputs} )
+ get_filename_component(ext "${ocaml_output}" EXT)
+
+ if( NOT (ext STREQUAL ".cmo" OR
+ ext STREQUAL ".ml" OR
+ ext STREQUAL CMAKE_C_OUTPUT_EXTENSION OR
+ ext STREQUAL CMAKE_SHARED_LIBRARY_SUFFIX) )
+ list(APPEND install_files "${ocaml_output}")
+ elseif( ext STREQUAL CMAKE_SHARED_LIBRARY_SUFFIX)
+ list(APPEND install_shlibs "${ocaml_output}")
+ endif()
+ endforeach()
+
+ install(FILES ${install_files}
+ DESTINATION "${RCC_OCAML_INSTALL_PATH}/rcc")
+ install(FILES ${install_shlibs}
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
+ WORLD_READ WORLD_EXECUTE
+ DESTINATION "${RCC_OCAML_INSTALL_PATH}/stublibs")
+
+ foreach( install_file ${install_files} ${install_shlibs} )
+ get_filename_component(filename "${install_file}" NAME)
+ add_custom_command(TARGET "ocaml_${name}" POST_BUILD
+ COMMAND "${CMAKE_COMMAND}" "-E" "copy" "${install_file}"
+ "${RCC_LIBRARY_DIR}/ocaml/rcc/"
+ COMMENT "Copying OCaml library component ${filename} to intermediate area"
+ VERBATIM)
+ add_dependencies("ocaml_${name}" ocaml_make_directory)
+ endforeach()
+endfunction()
+
+add_custom_target(ocaml_make_directory
+ COMMAND "${CMAKE_COMMAND}" "-E" "make_directory" "${RCC_LIBRARY_DIR}/ocaml/rcc")
+add_custom_target("ocaml_all")
+set_target_properties(ocaml_all PROPERTIES FOLDER "RCC/Bindings/OCaml")
+set_target_properties(ocaml_make_directory PROPERTIES FOLDER "RCC/Bindings/OCaml")
diff --git a/rcc/cmake/modules/AddRCC.cmake b/rcc/cmake/modules/AddRCC.cmake
new file mode 100644
index 0000000..11bd92e
--- /dev/null
+++ b/rcc/cmake/modules/AddRCC.cmake
@@ -0,0 +1,184 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+include_guard(GLOBAL)
+include(GNUInstallDirs)
+include(HandleRCCOptions)
+
+macro(rcc_configure_output_directories)
+ set(RCC_RUNTIME_OUTPUT_INTDIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin")
+ set(RCC_LIBRARY_OUTPUT_INTDIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib")
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${RCC_RUNTIME_OUTPUT_INTDIR}")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${RCC_LIBRARY_OUTPUT_INTDIR}")
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${RCC_LIBRARY_OUTPUT_INTDIR}")
+endmacro()
+
+function(rcc_set_output_directory target)
+ if(WIN32 OR CYGWIN)
+ set(moduleDir "${RCC_RUNTIME_OUTPUT_INTDIR}")
+ else()
+ set(moduleDir "${RCC_LIBRARY_OUTPUT_INTDIR}")
+ endif()
+ if(NOT CMAKE_CFG_INTDIR STREQUAL ".")
+ foreach(buildMode IN LISTS CMAKE_CONFIGURATION_TYPES)
+ string(TOUPPER "${buildMode}" configSuffix)
+ if(RCC_RUNTIME_OUTPUT_INTDIR)
+ string(REPLACE "${CMAKE_CFG_INTDIR}" "${buildMode}" binaryDir "${RCC_RUNTIME_OUTPUT_INTDIR}")
+ set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_${configSuffix} "${binaryDir}")
+ endif()
+ if(RCC_LIBRARY_OUTPUT_INTDIR)
+ string(REPLACE "${CMAKE_CFG_INTDIR}" "${buildMode}" libraryDir "${RCC_LIBRARY_OUTPUT_INTDIR}")
+ set_target_properties(${target} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY_${configSuffix} "${libraryDir}")
+ endif()
+ if(moduleDir)
+ string(REPLACE "${CMAKE_CFG_INTDIR}" "${buildMode}" configModuleDir "${moduleDir}")
+ set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${configSuffix} "${configModuleDir}")
+ endif()
+ endforeach()
+ else()
+ if(RCC_RUNTIME_OUTPUT_INTDIR)
+ set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${RCC_RUNTIME_OUTPUT_INTDIR}")
+ endif()
+ if(RCC_LIBRARY_OUTPUT_INTDIR)
+ set_target_properties(${target} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${RCC_LIBRARY_OUTPUT_INTDIR}")
+ endif()
+ if(moduleDir)
+ set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${moduleDir}")
+ endif()
+ endif()
+endfunction()
+
+function(rcc_update_pch target)
+ if(RCC_REQUIRES_RTTI OR RCC_REQUIRES_EH)
+ set(arg_DISABLE_PCH_REUSE ON)
+ endif()
+ get_target_property(sources ${target} SOURCES)
+ foreach(source IN LISTS sources)
+ get_filename_component(extension "${source}" EXT)
+ if(extension STREQUAL ".c" AND NOT arg_PRECOMPILE_HEADERS)
+ set(arg_DISABLE_PCH_REUSE ON)
+ elseif(extension STREQUAL ".mm")
+ set(arg_DISABLE_PCH_REUSE ON)
+ endif()
+ endforeach()
+ get_target_property(targetType ${target} TYPE)
+ if(targetType STREQUAL "EXECUTABLE")
+ get_target_property(positionIndependent ${target} POSITION_INDEPENDENT_CODE)
+ if(positionIndependent)
+ set(arg_DISABLE_PCH_REUSE ON)
+ endif()
+ endif()
+
+ set(pchPriority 0)
+ foreach(library IN LISTS arg_LINK_LIBS)
+ if(TARGET ${library})
+ get_target_property(libraryPriority ${library} RCC_PCH_PRIORITY)
+ get_target_property(libraryPCHDisabled ${library} DISABLE_PRECOMPILE_HEADERS)
+ if(libraryPriority GREATER pchPriority AND NOT libraryPCHDisabled)
+ set(pchPriority "${libraryPriority}")
+ set(pchReuse "${library}")
+ endif()
+ endif()
+ endforeach()
+ if(arg_PRECOMPILE_HEADERS)
+ message(DEBUG "Adding PCH ${arg_PRECOMPILE_HEADERS} for ${target} (prio ${pchPriority})")
+ target_precompile_headers(${target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${arg_PRECOMPILE_HEADERS}>")
+ if(NOT arg_DISABLE_PCH_REUSE)
+ math(EXPR pchPriority "${pchPriority} + 1")
+ set_target_properties(${target} PROPERTIES RCC_PCH_PRIORITY "${pchPriority}")
+ endif()
+ elseif(pchReuse AND NOT arg_DISABLE_PCH_REUSE)
+ message(DEBUG "Using PCH ${pchReuse} for ${target} (prio ${pchPriority})")
+ target_precompile_headers(${target} REUSE_FROM ${pchReuse})
+ else()
+ message(DEBUG "Using NO PCH for ${target}")
+ endif()
+endfunction()
+
+function(rcc_setup_rpath target)
+ if(CMAKE_INSTALL_RPATH)
+ return()
+ endif()
+ set(extraLibraryDir "")
+ if(RCC_INSTALL_PREFIX AND NOT RCC_INSTALL_PREFIX STREQUAL CMAKE_INSTALL_PREFIX)
+ set(extraLibraryDir "${RCC_LIBRARY_DIR}")
+ elseif(RCC_BUILD_LIBRARY_DIR)
+ set(extraLibraryDir "${RCC_LIBRARY_DIR}")
+ endif()
+ get_target_property(targetType ${target} TYPE)
+ if(targetType STREQUAL "EXECUTABLE")
+ set(installDirectory "${CMAKE_INSTALL_FULL_BINDIR}")
+ else()
+ set(installDirectory "${CMAKE_INSTALL_FULL_LIBDIR}")
+ endif()
+ file(RELATIVE_PATH relativeLibraryDir "${installDirectory}" "${CMAKE_INSTALL_FULL_LIBDIR}")
+
+ if(APPLE)
+ set(installName INSTALL_NAME_DIR "@rpath")
+ set(installRpath "@loader_path/${relativeLibraryDir}" ${extraLibraryDir})
+ elseif(CMAKE_SYSTEM_NAME MATCHES "AIX" AND BUILD_SHARED_LIBS)
+ set(installRpath "${RCC_LIBRARY_OUTPUT_INTDIR}" "${CMAKE_INSTALL_FULL_LIBDIR}" ${extraLibraryDir})
+ elseif(UNIX)
+ set(buildRpath "\$ORIGIN/../lib" ${extraLibraryDir})
+ set(installRpath "\$ORIGIN/${relativeLibraryDir}")
+ if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD|DragonFly")
+ target_link_options(${target} PRIVATE "LINKER:-z,origin")
+ endif()
+ if(RCC_LINKER_IS_GNULD AND RCC_LIBRARY_OUTPUT_INTDIR)
+ target_link_options(${target} PRIVATE "LINKER:-rpath-link,${RCC_LIBRARY_OUTPUT_INTDIR}")
+ endif()
+ else()
+ return()
+ endif()
+ if("${CMAKE_BUILD_RPATH}" STREQUAL "")
+ if(CMAKE_SYSTEM_NAME MATCHES "Darwin|AIX")
+ set_target_properties(${target} PROPERTIES BUILD_WITH_INSTALL_RPATH ON)
+ else()
+ set_property(TARGET ${target} APPEND PROPERTY BUILD_RPATH "${buildRpath}")
+ endif()
+ endif()
+ set_target_properties(${target} PROPERTIES INSTALL_RPATH "${installRpath}" ${installName})
+endfunction()
+
+function(rcc_configure_target target)
+ rcc_apply_options(${target})
+ rcc_set_output_directory(${target})
+ rcc_update_pch(${target})
+ get_target_property(targetType ${target} TYPE)
+ if(targetType MATCHES "^(EXECUTABLE|SHARED_LIBRARY|MODULE_LIBRARY)$" AND NOT arg_NO_INSTALL_RPATH)
+ rcc_setup_rpath(${target})
+ endif()
+ if(targetType STREQUAL "SHARED_LIBRARY")
+ if(MSVC)
+ set_target_properties(${target} PROPERTIES PREFIX "")
+ endif()
+ if(UNIX)
+ set_target_properties(${target} PROPERTIES
+ VERSION "${RCC_VERSION_MAJOR}.${RCC_VERSION_MINOR}"
+ SOVERSION "${RCC_VERSION_MAJOR}.${RCC_VERSION_MINOR}")
+ endif()
+ endif()
+endfunction()
+
+function(add_rcc_library name)
+ cmake_parse_arguments(PARSE_ARGV 1 arg "DISABLE_PCH_REUSE;NO_INSTALL_RPATH" "" "LINK_LIBS;PRECOMPILE_HEADERS")
+ add_library(${name} ${arg_UNPARSED_ARGUMENTS})
+ target_link_libraries(${name} PUBLIC RCCHeaders ${arg_LINK_LIBS})
+ rcc_configure_target(${name})
+ install(TARGETS ${name} EXPORT RCCTargets
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
+endfunction()
+
+function(add_rcc_executable name)
+ cmake_parse_arguments(PARSE_ARGV 1 arg "DISABLE_PCH_REUSE;NO_INSTALL_RPATH" "" "LINK_LIBS;PRECOMPILE_HEADERS")
+ add_executable(${name} ${arg_UNPARSED_ARGUMENTS})
+ target_link_libraries(${name} PRIVATE RCCHeaders ${arg_LINK_LIBS})
+ rcc_configure_target(${name})
+endfunction()
+
+function(add_rcc_tool name)
+ add_rcc_executable(${name} ${ARGN})
+ install(TARGETS ${name} EXPORT RCCTargets
+ RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
+endfunction()
diff --git a/rcc/cmake/modules/CMakeLists.txt b/rcc/cmake/modules/CMakeLists.txt
new file mode 100644
index 0000000..39b6d97
--- /dev/null
+++ b/rcc/cmake/modules/CMakeLists.txt
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+include(CMakePackageConfigHelpers)
+
+get_directory_property(RCC_DEFINITIONS DIRECTORY "${RCC_SOURCE_DIR}" COMPILE_DEFINITIONS)
+set(RCC_PACKAGE_MSVC_RUNTIME_LIBRARY "${CMAKE_MSVC_RUNTIME_LIBRARY}")
+if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
+ set(RCC_PACKAGE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
+endif()
+set(rccPackageDir "${RCC_BINARY_DIR}/lib/cmake/RCC")
+set(rccInstallPackageDir "${CMAKE_INSTALL_LIBDIR}/cmake/RCC")
+set(RCC_PACKAGE_MODULE_DIR "${RCC_CMAKE_DIR}")
+set(RCC_PACKAGE_INCLUDE_DIRS "${RCC_INCLUDE_DIRS}")
+set(RCC_PACKAGE_LIBRARY_DIR "${RCC_LIBRARY_DIR}")
+set(RCC_PACKAGE_BUILD_LIBRARY_DIR "${RCC_LIBRARY_DIR}")
+set(RCC_PACKAGE_INSTALL_PREFIX "")
+configure_package_config_file(RCCConfig.cmake.in "${rccPackageDir}/RCCConfig.cmake"
+ INSTALL_DESTINATION "${rccPackageDir}"
+ NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO)
+export(EXPORT RCCTargets FILE "${rccPackageDir}/RCCTargets.cmake")
+
+set(RCC_PACKAGE_MODULE_DIR "\${CMAKE_CURRENT_LIST_DIR}")
+if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
+ set(RCC_PACKAGE_INCLUDE_DIRS "${CMAKE_INSTALL_INCLUDEDIR}")
+else()
+ set(RCC_PACKAGE_INCLUDE_DIRS "\${PACKAGE_PREFIX_DIR}/${CMAKE_INSTALL_INCLUDEDIR}")
+endif()
+if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
+ set(RCC_PACKAGE_LIBRARY_DIR "${CMAKE_INSTALL_LIBDIR}")
+else()
+ set(RCC_PACKAGE_LIBRARY_DIR "\${PACKAGE_PREFIX_DIR}/${CMAKE_INSTALL_LIBDIR}")
+endif()
+set(RCC_PACKAGE_BUILD_LIBRARY_DIR "")
+set(RCC_PACKAGE_INSTALL_PREFIX "\${PACKAGE_PREFIX_DIR}")
+configure_package_config_file(RCCConfig.cmake.in RCCConfig.install.cmake
+ INSTALL_DESTINATION "${rccInstallPackageDir}"
+ NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO)
+configure_file(RCCConfigVersion.cmake.in
+ "${rccPackageDir}/RCCConfigVersion.cmake" @ONLY)
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/RCCConfig.install.cmake"
+ DESTINATION "${rccInstallPackageDir}" RENAME RCCConfig.cmake)
+install(FILES
+ "${rccPackageDir}/RCCConfigVersion.cmake"
+ AddRCC.cmake HandleRCCOptions.cmake
+ DESTINATION "${rccInstallPackageDir}")
+install(EXPORT RCCTargets FILE RCCTargets.cmake
+ DESTINATION "${rccInstallPackageDir}")
diff --git a/rcc/cmake/modules/CheckAtomic.cmake b/rcc/cmake/modules/CheckAtomic.cmake
new file mode 100644
index 0000000..b9ec06e
--- /dev/null
+++ b/rcc/cmake/modules/CheckAtomic.cmake
@@ -0,0 +1,125 @@
+# atomic builtins are required for threading support.
+
+INCLUDE(CheckCXXSourceCompiles)
+INCLUDE(CheckLibraryExists)
+
+# Sometimes linking against libatomic is required for atomic ops, if
+# the platform doesn't support lock-free atomics.
+
+function(check_working_cxx_atomics varname)
+ set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
+ set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
+ CHECK_CXX_SOURCE_COMPILES("
+#include <atomic>
+std::atomic<int> x;
+std::atomic<short> y;
+std::atomic<char> z;
+int main() {
+ ++z;
+ ++y;
+ return ++x;
+}
+" ${varname})
+ set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
+endfunction(check_working_cxx_atomics)
+
+function(check_working_cxx_atomics64 varname)
+ set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
+ set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}")
+ CHECK_CXX_SOURCE_COMPILES("
+#include <atomic>
+#include <cstdint>
+std::atomic<uint64_t> x (0);
+int main() {
+ uint64_t i = x.load(std::memory_order_relaxed);
+ (void)i;
+ return 0;
+}
+" ${varname})
+ set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
+endfunction(check_working_cxx_atomics64)
+
+
+# Check for (non-64-bit) atomic operations.
+if(MSVC)
+ set(HAVE_CXX_ATOMICS_WITHOUT_LIB True)
+elseif(RCC_COMPILER_IS_GCC_COMPATIBLE OR CMAKE_CXX_COMPILER_ID MATCHES "XL")
+ # First check if atomics work without the library.
+ check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
+ # If not, check if the library exists, and atomics work with it.
+ if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
+ check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
+ if(HAVE_LIBATOMIC)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
+ check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
+ if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
+ message(FATAL_ERROR "Host compiler must support std::atomic!")
+ endif()
+ else()
+ message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
+ endif()
+ endif()
+endif()
+
+# Check for 64 bit atomic operations.
+if(MSVC)
+ set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True)
+elseif(RCC_COMPILER_IS_GCC_COMPATIBLE OR CMAKE_CXX_COMPILER_ID MATCHES "XL")
+ # First check if atomics work without the library.
+ check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
+ # If not, check if the library exists, and atomics work with it.
+ if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
+ check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
+ if(HAVE_CXX_LIBATOMICS64)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
+ check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
+ if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
+ message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
+ endif()
+ else()
+ message(FATAL_ERROR "Host compiler appears to require libatomic for 64-bit operations, but cannot find it.")
+ endif()
+ endif()
+endif()
+
+# Set variable RCC_ATOMIC_LIB specifying flags for linking against libatomic.
+if(HAVE_CXX_ATOMICS_WITH_LIB OR HAVE_CXX_ATOMICS64_WITH_LIB)
+ # Use options --push-state, --as-needed and --pop-state if linker is known to support them.
+ # Use single option -Wl of compiler driver to avoid incorrect re-ordering of options by CMake.
+ if(RCC_LINKER_IS_GNULD OR RCC_LINKER_IS_GOLD OR RCC_LINKER_IS_LLD OR RCC_LINKER_IS_MOLD)
+ set(RCC_ATOMIC_LIB "-Wl,--push-state,--as-needed,-latomic,--pop-state")
+ else()
+ set(RCC_ATOMIC_LIB "-latomic")
+ endif()
+else()
+ set(RCC_ATOMIC_LIB)
+endif()
+
+## TODO: This define is only used for the legacy atomic operations in
+## rcc's Atomic.h, which should be replaced. Other code simply
+## assumes C++11 <atomic> works.
+CHECK_CXX_SOURCE_COMPILES("
+#ifdef _MSC_VER
+#include <windows.h>
+#endif
+int main() {
+#ifdef _MSC_VER
+ volatile LONG val = 1;
+ MemoryBarrier();
+ InterlockedCompareExchange(&val, 0, 1);
+ InterlockedIncrement(&val);
+ InterlockedDecrement(&val);
+#else
+ volatile unsigned long val = 1;
+ __sync_synchronize();
+ __sync_val_compare_and_swap(&val, 1, 0);
+ __sync_add_and_fetch(&val, 1);
+ __sync_sub_and_fetch(&val, 1);
+#endif
+ return 0;
+ }
+" RCC_HAS_ATOMICS)
+
+if( NOT RCC_HAS_ATOMICS )
+ message(STATUS "Warning: RCC will be built thread-unsafe because atomic builtins are missing")
+endif()
diff --git a/rcc/cmake/modules/CheckCompilerVersion.cmake b/rcc/cmake/modules/CheckCompilerVersion.cmake
new file mode 100644
index 0000000..7a9f964
--- /dev/null
+++ b/rcc/cmake/modules/CheckCompilerVersion.cmake
@@ -0,0 +1,110 @@
+# Check if the host compiler is new enough.
+# These versions are updated based on the following policy:
+# rcc.org/docs/DeveloperPolicy.html#toolchain
+
+include(CheckCXXSourceCompiles)
+
+set(GCC_MIN 7.4)
+set(GCC_SOFT_ERROR 7.4)
+set(CLANG_MIN 5.0)
+set(CLANG_SOFT_ERROR 5.0)
+set(APPLECLANG_MIN 10.0)
+set(APPLECLANG_SOFT_ERROR 10.0)
+
+# https://en.wikipedia.org/wiki/Microsoft_Visual_C#Internal_version_numbering
+# _MSC_VER == 1928 MSVC++ 19.27 Visual Studio 2019 Version 16.8 + 16.9
+set(MSVC_MIN 19.28)
+set(MSVC_SOFT_ERROR 19.28)
+
+set(LIBSTDCXX_MIN 7)
+set(LIBSTDCXX_SOFT_ERROR 7)
+
+
+if(DEFINED RCC_COMPILER_CHECKED)
+ return()
+endif()
+set(RCC_COMPILER_CHECKED ON)
+
+if(RCC_FORCE_USE_OLD_TOOLCHAIN)
+ return()
+endif()
+
+function(check_compiler_version NAME NICE_NAME MINIMUM_VERSION SOFT_ERROR_VERSION)
+ if(NOT CMAKE_CXX_COMPILER_ID STREQUAL NAME)
+ return()
+ endif()
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS MINIMUM_VERSION)
+ message(FATAL_ERROR "Host ${NICE_NAME} version must be at least ${MINIMUM_VERSION}, your version is ${CMAKE_CXX_COMPILER_VERSION}.")
+ elseif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS SOFT_ERROR_VERSION)
+ if(RCC_TEMPORARILY_ALLOW_OLD_TOOLCHAIN)
+ message(WARNING "Host ${NICE_NAME} version should be at least ${SOFT_ERROR_VERSION} because RCC will soon use new C++ features which your toolchain version doesn't support. Your version is ${CMAKE_CXX_COMPILER_VERSION}. Ignoring because you've set RCC_TEMPORARILY_ALLOW_OLD_TOOLCHAIN, but very soon your toolchain won't be supported.")
+ else()
+ message(FATAL_ERROR "Host ${NICE_NAME} version should be at least ${SOFT_ERROR_VERSION} because RCC will soon use new C++ features which your toolchain version doesn't support. Your version is ${CMAKE_CXX_COMPILER_VERSION}. You can temporarily opt out using RCC_TEMPORARILY_ALLOW_OLD_TOOLCHAIN, but very soon your toolchain won't be supported.")
+ endif()
+ endif()
+endfunction(check_compiler_version)
+
+check_compiler_version("GNU" "GCC" ${GCC_MIN} ${GCC_SOFT_ERROR})
+check_compiler_version("Clang" "Clang" ${CLANG_MIN} ${CLANG_SOFT_ERROR})
+check_compiler_version("AppleClang" "Apple Clang" ${APPLECLANG_MIN} ${APPLECLANG_SOFT_ERROR})
+check_compiler_version("MSVC" "Visual Studio" ${MSVC_MIN} ${MSVC_SOFT_ERROR})
+
+# See https://developercommunity.visualstudio.com/content/problem/845933/miscompile-boolean-condition-deduced-to-be-always.html
+# and thread "[rcc-dev] Longstanding failing tests - clang-tidy, MachO, Polly"
+# on rcc-dev Jan 21-23 2020.
+if ((${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) AND
+ (19.24 VERSION_LESS_EQUAL ${CMAKE_CXX_COMPILER_VERSION}) AND
+ (${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 19.25))
+ if(RCC_TEMPORARILY_ALLOW_OLD_TOOLCHAIN)
+ message(WARNING "Host Visual Studio version 16.4 is known to miscompile part of RCC")
+ else()
+ message(FATAL_ERROR "Host Visual Studio version 16.4 is known to miscompile part of RCC, please use clang-cl or upgrade to 16.5 or above (use -DRCC_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON to ignore)")
+ endif()
+endif()
+
+
+if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ if (CMAKE_CXX_SIMULATE_ID MATCHES "MSVC")
+ if (CMAKE_CXX_SIMULATE_VERSION VERSION_LESS MSVC_MIN)
+ message(FATAL_ERROR "Host Clang must have at least -fms-compatibility-version=${MSVC_MIN}, your version is ${CMAKE_CXX_SIMULATE_VERSION}.")
+ endif()
+ set(CLANG_CL 1)
+ elseif(NOT RCC_ENABLE_LIBCXX)
+ # Test that we aren't using too old of a version of libstdc++.
+ set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
+ set(OLD_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+ set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++0x")
+ check_cxx_source_compiles("
+#include <iosfwd>
+#if defined(__GLIBCXX__)
+#if !defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE < ${LIBSTDCXX_MIN}
+#error Unsupported libstdc++ version
+#endif
+#endif
+int main() { return 0; }
+"
+ RCC_LIBSTDCXX_MIN)
+ if(NOT RCC_LIBSTDCXX_MIN)
+ message(FATAL_ERROR "libstdc++ version must be at least ${GCC_MIN}.")
+ endif()
+ check_cxx_source_compiles("
+#include <iosfwd>
+#if defined(__GLIBCXX__)
+#if !defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE < ${LIBSTDCXX_SOFT_ERROR}
+#error Unsupported libstdc++ version
+#endif
+#endif
+int main() { return 0; }
+"
+ RCC_LIBSTDCXX_SOFT_ERROR)
+ if(NOT RCC_LIBSTDCXX_SOFT_ERROR)
+ if(RCC_TEMPORARILY_ALLOW_OLD_TOOLCHAIN)
+ message(WARNING "libstdc++ version should be at least ${LIBSTDCXX_SOFT_ERROR} because RCC will soon use new C++ features which your toolchain version doesn't support. Ignoring because you've set RCC_TEMPORARILY_ALLOW_OLD_TOOLCHAIN, but very soon your toolchain won't be supported.")
+ else()
+ message(FATAL_ERROR "libstdc++ version should be at least ${LIBSTDCXX_SOFT_ERROR} because RCC will soon use new C++ features which your toolchain version doesn't support. You can temporarily opt out using RCC_TEMPORARILY_ALLOW_OLD_TOOLCHAIN, but very soon your toolchain won't be supported.")
+ endif()
+ endif()
+ set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
+ set(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQUIRED_LIBRARIES})
+ endif()
+endif()
diff --git a/rcc/cmake/modules/CheckProblematicConfigurations.cmake b/rcc/cmake/modules/CheckProblematicConfigurations.cmake
new file mode 100644
index 0000000..3b96db9
--- /dev/null
+++ b/rcc/cmake/modules/CheckProblematicConfigurations.cmake
@@ -0,0 +1,19 @@
+
+option(RCC_ALLOW_PROBLEMATIC_CONFIGURATIONS OFF "Set this option to ON to allow problematic toolchain configurations. Use on your own risk.")
+
+macro(log_problematic MESSAGE)
+ if(RCC_ALLOW_PROBLEMATIC_CONFIGURATIONS)
+ message(WARNING "${MESSAGE}")
+ else()
+ message(FATAL_ERROR "${MESSAGE}\nYou can force usage of this configuration by passing -DRCC_ALLOW_PROBLEMATIC_CONFIGURATIONS=ON")
+ endif()
+endmacro()
+
+# MSVC and /arch:AVX is untested and have created problems before. See:
+# https://github.com/rcc/rcc-project/issues/54645
+if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+ string(TOLOWER "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}" _FLAGS)
+ if(_FLAGS MATCHES "/arch:avx[0-9]*")
+ log_problematic("Compiling RCC with MSVC and the /arch:AVX flag is known to cause issues with parts of RCC.\nSee https://github.com/rcc/rcc-project/issues/54645 for details.\nUse clang-cl if you want to enable AVX instructions.")
+ endif()
+endif()
diff --git a/rcc/cmake/modules/DetermineGCCCompatible.cmake b/rcc/cmake/modules/DetermineGCCCompatible.cmake
new file mode 100644
index 0000000..b645e45
--- /dev/null
+++ b/rcc/cmake/modules/DetermineGCCCompatible.cmake
@@ -0,0 +1,13 @@
+# Determine if the compiler has GCC-compatible command-line syntax.
+
+if(NOT DEFINED RCC_COMPILER_IS_GCC_COMPATIBLE)
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ set(RCC_COMPILER_IS_GCC_COMPATIBLE ON)
+ elseif( MSVC )
+ set(RCC_COMPILER_IS_GCC_COMPATIBLE OFF)
+ elseif( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
+ set(RCC_COMPILER_IS_GCC_COMPATIBLE ON)
+ elseif( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel" )
+ set(RCC_COMPILER_IS_GCC_COMPATIBLE ON)
+ endif()
+endif()
diff --git a/rcc/cmake/modules/FindFFI.cmake b/rcc/cmake/modules/FindFFI.cmake
new file mode 100644
index 0000000..b1f6452
--- /dev/null
+++ b/rcc/cmake/modules/FindFFI.cmake
@@ -0,0 +1,106 @@
+# Attempts to discover ffi library with a linkable ffi_call function.
+#
+# Example usage:
+#
+# find_package(FFI)
+#
+# FFI_REQUIRE_INCLUDE may be set to consider ffi found if the includes
+# are present in addition to the library. This is useful to keep off
+# for the imported package on platforms that install the library but
+# not the headers.
+#
+# FFI_LIBRARY_DIR may be set to define search paths for the ffi library.
+#
+# If successful, the following variables will be defined:
+# FFI_FOUND
+# FFI_INCLUDE_DIRS
+# FFI_LIBRARIES
+# FFI_STATIC_LIBRARIES
+# HAVE_FFI_CALL
+#
+# HAVE_FFI_H or HAVE_FFI_FFI_H is defined depending on the ffi.h include path.
+#
+# Additionally, the following import target will be defined:
+# FFI::ffi
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_LIBFFI QUIET libffi)
+
+find_path(FFI_INCLUDE_DIRS ffi.h PATHS ${FFI_INCLUDE_DIR} ${PC_LIBFFI_INCLUDE_DIRS})
+if( EXISTS "${FFI_INCLUDE_DIRS}/ffi.h" )
+ set(FFI_HEADER ffi.h CACHE INTERNAL "")
+ set(HAVE_FFI_H 1 CACHE INTERNAL "")
+else()
+ find_path(FFI_INCLUDE_DIRS ffi/ffi.h PATHS ${FFI_INCLUDE_DIR})
+ if( EXISTS "${FFI_INCLUDE_DIRS}/ffi/ffi.h" )
+ set(FFI_HEADER ffi/ffi.h CACHE INTERNAL "")
+ set(HAVE_FFI_FFI_H 1 CACHE INTERNAL "")
+ endif()
+endif()
+
+find_library(FFI_LIBRARIES NAMES ffi PATHS ${FFI_LIBRARY_DIR} ${PC_LIBFFI_LIBRARY_DIRS})
+find_library(FFI_STATIC_LIBRARIES NAMES libffi.a PATHS ${FFI_LIBRARY_DIR} ${PC_LIBFFI_LIBRARY_DIRS})
+
+if(FFI_LIBRARIES)
+ include(CMakePushCheckState)
+ cmake_push_check_state()
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ${FFI_LIBRARIES})
+ set(HAVE_FFI_CALL_SRC [=[
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ struct ffi_cif;
+ typedef struct ffi_cif ffi_cif;
+ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue);
+ #ifdef __cplusplus
+ }
+ #endif
+ int main(void) { ffi_call(0, 0, 0, 0); }
+ ]=])
+ if(DEFINED CMAKE_C_COMPILER)
+ include(CheckCSourceCompiles)
+ check_c_source_compiles("${HAVE_FFI_CALL_SRC}" HAVE_FFI_CALL)
+ else()
+ include(CheckCXXSourceCompiles)
+ check_cxx_source_compiles("${HAVE_FFI_CALL_SRC}" HAVE_FFI_CALL)
+ endif()
+ cmake_pop_check_state()
+endif()
+
+unset(required_includes)
+if(FFI_REQUIRE_INCLUDE)
+ set(required_includes FFI_INCLUDE_DIRS)
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(FFI
+ FOUND_VAR
+ FFI_FOUND
+ REQUIRED_VARS
+ FFI_LIBRARIES
+ ${required_includes}
+ HAVE_FFI_CALL)
+mark_as_advanced(FFI_LIBRARIES
+ FFI_STATIC_LIBRARIES
+ FFI_INCLUDE_DIRS
+ HAVE_FFI_CALL
+ FFI_HEADER
+ HAVE_FFI_H
+ HAVE_FFI_FFI_H)
+
+if(FFI_FOUND)
+ if(NOT TARGET FFI::ffi AND FFI_LIBRARIES)
+ add_library(FFI::ffi UNKNOWN IMPORTED)
+ set_target_properties(FFI::ffi PROPERTIES IMPORTED_LOCATION "${FFI_LIBRARIES}")
+ if(FFI_INCLUDE_DIRS)
+ set_target_properties(FFI::ffi PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFI_INCLUDE_DIRS}")
+ endif()
+ endif()
+ if(NOT TARGET FFI::ffi_static AND FFI_STATIC_LIBRARIES)
+ add_library(FFI::ffi_static UNKNOWN IMPORTED)
+ set_target_properties(FFI::ffi_static PROPERTIES IMPORTED_LOCATION "${FFI_STATIC_LIBRARIES}")
+ if(FFI_INCLUDE_DIRS)
+ set_target_properties(FFI::ffi_static PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFI_INCLUDE_DIRS}")
+ endif()
+ endif()
+endif()
diff --git a/rcc/cmake/modules/FindLibEdit.cmake b/rcc/cmake/modules/FindLibEdit.cmake
new file mode 100644
index 0000000..b3f49e1
--- /dev/null
+++ b/rcc/cmake/modules/FindLibEdit.cmake
@@ -0,0 +1,65 @@
+#.rst:
+# FindLibEdit
+# -----------
+#
+# Find libedit library and headers
+#
+# The module defines the following variables:
+#
+# ::
+#
+# LibEdit_FOUND - true if libedit was found
+# LibEdit_INCLUDE_DIRS - include search path
+# LibEdit_LIBRARIES - libraries to link
+# LibEdit_VERSION_STRING - version number
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_LIBEDIT QUIET libedit)
+
+find_path(LibEdit_INCLUDE_DIRS NAMES histedit.h HINTS ${PC_LIBEDIT_INCLUDE_DIRS})
+find_library(LibEdit_LIBRARIES NAMES edit HINTS ${PC_LIBEDIT_LIBRARY_DIRS})
+
+include(CheckIncludeFile)
+if(LibEdit_INCLUDE_DIRS AND EXISTS "${LibEdit_INCLUDE_DIRS}/histedit.h")
+ include(CMakePushCheckState)
+ cmake_push_check_state()
+ list(APPEND CMAKE_REQUIRED_INCLUDES ${LibEdit_INCLUDE_DIRS})
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ${LibEdit_LIBRARIES})
+ check_include_file(histedit.h HAVE_HISTEDIT_H)
+ cmake_pop_check_state()
+ if (HAVE_HISTEDIT_H)
+ file(STRINGS "${LibEdit_INCLUDE_DIRS}/histedit.h"
+ libedit_major_version_str
+ REGEX "^#define[ \t]+LIBEDIT_MAJOR[ \t]+[0-9]+")
+ string(REGEX REPLACE "^#define[ \t]+LIBEDIT_MAJOR[ \t]+([0-9]+)" "\\1"
+ libedit_major_version "${libedit_major_version_str}")
+
+ file(STRINGS "${LibEdit_INCLUDE_DIRS}/histedit.h"
+ libedit_minor_version_str
+ REGEX "^#define[ \t]+LIBEDIT_MINOR[ \t]+[0-9]+")
+ string(REGEX REPLACE "^#define[ \t]+LIBEDIT_MINOR[ \t]+([0-9]+)" "\\1"
+ libedit_minor_version "${libedit_minor_version_str}")
+
+ set(LibEdit_VERSION_STRING "${libedit_major_version}.${libedit_minor_version}")
+ else()
+ set(LibEdit_INCLUDE_DIRS "")
+ set(LibEdit_LIBRARIES "")
+ endif()
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LibEdit
+ FOUND_VAR
+ LibEdit_FOUND
+ REQUIRED_VARS
+ LibEdit_INCLUDE_DIRS
+ LibEdit_LIBRARIES
+ VERSION_VAR
+ LibEdit_VERSION_STRING)
+mark_as_advanced(LibEdit_INCLUDE_DIRS LibEdit_LIBRARIES)
+
+if (LibEdit_FOUND AND NOT TARGET LibEdit::LibEdit)
+ add_library(LibEdit::LibEdit INTERFACE IMPORTED)
+ target_link_libraries(LibEdit::LibEdit INTERFACE ${LibEdit_LIBRARIES})
+ target_include_directories(LibEdit::LibEdit INTERFACE ${LibEdit_INCLUDE_DIRS})
+endif()
diff --git a/rcc/cmake/modules/FindLibpfm.cmake b/rcc/cmake/modules/FindLibpfm.cmake
new file mode 100644
index 0000000..9e5900b
--- /dev/null
+++ b/rcc/cmake/modules/FindLibpfm.cmake
@@ -0,0 +1,37 @@
+# CMake module for finding libpfm4.
+#
+# If successful, the following variables will be defined:
+# HAVE_LIBPFM
+#
+# Libpfm can be disabled by setting RCC_ENABLE_LIBPFM to 0.
+
+include(CheckIncludeFile)
+include(CheckLibraryExists)
+include(CheckCXXSourceCompiles)
+
+if (RCC_ENABLE_LIBPFM)
+ check_library_exists(pfm pfm_initialize "" HAVE_LIBPFM_INITIALIZE)
+ if(HAVE_LIBPFM_INITIALIZE)
+ check_include_file(perfmon/perf_event.h HAVE_PERFMON_PERF_EVENT_H)
+ check_include_file(perfmon/pfmlib.h HAVE_PERFMON_PFMLIB_H)
+ check_include_file(perfmon/pfmlib_perf_event.h HAVE_PERFMON_PFMLIB_PERF_EVENT_H)
+ if(HAVE_PERFMON_PERF_EVENT_H AND HAVE_PERFMON_PFMLIB_H AND HAVE_PERFMON_PFMLIB_PERF_EVENT_H)
+ set(HAVE_LIBPFM 1)
+ # Check to see if perf_branch_entry has the field 'cycles'.
+ # We couldn't use CheckStructHasMember here because 'cycles' is a bit field which is not
+ # supported by CheckStructHasMember.
+ CHECK_CXX_SOURCE_COMPILES("
+ #include <perfmon/perf_event.h>
+ int main() {
+ perf_branch_entry entry;
+ entry.cycles = 2;
+ return 0;
+ }" COMPILE_WITH_CYCLES)
+ if(COMPILE_WITH_CYCLES)
+ set(LIBPFM_HAS_FIELD_CYCLES 1)
+ endif()
+ endif()
+ endif()
+endif()
+
+
diff --git a/rcc/cmake/modules/FindOCaml.cmake b/rcc/cmake/modules/FindOCaml.cmake
new file mode 100644
index 0000000..8eba212
--- /dev/null
+++ b/rcc/cmake/modules/FindOCaml.cmake
@@ -0,0 +1,103 @@
+# CMake find_package() module for the OCaml language.
+# Assumes ocamlfind will be used for compilation.
+# http://ocaml.org/
+#
+# Example usage:
+#
+# find_package(OCaml)
+#
+# If successful, the following variables will be defined:
+# OCAMLFIND
+# OCAML_VERSION
+# OCAML_STDLIB_PATH
+# HAVE_OCAMLOPT
+#
+# Also provides find_ocamlfind_package() macro.
+#
+# Example usage:
+#
+# find_ocamlfind_package(ctypes)
+#
+# In any case, the following variables are defined:
+#
+# HAVE_OCAML_${pkg}
+#
+# If successful, the following variables will be defined:
+#
+# OCAML_${pkg}_VERSION
+
+include( FindPackageHandleStandardArgs )
+
+find_program(OCAMLFIND
+ NAMES ocamlfind)
+
+if( OCAMLFIND )
+ execute_process(
+ COMMAND ${OCAMLFIND} ocamlc -version
+ OUTPUT_VARIABLE OCAML_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ execute_process(
+ COMMAND ${OCAMLFIND} ocamlc -where
+ OUTPUT_VARIABLE OCAML_STDLIB_PATH
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ execute_process(
+ COMMAND ${OCAMLFIND} ocamlc -version
+ OUTPUT_QUIET
+ RESULT_VARIABLE find_ocaml_result)
+ if( find_ocaml_result EQUAL 0 )
+ set(HAVE_OCAMLOPT TRUE)
+ else()
+ set(HAVE_OCAMLOPT FALSE)
+ endif()
+endif()
+
+find_package_handle_standard_args( OCaml DEFAULT_MSG
+ OCAMLFIND
+ OCAML_VERSION
+ OCAML_STDLIB_PATH)
+
+mark_as_advanced(
+ OCAMLFIND)
+
+function(find_ocamlfind_package pkg)
+ CMAKE_PARSE_ARGUMENTS(ARG "OPTIONAL" "VERSION" "" ${ARGN})
+
+ execute_process(
+ COMMAND "${OCAMLFIND}" "query" "${pkg}" "-format" "%v"
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE version
+ ERROR_VARIABLE error
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_STRIP_TRAILING_WHITESPACE)
+
+ if( NOT result EQUAL 0 AND NOT ARG_OPTIONAL )
+ message(FATAL_ERROR ${error})
+ endif()
+
+ if( result EQUAL 0 )
+ set(found TRUE)
+ else()
+ set(found FALSE)
+ endif()
+
+ if( found AND ARG_VERSION )
+ if( version VERSION_LESS ARG_VERSION AND ARG_OPTIONAL )
+ # If it's optional and the constraint is not satisfied, pretend
+ # it wasn't found.
+ set(found FALSE)
+ elseif( version VERSION_LESS ARG_VERSION )
+ message(FATAL_ERROR
+ "ocamlfind package ${pkg} should have version ${ARG_VERSION} or newer")
+ endif()
+ endif()
+
+ string(TOUPPER ${pkg} pkg)
+
+ set(HAVE_OCAML_${pkg} ${found}
+ PARENT_SCOPE)
+
+ set(OCAML_${pkg}_VERSION ${version}
+ PARENT_SCOPE)
+endfunction()
diff --git a/rcc/cmake/modules/GetErrcMessages.cmake b/rcc/cmake/modules/GetErrcMessages.cmake
new file mode 100644
index 0000000..ad94f6a
--- /dev/null
+++ b/rcc/cmake/modules/GetErrcMessages.cmake
@@ -0,0 +1,45 @@
+# This function returns the messages of various POSIX error codes as they are returned by std::error_code.
+# The purpose of this function is to supply those error messages to rcc-lit using the errc_messages config.
+# Currently supplied and needed error codes: ENOENT, EISDIR, EINVAL and EACCES.
+# Messages are semi colon separated.
+# Keep amount, order and tested error codes in sync with rcc/utils/lit/lit/rcc/config.py.
+function(get_errc_messages outvar)
+ if(CMAKE_CROSSCOMPILING AND NOT CMAKE_CROSSCOMPILING_EMULATOR AND NOT DEFINED errc_exit_code)
+ set(${outvar} "" PARENT_SCOPE)
+ message(STATUS "Can't get errc messages in cross-compilation mode")
+ return()
+ endif()
+
+ set(errc_test_code ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/getErrc.cpp)
+
+ file(WRITE ${errc_test_code} "
+ #include <cerrno>
+ #include <iostream>
+ #include <string>
+ #include <system_error>
+
+ std::string getMessageFor(int err) {
+ return std::make_error_code(static_cast<std::errc>(err)).message();
+ }
+
+ int main() {
+ std::cout << getMessageFor(ENOENT) << ';' << getMessageFor(EISDIR);
+ std::cout << ';' << getMessageFor(EINVAL) << ';' << getMessageFor(EACCES);
+ return 0;
+ }
+ ")
+
+ try_run(errc_exit_code
+ errc_compiled
+ ${CMAKE_BINARY_DIR}
+ ${errc_test_code}
+ RUN_OUTPUT_VARIABLE errc_result
+ COMPILE_OUTPUT_VARIABLE errc_compile_errors)
+ if (errc_compiled AND "${errc_exit_code}" STREQUAL "0")
+ set(${outvar} ${errc_result} PARENT_SCOPE)
+ else()
+ set(${outvar} "" PARENT_SCOPE)
+ message(NOTICE "${errc_compile_errors}")
+ message(STATUS "Failed to get errc messages")
+ endif ()
+endfunction()
diff --git a/rcc/cmake/modules/GetHostTriple.cmake b/rcc/cmake/modules/GetHostTriple.cmake
new file mode 100644
index 0000000..046fc36
--- /dev/null
+++ b/rcc/cmake/modules/GetHostTriple.cmake
@@ -0,0 +1,98 @@
+# Returns the host triple.
+# Invokes config.guess, except for platforms it cannot identify.
+
+function( get_host_triple var )
+ if( MSVC OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
+ if( CMAKE_C_COMPILER_ARCHITECTURE_ID MATCHES "ARM64.*" )
+ set( value "aarch64-pc-windows-msvc" )
+ elseif( CMAKE_C_COMPILER_ARCHITECTURE_ID MATCHES "ARM.*" )
+ set( value "armv7-pc-windows-msvc" )
+ elseif( CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "x64" )
+ set( value "x86_64-pc-windows-msvc" )
+ elseif( CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "X86" )
+ set( value "i686-pc-windows-msvc" )
+ elseif( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+ set( value "x86_64-pc-windows-msvc" )
+ else()
+ set( value "i686-pc-windows-msvc" )
+ endif()
+ elseif( MINGW AND NOT MSYS )
+ # CMake doesn't provide COMPILER_ARCHITECTURE_ID for Clang/GCC,
+ # but it does for MSVC.
+ if( CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "ARM.*" )
+ if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+ set( value "aarch64-w64-windows-gnu" )
+ else()
+ set( value "armv7-w64-windows-gnu" )
+ endif()
+ else()
+ if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+ set( value "x86_64-w64-windows-gnu" )
+ else()
+ set( value "i686-w64-windows-gnu" )
+ endif()
+ endif()
+ elseif( CMAKE_SYSTEM_NAME MATCHES "OS390" )
+ set( value "s390x-ibm-zos" )
+ elseif( CMAKE_SYSTEM_NAME STREQUAL "AIX" )
+ # We defer to dynamic detection of the host AIX version.
+ if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+ set( value "powerpc64-ibm-aix" )
+ else()
+ set( value "powerpc-ibm-aix" )
+ endif()
+ elseif( CMAKE_HOST_SYSTEM_NAME MATCHES "HarmonyOS|OpenHarmony|OHOS" )
+ # config.guess cannot identify HarmonyOS: uname -s reports "HarmonyOS",
+ # which config.guess does not recognize, and its probing is rejected by
+ # the system sandbox. Build the triple from CMake's host detection using
+ # the form clang targets on OHOS (e.g. aarch64-unknown-linux-ohos). CMake
+ # itself may report the host processor as "unknown" because uname -p does,
+ # so fall back to asking uname -m directly.
+ set( TT_MACHINE "${CMAKE_HOST_SYSTEM_PROCESSOR}" )
+ if( NOT TT_MACHINE OR TT_MACHINE STREQUAL "unknown" )
+ find_program( TT_UNAME uname PATHS /bin /usr/bin /usr/local/bin
+ NO_CMAKE_FIND_ROOT_PATH )
+ set( TT_RV 1 )
+ if( TT_UNAME )
+ execute_process( COMMAND ${TT_UNAME} -m
+ RESULT_VARIABLE TT_RV
+ OUTPUT_VARIABLE TT_MACHINE
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET )
+ endif()
+ if( NOT TT_RV EQUAL 0 )
+ set( TT_MACHINE "" )
+ endif()
+ endif()
+ if( TT_MACHINE MATCHES "aarch64|arm64" )
+ set( value "aarch64-unknown-linux-ohos" )
+ elseif( TT_MACHINE MATCHES "^arm" )
+ set( value "arm-unknown-linux-ohos" )
+ elseif( TT_MACHINE MATCHES "^x86_64" )
+ set( value "x86_64-unknown-linux-ohos" )
+ elseif( TT_MACHINE MATCHES "^riscv64" )
+ set( value "riscv64-unknown-linux-ohos" )
+ elseif( TT_MACHINE MATCHES "^loongarch64" )
+ set( value "loongarch64-unknown-linux-ohos" )
+ else()
+ message( FATAL_ERROR
+ "Failed to determine host triple for ${CMAKE_HOST_SYSTEM_NAME}: "
+ "host processor \"${TT_MACHINE}\" is not supported" )
+ endif()
+ else()
+ if(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows AND NOT MSYS)
+ message(WARNING "unable to determine host target triple")
+ else()
+ set(config_guess ${RCC_MAIN_SRC_DIR}/cmake/config.guess)
+ execute_process(COMMAND sh ${config_guess}
+ RESULT_VARIABLE TT_RV
+ OUTPUT_VARIABLE TT_OUT
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if( NOT TT_RV EQUAL 0 )
+ message(FATAL_ERROR "Failed to execute ${config_guess}")
+ endif( NOT TT_RV EQUAL 0 )
+ set( value ${TT_OUT} )
+ endif()
+ endif()
+ set( ${var} ${value} PARENT_SCOPE )
+endfunction( get_host_triple var )
diff --git a/rcc/cmake/modules/HandleRCCOptions.cmake b/rcc/cmake/modules/HandleRCCOptions.cmake
new file mode 100644
index 0000000..6b99829
--- /dev/null
+++ b/rcc/cmake/modules/HandleRCCOptions.cmake
@@ -0,0 +1,1182 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+include_guard(GLOBAL)
+
+include(CheckCCompilerFlag)
+include(CheckCSourceCompiles)
+include(CheckCXXCompilerFlag)
+include(CheckCXXSourceCompiles)
+include(CMakePushCheckState)
+include(CheckLinkerFlag)
+include(CheckSymbolExists)
+
+function(rcc_append_flags value)
+ foreach(variable IN LISTS ARGN)
+ set(${variable} "${${variable}} ${value}" PARENT_SCOPE)
+ endforeach()
+endfunction()
+
+macro(rcc_add_supported_warning flag name)
+ check_c_compiler_flag("-Werror ${flag}" RCC_C_SUPPORTS_${name})
+ if(RCC_C_SUPPORTS_${name})
+ rcc_append_flags("${flag}" CMAKE_C_FLAGS)
+ endif()
+ check_cxx_compiler_flag("-Werror ${flag}" RCC_CXX_SUPPORTS_${name})
+ if(RCC_CXX_SUPPORTS_${name})
+ rcc_append_flags("${flag}" CMAKE_CXX_FLAGS)
+ endif()
+endmacro()
+
+macro(rcc_configure_job_pools)
+ set(RCC_PARALLEL_COMPILE_JOBS "" CACHE STRING "Maximum concurrent compilation jobs (Ninja only)")
+ set(RCC_PARALLEL_LINK_JOBS "" CACHE STRING "Maximum concurrent link jobs (Ninja only)")
+ if(RCC_RAM_PER_COMPILE_JOB OR RCC_RAM_PER_LINK_JOB)
+ cmake_host_system_information(RESULT rccAvailableMemory QUERY AVAILABLE_PHYSICAL_MEMORY)
+ cmake_host_system_information(RESULT rccLogicalCores QUERY NUMBER_OF_LOGICAL_CORES)
+ endif()
+ foreach(rccJobKind COMPILE LINK)
+ if(RCC_RAM_PER_${rccJobKind}_JOB)
+ math(EXPR rccMemoryJobs "${rccAvailableMemory} / ${RCC_RAM_PER_${rccJobKind}_JOB}" OUTPUT_FORMAT DECIMAL)
+ if(rccMemoryJobs LESS 1)
+ set(rccMemoryJobs 1)
+ endif()
+ if(rccMemoryJobs LESS rccLogicalCores)
+ set(RCC_PARALLEL_${rccJobKind}_JOBS "${rccMemoryJobs}")
+ else()
+ set(RCC_PARALLEL_${rccJobKind}_JOBS "${rccLogicalCores}")
+ endif()
+ endif()
+ endforeach()
+ if(RCC_PARALLEL_COMPILE_JOBS)
+ if(CMAKE_GENERATOR MATCHES "Ninja")
+ set_property(GLOBAL APPEND PROPERTY JOB_POOLS compile_job_pool=${RCC_PARALLEL_COMPILE_JOBS})
+ set(CMAKE_JOB_POOL_COMPILE compile_job_pool)
+ else()
+ message(WARNING "Job pooling is only available with Ninja generators.")
+ endif()
+ endif()
+ if(CMAKE_GENERATOR MATCHES "Ninja")
+ if(NOT RCC_PARALLEL_LINK_JOBS AND rccLTOMode STREQUAL "THIN")
+ message(STATUS "ThinLTO provides its own parallel linking - limiting parallel link jobs to 2.")
+ set(RCC_PARALLEL_LINK_JOBS 2)
+ endif()
+ if(RCC_PARALLEL_LINK_JOBS)
+ set_property(GLOBAL APPEND PROPERTY JOB_POOLS link_job_pool=${RCC_PARALLEL_LINK_JOBS})
+ set(CMAKE_JOB_POOL_LINK link_job_pool)
+ endif()
+ elseif(RCC_PARALLEL_LINK_JOBS)
+ message(WARNING "Job pooling is only available with Ninja generators.")
+ endif()
+endmacro()
+
+macro(rcc_configure_platform_checks)
+ if(UNIX AND CMAKE_SYSTEM_NAME MATCHES "AIX")
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_XOPEN_SOURCE=700" "-D_LARGE_FILE_API")
+ endif()
+ if(UNIX AND CMAKE_SYSTEM_NAME MATCHES "SunOS")
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_FILE_OFFSET_BITS=64")
+ endif()
+ check_symbol_exists(__GLIBC__ stdio.h RCC_USING_GLIBC)
+ if(RCC_USING_GLIBC OR CYGWIN)
+ add_compile_definitions(_GNU_SOURCE)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE")
+ endif()
+ if(RCC_USING_GLIBC AND CMAKE_SIZEOF_VOID_P EQUAL 4)
+ add_compile_definitions(_FILE_OFFSET_BITS=64)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_FILE_OFFSET_BITS=64")
+ endif()
+ if(NOT RCC_ENABLE_PIC)
+ rcc_append_flags("-fno-pie" CMAKE_EXE_LINKER_FLAGS)
+ endif()
+endmacro()
+
+macro(rcc_configure_platform_link_options)
+ if(APPLE)
+ rcc_append_flags("-Wl,-flat_namespace -Wl,-undefined -Wl,dynamic_lookup" CMAKE_MODULE_LINKER_FLAGS)
+ endif()
+ if(CMAKE_SYSTEM_NAME MATCHES "AIX")
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
+ rcc_append_flags("-mcmodel=large" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ rcc_append_flags("-Wl,-bglink=large" CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES "XL")
+ rcc_append_flags("-Wl,-bbigtoc -bcdtors:mbr"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+ if(BUILD_SHARED_LIBS)
+ message(WARNING "Build and install environment path info may be exposed; binaries will also be unrelocatable.")
+ endif()
+ endif()
+ if(CMAKE_SYSTEM_NAME MATCHES "OS390")
+ rcc_append_flags("-Wl,-bcompress=yes" CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+ if(NOT (CMAKE_SYSTEM_NAME MATCHES "Darwin|FreeBSD|OpenBSD|DragonFly|AIX|OS390|Emscripten"
+ OR WIN32 OR CYGWIN) AND NOT RCC_USE_SANITIZER)
+ rcc_append_flags("-Wl,-z,defs" CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+endmacro()
+
+macro(rcc_configure_platform_definitions)
+ if(UNIX AND CMAKE_SYSTEM_NAME MATCHES "AIX")
+ add_compile_definitions(_XOPEN_SOURCE=700 _LARGE_FILE_API)
+ add_compile_options(-pthread)
+ rcc_append_flags("-shared -Wl,-G" CMAKE_MODULE_LINKER_FLAGS)
+ rcc_append_flags("-shared" CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+ if(CMAKE_SYSTEM_NAME MATCHES "OS390")
+ add_compile_definitions(_XOPEN_SOURCE=600 _XPLATFORM_SOURCE _OPEN_SYS _OPEN_SYS_FILE_EXT _EXT)
+ rcc_append_flags("-fzos-le-char-mode=ascii -m64" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ if(UNIX AND CMAKE_SYSTEM_NAME MATCHES "SunOS")
+ add_compile_definitions(_FILE_OFFSET_BITS=64)
+ endif()
+endmacro()
+
+macro(rcc_configure_warning_options)
+ if(MSVC)
+ if(RCC_ENABLE_WERROR)
+ rcc_append_flags("/WX" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ if(RCC_ENABLE_WARNINGS)
+ string(REGEX REPLACE " /W[0-4]" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+ string(REGEX REPLACE " /W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ rcc_append_flags("/W4" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ if(NOT RCC_CLANG_CL)
+ if(RCC_ENABLE_WARNING_SUPPRESSIONS)
+ rcc_append_flags(
+ "-wd4146 -wd4244 -wd4267 -wd4456 -wd4457 -wd4458 -wd4459 -wd4624 -wd4100 -wd4127 -wd4505 -wd4702 -wd4245 -wd4310 -wd4701 -wd4703 -wd4389 -wd4805 -wd4577 -wd4319 -wd4324 -wd4251 -wd4275"
+ CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ rcc_append_flags("-w14062 -we4238" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ endif()
+
+ if(RCC_GCC_COMPATIBLE AND RCC_ENABLE_WERROR)
+ rcc_append_flags("-Werror" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ rcc_append_flags("-Wno-error" CMAKE_REQUIRED_FLAGS)
+ endif()
+ if(RCC_GCC_COMPATIBLE OR CMAKE_CXX_COMPILER_ID MATCHES "XL")
+ rcc_append_flags("-Werror=date-time" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ rcc_append_flags("-Werror=unguarded-availability-new" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+
+ set(rccInitialCFlags "${CMAKE_C_FLAGS}")
+ set(rccInitialCXXFlags "${CMAKE_CXX_FLAGS}")
+ if(RCC_ENABLE_WARNINGS AND (RCC_GCC_COMPATIBLE OR RCC_CLANG_CL))
+ if(NOT RCC_CLANG_CL)
+ rcc_append_flags("-Wall" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ rcc_append_flags("-Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual"
+ CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ rcc_append_flags("-Wno-missing-field-initializers" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ else()
+ rcc_append_flags("-Wmissing-field-initializers" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+
+ if(RCC_ENABLE_PEDANTIC AND RCC_GCC_COMPATIBLE)
+ rcc_append_flags("-pedantic -Wno-long-long" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ rcc_add_supported_warning("-Wc++98-compat-extra-semi" CXX98_COMPAT_EXTRA_SEMI)
+ endif()
+ rcc_append_flags("-Wimplicit-fallthrough" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ rcc_append_flags("-Wcovered-switch-default" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ # Match LLVM's GCC warning suppression policy and version conditions.
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15.0)
+ rcc_append_flags("-Wno-uninitialized" CMAKE_CXX_FLAGS)
+ else()
+ rcc_append_flags("-Wno-maybe-uninitialized" CMAKE_CXX_FLAGS)
+ endif()
+ rcc_append_flags("-Wno-nonnull" CMAKE_CXX_FLAGS)
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.1)
+ rcc_append_flags("-Wno-class-memaccess" CMAKE_CXX_FLAGS)
+ endif()
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.1)
+ rcc_append_flags("-Wno-dangling-reference" CMAKE_CXX_FLAGS)
+ endif()
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9.1)
+ rcc_append_flags("-Wno-redundant-move -Wno-pessimizing-move" CMAKE_CXX_FLAGS)
+ endif()
+ rcc_append_flags("-Wno-array-bounds" CMAKE_CXX_FLAGS)
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11.1)
+ rcc_append_flags("-Wno-stringop-overread" CMAKE_CXX_FLAGS)
+ endif()
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12.1)
+ rcc_append_flags("-Wno-dangling-pointer" CMAKE_CXX_FLAGS)
+ endif()
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14.0)
+ rcc_append_flags("-Wno-unused-but-set-parameter" CMAKE_CXX_FLAGS)
+ endif()
+ endif()
+ rcc_append_flags("-Wno-noexcept-type" CMAKE_CXX_FLAGS)
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ rcc_append_flags("-Wnon-virtual-dtor" CMAKE_CXX_FLAGS)
+ endif()
+ rcc_append_flags("-Wdelete-non-virtual-dtor" CMAKE_CXX_FLAGS)
+
+ check_cxx_compiler_flag("-Wsuggest-override" RCC_SUPPORTS_SUGGEST_OVERRIDE)
+ if(RCC_SUPPORTS_SUGGEST_OVERRIDE)
+ cmake_push_check_state()
+ string(APPEND CMAKE_REQUIRED_FLAGS " -Werror=suggest-override")
+ check_cxx_source_compiles([=[
+ class Base { public: virtual void anchor(); };
+ class Derived : Base { public: void anchor() final; };
+ int main() { return 0; }
+ ]=] RCC_SUGGEST_OVERRIDE_ACCEPTS_FINAL)
+ cmake_pop_check_state()
+ if(RCC_SUGGEST_OVERRIDE_ACCEPTS_FINAL)
+ rcc_append_flags("-Wsuggest-override" CMAKE_CXX_FLAGS)
+ endif()
+ endif()
+
+ cmake_push_check_state()
+ string(APPEND CMAKE_REQUIRED_FLAGS " -Werror -Wcomment")
+ check_c_source_compiles("// \\\\\\n//\\nint main(void) { return 0; }"
+ RCC_C_WCOMMENT_ACCEPTS_LINE_WRAP)
+ cmake_pop_check_state()
+ if(NOT RCC_C_WCOMMENT_ACCEPTS_LINE_WRAP)
+ rcc_append_flags("-Wno-comment" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ rcc_append_flags("-Wstring-conversion" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ rcc_append_flags("-Wno-pass-failed" CMAKE_CXX_FLAGS)
+ endif()
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ rcc_append_flags("-Wno-misleading-indentation" CMAKE_CXX_FLAGS)
+ else()
+ rcc_add_supported_warning("-Wmisleading-indentation" MISLEADING_INDENTATION)
+ endif()
+ rcc_add_supported_warning("-Wctad-maybe-unsupported" CTAD_MAYBE_UNSUPPORTED)
+ elseif(RCC_GCC_COMPATIBLE AND NOT RCC_ENABLE_WARNINGS)
+ rcc_append_flags("-w" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+
+ if(NOT RCC_ENABLE_WARNING_SUPPRESSIONS AND (RCC_GCC_COMPATIBLE OR RCC_CLANG_CL))
+ foreach(rccLanguage C CXX)
+ string(LENGTH "${rccInitial${rccLanguage}Flags}" rccInitialLength)
+ string(SUBSTRING "${CMAKE_${rccLanguage}_FLAGS}" ${rccInitialLength} -1 rccAddedFlags)
+ string(REGEX REPLACE "(^| +)-Wno-[a-zA-Z0-9_-]+" "" rccAddedFlags "${rccAddedFlags}")
+ set(CMAKE_${rccLanguage}_FLAGS "${rccInitial${rccLanguage}Flags}${rccAddedFlags}")
+ endforeach()
+ endif()
+endmacro()
+
+# Configure in the caller's directory scope, as LLVM's option modules do.
+macro(rcc_configure_options)
+ if(DEFINED CMAKE_CXX_STANDARD AND CMAKE_CXX_STANDARD LESS 23)
+ message(FATAL_ERROR "RCC requires CMAKE_CXX_STANDARD to be at least 23")
+ endif()
+ set(CMAKE_CXX_STANDARD 23 CACHE STRING "C++ standard to conform to")
+ set(CMAKE_CXX_STANDARD_REQUIRED YES)
+ set(CMAKE_CXX_EXTENSIONS NO)
+
+ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+ message(WARNING "No build type selected. Defaulted CMAKE_BUILD_TYPE=Release.")
+ set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type: Debug, Release, RelWithDebInfo, MinSizeRel" FORCE)
+ endif()
+ if(CMAKE_DEFAULT_BUILD_TYPE)
+ set(CMAKE_TRY_COMPILE_CONFIGURATION "${CMAKE_DEFAULT_BUILD_TYPE}")
+ elseif(CMAKE_CONFIGURATION_TYPES)
+ list(GET CMAKE_CONFIGURATION_TYPES 0 CMAKE_TRY_COMPILE_CONFIGURATION)
+ elseif(CMAKE_BUILD_TYPE)
+ set(CMAKE_TRY_COMPILE_CONFIGURATION "${CMAKE_BUILD_TYPE}")
+ endif()
+ set(RCC_ADDITIONAL_BUILD_TYPES "" CACHE STRING "Additional allowed CMake build types")
+ set(rccAllowedBuildTypes DEBUG RELEASE RELWITHDEBINFO MINSIZEREL ${RCC_ADDITIONAL_BUILD_TYPES})
+ string(REPLACE ";" "|" rccAllowedBuildTypes "${rccAllowedBuildTypes}")
+ string(TOUPPER "${rccAllowedBuildTypes}" rccAllowedBuildTypes)
+ set(assertionsDefault OFF)
+ string(TOUPPER "${CMAKE_BUILD_TYPE}" buildType)
+ if(CMAKE_BUILD_TYPE AND NOT buildType MATCHES "^(${rccAllowedBuildTypes})$")
+ message(FATAL_ERROR "Unknown value for CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
+ endif()
+ if(buildType STREQUAL "DEBUG")
+ set(assertionsDefault ON)
+ endif()
+ option(RCC_ENABLE_WARNINGS "Enable compiler warnings" ON)
+ option(RCC_ENABLE_WARNING_SUPPRESSIONS "Suppress compiler warnings" ON)
+ option(RCC_ENABLE_PEDANTIC "Compile with pedantic enabled" ON)
+ option(RCC_ENABLE_WERROR "Treat compiler warnings as errors" OFF)
+ option(RCC_ENABLE_ASSERTIONS "Enable assertions" "${assertionsDefault}")
+ option(RCC_ENABLE_EH "Enable C++ exceptions" OFF)
+ option(RCC_ENABLE_RTTI "Enable C++ runtime type information" OFF)
+ option(RCC_ENABLE_UNWIND_TABLES "Emit unwind tables for the libraries" ON)
+ set(RCC_USE_SANITIZER "" CACHE STRING
+ "Sanitizer used to build binaries; use LLVM's platform-specific combinations")
+ option(RCC_OPTIMIZE_SANITIZED_BUILDS "Use -O1 for Debug sanitizer builds" ON)
+ set(RCC_UBSAN_FLAGS
+ "-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all"
+ CACHE STRING "Compiler flags for the Undefined sanitizer")
+
+ if(RCC_ENABLE_EH AND NOT RCC_ENABLE_RTTI)
+ message(FATAL_ERROR "RCC_ENABLE_EH requires RCC_ENABLE_RTTI.")
+ endif()
+
+ if(NOT DEFINED RCC_GCC_COMPATIBLE)
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ set(RCC_GCC_COMPATIBLE ON)
+ elseif(MSVC)
+ set(RCC_GCC_COMPATIBLE OFF)
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang|Intel")
+ set(RCC_GCC_COMPATIBLE ON)
+ endif()
+ endif()
+ set(RCC_CLANG_CL OFF)
+ if(MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ set(RCC_CLANG_CL ON)
+ endif()
+
+ if(WIN32)
+ set(RCC_ON_UNIX OFF)
+ elseif(FUCHSIA OR UNIX OR CYGWIN)
+ set(RCC_ON_UNIX ON)
+ elseif(CMAKE_SYSTEM_NAME STREQUAL "Generic")
+ set(RCC_ON_UNIX OFF)
+ else()
+ message(SEND_ERROR "Unable to determine platform")
+ endif()
+
+ rcc_configure_additional_options()
+ rcc_configure_standard_library()
+ rcc_configure_platform_checks()
+ rcc_configure_job_pools()
+
+ if(RCC_ENABLE_ASSERTIONS)
+ if(NOT WIN32 OR MINGW)
+ add_compile_definitions(_DEBUG)
+ endif()
+ if(NOT buildType STREQUAL "DEBUG")
+ add_compile_options("$<$<COMPILE_LANGUAGE:C,CXX>:-UNDEBUG>")
+ if(MSVC)
+ foreach(rccFlagsVariable
+ CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_MINSIZEREL
+ CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_MINSIZEREL)
+ string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " "
+ ${rccFlagsVariable} "${${rccFlagsVariable}}")
+ endforeach()
+ endif()
+ endif()
+ add_compile_definitions(_GLIBCXX_ASSERTIONS)
+ check_cxx_source_compiles([=[
+ #define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_EXTENSIVE
+ #include <string>
+ int main() { return 0; }
+ ]=] RCC_SUPPORTS_LIBCXX_HARDENING_MODE)
+ if(RCC_SUPPORTS_LIBCXX_HARDENING_MODE)
+ add_compile_definitions(_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE)
+ endif()
+ endif()
+
+ rcc_configure_standard_library_abi()
+ rcc_configure_platform_link_options()
+ rcc_configure_linker()
+ rcc_configure_platform_options()
+ rcc_configure_warning_options()
+
+ if(RCC_USE_SANITIZER)
+ rcc_configure_sanitizer_options()
+ endif()
+ rcc_configure_debug_options()
+ rcc_configure_sections()
+ if(MSVC)
+ string(REGEX REPLACE "(^| ) */EH[-cs]+ *( |$)" "\\1 \\2"
+ CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ string(REGEX REPLACE "(^| ) */GR-? *( |$)" "\\1 \\2"
+ CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ endif()
+ rcc_configure_profile_options()
+ rcc_configure_pch_and_cache()
+ rcc_configure_lto()
+ rcc_configure_relative_paths()
+ rcc_configure_platform_definitions()
+endmacro()
+
+macro(rcc_configure_sanitizer_options)
+ set(ubsanFlags "${RCC_UBSAN_FLAGS}")
+ set(sanitizerFlags)
+ set(commonFlags ON)
+ if(RCC_ON_UNIX)
+ if(RCC_USE_SANITIZER STREQUAL "Address")
+ list(APPEND sanitizerFlags -fsanitize=address)
+ elseif(RCC_USE_SANITIZER STREQUAL "HWAddress")
+ list(APPEND sanitizerFlags -fsanitize=hwaddress)
+ elseif(RCC_USE_SANITIZER MATCHES "Memory(WithOrigins)?")
+ list(APPEND sanitizerFlags -fsanitize=memory)
+ if(RCC_USE_SANITIZER STREQUAL "MemoryWithOrigins")
+ list(APPEND sanitizerFlags -fsanitize-memory-track-origins)
+ endif()
+ elseif(RCC_USE_SANITIZER STREQUAL "Undefined")
+ list(APPEND sanitizerFlags ${ubsanFlags})
+ elseif(RCC_USE_SANITIZER STREQUAL "Thread")
+ list(APPEND sanitizerFlags -fsanitize=thread)
+ elseif(RCC_USE_SANITIZER STREQUAL "DataFlow")
+ list(APPEND sanitizerFlags -fsanitize=dataflow)
+ set(commonFlags OFF)
+ elseif(RCC_USE_SANITIZER STREQUAL "Address;Undefined" OR RCC_USE_SANITIZER STREQUAL "Undefined;Address")
+ list(APPEND sanitizerFlags -fsanitize=address ${ubsanFlags})
+ elseif(RCC_USE_SANITIZER STREQUAL "Leaks")
+ list(APPEND sanitizerFlags -fsanitize=leak)
+ else()
+ message(FATAL_ERROR "Unsupported RCC_USE_SANITIZER value: ${RCC_USE_SANITIZER}")
+ endif()
+ elseif(MINGW OR MSVC)
+ if(NOT RCC_USE_SANITIZER MATCHES "^(Address|Undefined|Address;Undefined|Undefined;Address)$")
+ message(FATAL_ERROR "Unsupported sanitizer in this Windows environment: ${RCC_USE_SANITIZER}")
+ endif()
+ if("Address" IN_LIST RCC_USE_SANITIZER)
+ if(MSVC AND NOT RCC_CLANG_CL)
+ list(APPEND sanitizerFlags /fsanitize=address)
+ else()
+ list(APPEND sanitizerFlags -fsanitize=address)
+ endif()
+ endif()
+ if("Undefined" IN_LIST RCC_USE_SANITIZER)
+ if(MSVC AND NOT RCC_CLANG_CL)
+ message(FATAL_ERROR "Undefined sanitizer requires clang-cl in the MSVC environment")
+ endif()
+ list(APPEND sanitizerFlags ${ubsanFlags})
+ endif()
+ else()
+ message(FATAL_ERROR "RCC_USE_SANITIZER is not supported on this platform")
+ endif()
+
+ if(commonFlags)
+ if(MSVC AND NOT RCC_CLANG_CL)
+ rcc_append_flags("/Z7" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ rcc_append_flags("/debug" CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ foreach(rccFlagsVariable CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ string(REGEX REPLACE "(^| )/INCREMENTAL($| )" " /INCREMENTAL:NO "
+ ${rccFlagsVariable} "${${rccFlagsVariable}}")
+ endforeach()
+ if(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "X86")
+ rcc_append_flags("/Oy-" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ else()
+ rcc_append_flags("-fno-omit-frame-pointer" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ if(NOT buildType STREQUAL "DEBUG" AND NOT buildType STREQUAL "RELWITHDEBINFO"
+ AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ rcc_append_flags("-gline-tables-only" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ if(buildType STREQUAL "DEBUG" AND RCC_OPTIMIZE_SANITIZED_BUILDS)
+ rcc_append_flags("-O1" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ endif()
+ endif()
+ string(JOIN " " rccSanitizerFlags ${sanitizerFlags})
+ rcc_append_flags("${rccSanitizerFlags}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+
+ if(MSVC)
+ if(NOT RCC_CLANG_CL AND "Address" IN_LIST RCC_USE_SANITIZER)
+ foreach(rccFlagsVariable CMAKE_CXX_FLAGS_${buildType} CMAKE_C_FLAGS_${buildType})
+ string(REGEX REPLACE "(^| )/RTC[1csu]*($| )" " "
+ ${rccFlagsVariable} "${${rccFlagsVariable}}")
+ endforeach()
+ endif()
+ if(RCC_LINKER_IS_LLD_LINK AND "Address" IN_LIST RCC_USE_SANITIZER)
+ if(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "X86")
+ set(runtimeArch i386)
+ else()
+ set(runtimeArch x86_64)
+ endif()
+ rcc_append_flags("/opt:nolldtailmerge clang_rt.asan_dynamic-${runtimeArch}.lib"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ if(CMAKE_MSVC_RUNTIME_LIBRARY MATCHES "^(MultiThreaded|MultiThreadedDebug)$")
+ set(rccRuntimeThunk "clang_rt.asan_static_runtime_thunk-${runtimeArch}.lib")
+ else()
+ set(rccRuntimeThunk "clang_rt.asan_dynamic_runtime_thunk-${runtimeArch}.lib")
+ endif()
+ rcc_append_flags("/wholearchive:${rccRuntimeThunk}"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+ endif()
+
+ if(RCC_USE_SANITIZE_COVERAGE)
+ rcc_append_flags("-fsanitize=fuzzer-no-link" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ if(RCC_USE_SANITIZER MATCHES ".*Undefined.*")
+ set(rccIgnorelist "${PROJECT_SOURCE_DIR}/utils/sanitizers/ubsan_ignorelist.txt")
+ if(EXISTS "${rccIgnorelist}")
+ rcc_append_flags("-fsanitize-ignorelist=\"${rccIgnorelist}\"" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ endif()
+endmacro()
+
+macro(rcc_configure_compiler_rt_path)
+ if(RCC_CLANG_CL AND (RCC_BUILD_INSTRUMENTED OR RCC_USE_SANITIZER))
+ execute_process(
+ COMMAND "${CMAKE_CXX_COMPILER}" /clang:-print-libgcc-file-name /clang:--rtlib=compiler-rt
+ OUTPUT_VARIABLE rccCompilerRTFile
+ ERROR_VARIABLE rccClangCLError
+ RESULT_VARIABLE rccClangCLResult
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_STRIP_TRAILING_WHITESPACE)
+ if(NOT rccClangCLResult STREQUAL "0")
+ message(FATAL_ERROR "Unable to invoke clang-cl to find resource dir: ${rccClangCLError}")
+ endif()
+ file(TO_CMAKE_PATH "${rccCompilerRTFile}" rccCompilerRTFile)
+ get_filename_component(rccRuntimeDir "${rccCompilerRTFile}" DIRECTORY)
+ foreach(rccFlagsVariable CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ set(${rccFlagsVariable}
+ "${CMAKE_CXX_LINKER_WRAPPER_FLAG}/libpath:\"${rccRuntimeDir}\" ${${rccFlagsVariable}}")
+ endforeach()
+ endif()
+endmacro()
+
+function(rcc_apply_options target)
+ set(enableEH ${RCC_ENABLE_EH})
+ set(enableRTTI ${RCC_ENABLE_RTTI})
+ if(RCC_REQUIRES_EH)
+ set(enableEH ON)
+ endif()
+ if(RCC_REQUIRES_RTTI)
+ set(enableRTTI ON)
+ endif()
+ if(enableEH AND NOT enableRTTI)
+ message(AUTHOR_WARNING "Exception handling requires RTTI; enabling RTTI for ${target}")
+ set(enableRTTI ON)
+ endif()
+ set(cxxFlags)
+ if(MSVC)
+ if(enableEH)
+ list(APPEND cxxFlags /EHsc)
+ else()
+ list(APPEND cxxFlags /EHs-c-)
+ target_compile_definitions(${target} PRIVATE _HAS_EXCEPTIONS=0)
+ endif()
+ if(enableRTTI)
+ list(APPEND cxxFlags /GR)
+ else()
+ list(APPEND cxxFlags /GR-)
+ endif()
+ elseif(RCC_GCC_COMPATIBLE)
+ if(NOT enableEH)
+ list(APPEND cxxFlags -fno-exceptions)
+ if(RCC_ENABLE_UNWIND_TABLES)
+ list(APPEND cxxFlags -funwind-tables)
+ else()
+ list(APPEND cxxFlags -fno-unwind-tables -fno-asynchronous-unwind-tables)
+ endif()
+ endif()
+ if(NOT enableRTTI)
+ list(APPEND cxxFlags -fno-rtti)
+ endif()
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES "XL")
+ if(NOT enableEH)
+ list(APPEND cxxFlags -qnoeh)
+ endif()
+ if(NOT enableRTTI)
+ list(APPEND cxxFlags -qnortti)
+ endif()
+ endif()
+ target_compile_options(${target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${cxxFlags}>")
+ rcc_apply_link_options(${target})
+endfunction()
+
+macro(rcc_configure_additional_options)
+ option(BUILD_SHARED_LIBS "Build libraries as shared libraries instead of static" OFF)
+ if(NOT CMAKE_SYSTEM_NAME MATCHES "OS390")
+ option(RCC_ENABLE_PIC "Build position-independent code" ON)
+ endif()
+ option(RCC_ENABLE_LIBCXX "Use libc++ if available" OFF)
+ option(RCC_STATIC_LINK_CXX_STDLIB "Statically link the C++ standard library" OFF)
+ option(RCC_ENABLE_LLD "Use lld as the linker" OFF)
+ set(RCC_USE_LINKER "" CACHE STRING "Linker to select through the compiler driver")
+ set(RCC_ENABLE_LTO OFF CACHE STRING "Enable LTO; use Thin or Full to select its mode")
+ string(TOUPPER "${RCC_ENABLE_LTO}" rccLTOMode)
+ option(RCC_ENABLE_FATLTO "Build with fat LTO objects" OFF)
+ set(RCC_THINLTO_CACHE_PATH "${PROJECT_BINARY_DIR}/lto.cache" CACHE STRING "ThinLTO cache directory")
+ option(RCC_NO_DEAD_STRIP "Disable removal of unused sections" OFF)
+ option(RCC_USE_SPLIT_DWARF "Use split DWARF in debug builds" OFF)
+ option(RCC_USE_SANITIZE_COVERAGE "Enable sanitizer coverage without the fuzzer main function" OFF)
+ set(RCC_BUILD_INSTRUMENTED OFF CACHE STRING "PGO instrumentation: IR, Frontend, CSIR, CSSPGO")
+ option(RCC_BUILD_INSTRUMENTED_COVERAGE "Build with code coverage instrumentation" OFF)
+ mark_as_advanced(RCC_BUILD_INSTRUMENTED RCC_BUILD_INSTRUMENTED_COVERAGE)
+ set(RCC_PROFDATA_FILE "" CACHE FILEPATH "Instrumentation profile to use when compiling")
+ set(RCC_SPROFDATA_FILE "" CACHE FILEPATH "Sampling profile to use when compiling")
+ set(RCC_CCACHE_BUILD OFF CACHE BOOL "Enable ccache for compilation")
+ set(RCC_SOURCE_PREFIX "" CACHE STRING "Source prefix in mapped paths")
+ option(RCC_USE_RELATIVE_PATHS_IN_DEBUG_INFO "Use relative paths in debug information" OFF)
+ option(RCC_USE_RELATIVE_PATHS_IN_FILES "Use relative paths in source and debug information" OFF)
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT (WIN32 OR CMAKE_SYSTEM_NAME MATCHES "AIX"))
+ option(RCC_BUILD_32_BITS "Build 32-bit binaries on a 64-bit platform" OFF)
+ endif()
+endmacro()
+
+macro(rcc_configure_standard_library)
+ set(RCC_LIBCXX_USED OFF)
+ if(RCC_ENABLE_LIBCXX)
+ if(RCC_GCC_COMPATIBLE)
+ check_cxx_compiler_flag("-stdlib=libc++" RCC_COMPILER_SUPPORTS_LIBCXX)
+ check_linker_flag(CXX "-stdlib=libc++" RCC_LINKER_SUPPORTS_LIBCXX)
+ if(RCC_COMPILER_SUPPORTS_LIBCXX AND RCC_LINKER_SUPPORTS_LIBCXX)
+ rcc_append_flags("-stdlib=libc++" CMAKE_CXX_FLAGS
+ CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS)
+ set(RCC_LIBCXX_USED ON)
+ else()
+ message(WARNING "Cannot select libc++ with -stdlib=")
+ endif()
+ else()
+ message(WARNING "No libc++ selection flag is known for this compiler")
+ endif()
+ endif()
+ if(RCC_STATIC_LINK_CXX_STDLIB)
+ if(RCC_GCC_COMPATIBLE)
+ check_cxx_compiler_flag("-static-libstdc++" RCC_COMPILER_SUPPORTS_STATIC_STDLIB)
+ check_linker_flag(CXX "-static-libstdc++" RCC_LINKER_SUPPORTS_STATIC_STDLIB)
+ if(RCC_COMPILER_SUPPORTS_STATIC_STDLIB AND RCC_LINKER_SUPPORTS_STATIC_STDLIB)
+ rcc_append_flags("-static-libstdc++"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS)
+ else()
+ message(WARNING "Cannot select static linking for the C++ standard library")
+ endif()
+ else()
+ message(WARNING "No static C++ standard library selection flag is known for this compiler")
+ endif()
+ endif()
+endmacro()
+
+macro(rcc_configure_standard_library_abi)
+ check_cxx_source_compiles([=[
+ #include <iosfwd>
+ #if !defined(__GLIBCXX__)
+ #error Not libstdc++
+ #endif
+ int main() { return 0; }
+ ]=] RCC_USES_LIBSTDCXX)
+ check_cxx_source_compiles([=[
+ #include <string>
+ #if _GLIBCXX_USE_CXX11_ABI == 0
+ #error C++11 ABI not active
+ #endif
+ int main() { return 0; }
+ ]=] RCC_DEFAULT_GLIBCXX_CXX11_ABI)
+ option(GLIBCXX_USE_CXX11_ABI "Use the libstdc++ C++11 ABI" ${RCC_DEFAULT_GLIBCXX_CXX11_ABI})
+ if(RCC_USES_LIBSTDCXX)
+ if(GLIBCXX_USE_CXX11_ABI)
+ add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=1)
+ else()
+ add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
+ endif()
+ endif()
+endmacro()
+
+macro(rcc_configure_linker)
+ if(RCC_ENABLE_LLD)
+ if(RCC_USE_LINKER)
+ message(FATAL_ERROR "RCC_ENABLE_LLD and RCC_USE_LINKER cannot be set together")
+ endif()
+ if(MSVC)
+ if(NOT CMAKE_LINKER MATCHES "lld-link")
+ get_filename_component(rccCXXCompilerDir "${CMAKE_CXX_COMPILER}" DIRECTORY)
+ get_filename_component(rccCCompilerDir "${CMAKE_C_COMPILER}" DIRECTORY)
+ find_program(RCC_LLD_LINK NAMES lld-link lld-link.exe
+ HINTS "${rccCXXCompilerDir}" "${rccCCompilerDir}")
+ if(NOT RCC_LLD_LINK)
+ message(FATAL_ERROR "RCC_ENABLE_LLD requires lld-link; set CMAKE_LINKER to its path")
+ endif()
+ set(CMAKE_LINKER "${RCC_LLD_LINK}")
+ endif()
+ else()
+ set(RCC_USE_LINKER lld)
+ endif()
+ endif()
+ if(RCC_USE_LINKER)
+ check_cxx_source_compiles("int main() { return 0; }" RCC_CAN_LINK_EXECUTABLE)
+ rcc_append_flags("-fuse-ld=${RCC_USE_LINKER}"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ if(RCC_CAN_LINK_EXECUTABLE)
+ check_cxx_source_compiles("int main() { return 0; }" RCC_SUPPORTS_CUSTOM_LINKER)
+ if(NOT RCC_SUPPORTS_CUSTOM_LINKER)
+ message(FATAL_ERROR "The compiler cannot link with -fuse-ld=${RCC_USE_LINKER}")
+ endif()
+ else()
+ message(STATUS "Skipping custom linker check: the target cannot link an executable")
+ endif()
+ endif()
+ set(RCC_LINKER_IS_LLD OFF)
+ set(RCC_LINKER_IS_LLD_LINK OFF)
+ if(CMAKE_LINKER MATCHES ".*lld" OR RCC_USE_LINKER STREQUAL "lld" OR RCC_ENABLE_LLD)
+ set(RCC_LINKER_IS_LLD ON)
+ endif()
+ if(CMAKE_LINKER MATCHES "lld-link" OR (MSVC AND (RCC_USE_LINKER STREQUAL "lld" OR RCC_ENABLE_LLD)))
+ set(RCC_LINKER_IS_LLD_LINK ON)
+ endif()
+ if(NOT WIN32)
+ if(APPLE)
+ set(rccLinkerVersionFlag "-Wl,-v")
+ else()
+ set(rccLinkerVersionFlag "-Wl,--version")
+ endif()
+ if(CMAKE_HOST_WIN32)
+ set(rccLinkerDevNull "NUL")
+ else()
+ set(rccLinkerDevNull "/dev/null")
+ endif()
+ if(RCC_USE_LINKER)
+ set(rccLinkerCommand ${CMAKE_C_COMPILER} -fuse-ld=${RCC_USE_LINKER} ${rccLinkerVersionFlag} -o ${rccLinkerDevNull})
+ else()
+ separate_arguments(rccLinkerFlags UNIX_COMMAND "${CMAKE_EXE_LINKER_FLAGS}")
+ set(rccLinkerCommand ${CMAKE_C_COMPILER} ${rccLinkerFlags} ${rccLinkerVersionFlag} -o ${rccLinkerDevNull})
+ endif()
+ execute_process(COMMAND ${rccLinkerCommand}
+ OUTPUT_VARIABLE rccLinkerOutput ERROR_VARIABLE rccLinkerError)
+ set(RCC_LINKER_IS_SOLARISLD OFF)
+ set(RCC_LINKER_IS_GNULD OFF)
+ if(rccLinkerOutput MATCHES "GNU ld")
+ set(RCC_LINKER_IS_GNULD ON)
+ endif()
+ if(rccLinkerOutput MATCHES "Solaris Link Editors" OR rccLinkerError MATCHES "Solaris Link Editors")
+ set(RCC_LINKER_IS_SOLARISLD ON)
+ endif()
+ endif()
+ if(APPLE)
+ if(NOT RCC_USE_LINKER)
+ check_linker_flag(C "-Wl,-no_warn_duplicate_libraries" RCC_LINKER_SUPPORTS_NO_WARN_DUPLICATE_LIBRARIES)
+ else()
+ set(RCC_LINKER_SUPPORTS_NO_WARN_DUPLICATE_LIBRARIES OFF CACHE INTERNAL "")
+ endif()
+ endif()
+endmacro()
+
+function(rcc_has_no_incremental flags output)
+ set(${output} OFF PARENT_SCOPE)
+ string(FIND "${flags}" "/INCREMENTAL" position REVERSE)
+ if(position GREATER -1)
+ string(SUBSTRING "${flags}" ${position} 15 option)
+ if(option MATCHES "/INCREMENTAL:NO")
+ set(${output} ON PARENT_SCOPE)
+ endif()
+ endif()
+endfunction()
+
+macro(rcc_configure_msvc_options)
+ add_compile_definitions(_CRT_SECURE_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS
+ _CRT_NONSTDC_NO_DEPRECATE _CRT_NONSTDC_NO_WARNINGS
+ _SCL_SECURE_NO_DEPRECATE _SCL_SECURE_NO_WARNINGS UNICODE _UNICODE)
+ rcc_append_flags("/Zc:inline /Oi /permissive-" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+ rcc_append_flags("/Zc:preprocessor" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ rcc_append_flags("/Zc:__cplusplus /bigobj" CMAKE_CXX_FLAGS)
+ set(RCC_WINSYSROOT "" CACHE STRING "Argument to clang-cl's /winsysroot")
+ if(RCC_WINSYSROOT)
+ if(NOT RCC_CLANG_CL)
+ message(FATAL_ERROR "RCC_WINSYSROOT requires clang-cl")
+ endif()
+ rcc_append_flags("/winsysroot\"${RCC_WINSYSROOT}\"" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ if(RCC_LINKER_IS_LLD_LINK)
+ rcc_append_flags("/winsysroot:\"${RCC_WINSYSROOT}\""
+ CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+ endif()
+ option(RCC_ENABLE_PDB "Generate PDB files in Release builds" OFF)
+ if(RCC_ENABLE_PDB AND buildType STREQUAL "RELEASE")
+ rcc_append_flags("/Zi" CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE)
+ rcc_append_flags("/DEBUG /OPT:REF /OPT:ICF"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+ set(rccAllLinkerFlags "")
+ foreach(rccKind EXE MODULE SHARED)
+ string(APPEND rccAllLinkerFlags
+ " ${CMAKE_${rccKind}_LINKER_FLAGS_${buildType}} ${CMAKE_${rccKind}_LINKER_FLAGS}")
+ endforeach()
+ string(TOUPPER "${rccAllLinkerFlags}" rccAllLinkerFlags)
+ if(RCC_CLANG_CL AND RCC_LINKER_IS_LLD AND rccAllLinkerFlags MATCHES "/DEBUG")
+ rcc_add_supported_warning("-gcodeview-ghash" GCODEVIEW_GHASH)
+ endif()
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT RCC_ENABLE_LTO)
+ foreach(rccKind EXE MODULE SHARED)
+ rcc_has_no_incremental(
+ "${CMAKE_${rccKind}_LINKER_FLAGS_${buildType}} ${CMAKE_${rccKind}_LINKER_FLAGS}"
+ rccNoIncremental${rccKind})
+ endforeach()
+ if(rccNoIncrementalEXE AND rccNoIncrementalMODULE AND rccNoIncrementalSHARED)
+ add_compile_options("$<$<COMPILE_LANGUAGE:C,CXX>:/Brepro>")
+ add_link_options("LINKER:/Brepro")
+ else()
+ message(WARNING "/Brepro is incompatible with incremental linking; output will not be deterministic")
+ endif()
+ endif()
+endmacro()
+
+macro(rcc_configure_platform_options)
+ if(RCC_ENABLE_PIC)
+ if(XCODE)
+ message(WARNING "-fPIC is not supported with Xcode")
+ elseif(NOT (WIN32 OR CYGWIN))
+ check_c_compiler_flag("-Werror -fPIC" RCC_C_SUPPORTS_FPIC)
+ check_cxx_compiler_flag("-Werror -fPIC" RCC_CXX_SUPPORTS_FPIC)
+ if(RCC_C_SUPPORTS_FPIC AND RCC_CXX_SUPPORTS_FPIC)
+ message(STATUS "Building with -fPIC")
+ rcc_append_flags("-fPIC" CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_ASM_FLAGS)
+ else()
+ message(WARNING "-fPIC is not supported")
+ endif()
+ if(NOT CMAKE_SYSTEM_NAME MATCHES "AIX" AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
+ rcc_add_supported_warning("-fno-semantic-interposition" FNO_SEMANTIC_INTERPOSITION)
+ endif()
+ endif()
+ endif()
+ if(NOT CMAKE_SYSTEM_NAME MATCHES "AIX" AND
+ (NOT (WIN32 OR CYGWIN) OR ((MINGW OR CYGWIN) AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")))
+ check_cxx_compiler_flag("-fvisibility-inlines-hidden" RCC_SUPPORTS_HIDDEN_INLINES)
+ if(RCC_SUPPORTS_HIDDEN_INLINES)
+ rcc_append_flags("-fvisibility-inlines-hidden" CMAKE_CXX_FLAGS)
+ endif()
+ endif()
+
+ if((CMAKE_SIZEOF_VOID_P EQUAL 8 AND MINGW) OR CMAKE_SIZEOF_VOID_P EQUAL 4)
+ add_compile_definitions(_FILE_OFFSET_BITS=64)
+ endif()
+ if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ add_compile_definitions(_LARGEFILE_SOURCE)
+ endif()
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 AND RCC_BUILD_32_BITS)
+ message(STATUS "Building 32 bits executables and libraries.")
+ rcc_append_flags("-m32" CMAKE_C_FLAGS CMAKE_CXX_FLAGS
+ CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS)
+ add_compile_definitions(_LARGEFILE_SOURCE _FILE_OFFSET_BITS=64)
+ endif()
+
+ if(MSVC OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
+ add_link_options("$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:LINKER:/STACK:10000000>")
+ elseif(MINGW OR CYGWIN)
+ add_link_options("$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:LINKER:--stack,16777216>")
+ if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ rcc_append_flags("-Wa,-mbig-obj" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ endif()
+ if(MSVC)
+ rcc_configure_msvc_options()
+ endif()
+ if(XCODE)
+ foreach(rccWarning
+ GCC_WARN_ABOUT_RETURN_TYPE GCC_WARN_ABOUT_MISSING_NEWLINE GCC_WARN_UNUSED_VALUE
+ GCC_WARN_UNUSED_VARIABLE GCC_WARN_SIGN_COMPARE GCC_WARN_UNUSED_FUNCTION
+ GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS
+ GCC_WARN_UNINITIALIZED_AUTOS CLANG_WARN_BOOL_CONVERSION CLANG_WARN_EMPTY_BODY
+ CLANG_WARN_ENUM_CONVERSION CLANG_WARN_INT_CONVERSION CLANG_WARN_CONSTANT_CONVERSION
+ GCC_WARN_NON_VIRTUAL_DESTRUCTOR)
+ set(CMAKE_XCODE_ATTRIBUTE_${rccWarning} YES)
+ endforeach()
+ endif()
+ if(MSVC_IDE)
+ set(RCC_COMPILER_JOBS "0" CACHE STRING "Parallel compiler jobs; 0 uses all processors")
+ if(RCC_COMPILER_JOBS STREQUAL "0")
+ add_compile_options(/MP)
+ elseif(NOT RCC_COMPILER_JOBS STREQUAL "1")
+ message(STATUS "Number of parallel compiler jobs set to ${RCC_COMPILER_JOBS}")
+ add_compile_options("/MP${RCC_COMPILER_JOBS}")
+ else()
+ message(STATUS "Parallel compilation disabled")
+ endif()
+ endif()
+
+endmacro()
+
+macro(rcc_configure_sections)
+ if(NOT CYGWIN AND NOT MSVC)
+ if(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin" AND NOT buildType STREQUAL "DEBUG")
+ if(CMAKE_CXX_COMPILER_ID MATCHES "XL")
+ rcc_append_flags("-qfuncsect" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ else()
+ rcc_append_flags("-ffunction-sections" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ rcc_append_flags("-fdata-sections" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ elseif(MSVC AND NOT buildType STREQUAL "DEBUG")
+ rcc_append_flags("/Gw" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+endmacro()
+
+macro(rcc_configure_debug_options)
+ if(RCC_USE_SPLIT_DWARF AND (buildType STREQUAL "DEBUG" OR buildType STREQUAL "RELWITHDEBINFO")
+ AND CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
+ add_compile_options("$<$<COMPILE_LANGUAGE:C,CXX>:-gsplit-dwarf>")
+ check_linker_flag(CXX "-Wl,--gdb-index" RCC_LINKER_SUPPORTS_GDB_INDEX)
+ if(RCC_LINKER_SUPPORTS_GDB_INDEX)
+ rcc_append_flags("-Wl,--gdb-index" CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+ endif()
+ if(RCC_ENABLE_PIC AND RCC_USING_GLIBC)
+ check_cxx_source_compiles([=[
+ #include <cstdio>
+ #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 36)
+ #error RELR requires glibc 2.36
+ #endif
+ int main() { return 0; }
+ ]=] RCC_GLIBC_SUPPORTS_RELR)
+ if(RCC_GLIBC_SUPPORTS_RELR)
+ check_linker_flag(CXX "-Wl,-z,pack-relative-relocs" RCC_LINKER_SUPPORTS_RELR)
+ if(RCC_LINKER_SUPPORTS_RELR)
+ rcc_append_flags("-Wl,-z,pack-relative-relocs"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+ endif()
+ endif()
+ add_compile_definitions(__STDC_CONSTANT_MACROS __STDC_FORMAT_MACROS __STDC_LIMIT_MACROS)
+ if(UNIX AND CMAKE_GENERATOR MATCHES "Ninja")
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
+ rcc_append_flags("-fdiagnostics-color" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ check_linker_flag(CXX "-Wl,--color-diagnostics" RCC_LINKER_SUPPORTS_COLOR_DIAGNOSTICS)
+ if(RCC_LINKER_SUPPORTS_COLOR_DIAGNOSTICS)
+ rcc_append_flags("-Wl,--color-diagnostics"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+ endif()
+endmacro()
+
+macro(rcc_configure_profile_options)
+ string(TOUPPER "${RCC_BUILD_INSTRUMENTED}" rccProfileMode)
+ if(RCC_BUILD_INSTRUMENTED OR RCC_BUILD_INSTRUMENTED_COVERAGE)
+ if(NOT RCC_PROFILE_MERGE_POOL_SIZE)
+ set(RCC_PROFILE_MERGE_POOL_SIZE 4)
+ endif()
+ if(NOT RCC_PROFILE_FILE_PATTERN)
+ if(NOT RCC_PROFILE_DATA_DIR)
+ file(TO_NATIVE_PATH "${PROJECT_BINARY_DIR}/profiles" RCC_PROFILE_DATA_DIR)
+ endif()
+ file(TO_NATIVE_PATH "${RCC_PROFILE_DATA_DIR}/%${RCC_PROFILE_MERGE_POOL_SIZE}m.profraw" RCC_PROFILE_FILE_PATTERN)
+ endif()
+ if(NOT RCC_CSPROFILE_FILE_PATTERN)
+ if(NOT RCC_CSPROFILE_DATA_DIR)
+ file(TO_NATIVE_PATH "${PROJECT_BINARY_DIR}/csprofiles" RCC_CSPROFILE_DATA_DIR)
+ endif()
+ file(TO_NATIVE_PATH "${RCC_CSPROFILE_DATA_DIR}/%${RCC_PROFILE_MERGE_POOL_SIZE}m.profraw" RCC_CSPROFILE_FILE_PATTERN)
+ endif()
+ endif()
+ if(RCC_BUILD_INSTRUMENTED AND RCC_BUILD_INSTRUMENTED_COVERAGE)
+ message(FATAL_ERROR "PGO instrumentation and coverage instrumentation cannot both be enabled")
+ endif()
+ if(RCC_BUILD_INSTRUMENTED)
+ if(rccProfileMode STREQUAL "IR")
+ set(rccProfileFlags "-fprofile-generate=\"${RCC_PROFILE_DATA_DIR}\"")
+ elseif(rccProfileMode STREQUAL "CSIR")
+ set(rccProfileFlags "-fcs-profile-generate=\"${RCC_CSPROFILE_DATA_DIR}\"")
+ elseif(rccProfileMode STREQUAL "CSSPGO")
+ if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ message(FATAL_ERROR "RCC_BUILD_INSTRUMENTED=CSSPGO requires Clang")
+ endif()
+ set(rccProfileFlags
+ "-fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fno-optimize-sibling-calls -fpseudo-probe-for-profiling -fdebug-info-for-profiling")
+ else()
+ set(rccProfileFlags "-fprofile-instr-generate=\"${RCC_PROFILE_FILE_PATTERN}\"")
+ endif()
+ rcc_append_flags("${rccProfileFlags}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ if(NOT RCC_LINKER_IS_LLD_LINK)
+ rcc_append_flags("${rccProfileFlags}" CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+ endif()
+ rcc_configure_compiler_rt_path()
+
+ if(RCC_PROFDATA_FILE AND EXISTS "${RCC_PROFDATA_FILE}")
+ if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ message(FATAL_ERROR "RCC_PROFDATA_FILE requires Clang")
+ endif()
+ rcc_append_flags("-fprofile-instr-use=\"${RCC_PROFDATA_FILE}\"" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ if(NOT RCC_LINKER_IS_LLD_LINK)
+ rcc_append_flags("-fprofile-instr-use=\"${RCC_PROFDATA_FILE}\""
+ CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+ elseif(RCC_PROFDATA_FILE)
+ message(WARNING "RCC_PROFDATA_FILE does not exist: ${RCC_PROFDATA_FILE}")
+ endif()
+ if(RCC_SPROFDATA_FILE AND EXISTS "${RCC_SPROFDATA_FILE}")
+ if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ message(FATAL_ERROR "RCC_SPROFDATA_FILE requires Clang")
+ endif()
+ set(rccSampleFlags "-fpseudo-probe-for-profiling -fprofile-sample-use=\"${RCC_SPROFDATA_FILE}\"")
+ rcc_append_flags("${rccSampleFlags}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ if(NOT RCC_LINKER_IS_LLD_LINK)
+ rcc_append_flags("${rccSampleFlags}" CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+ endif()
+ if(RCC_BUILD_INSTRUMENTED_COVERAGE)
+ rcc_append_flags("-fprofile-instr-generate=\"${RCC_PROFILE_FILE_PATTERN}\" -fcoverage-mapping"
+ CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+endmacro()
+
+macro(rcc_configure_lto)
+ if(RCC_ENABLE_LTO AND WIN32 AND NOT RCC_LINKER_IS_LLD_LINK AND NOT MINGW)
+ message(FATAL_ERROR "LTO on Windows requires lld-link; set CMAKE_LINKER to its path")
+ endif()
+ if(RCC_ENABLE_LTO)
+ if(rccLTOMode STREQUAL "THIN")
+ set(rccLTOFlag "-flto=thin")
+ elseif(rccLTOMode STREQUAL "FULL")
+ set(rccLTOFlag "-flto=full")
+ else()
+ set(rccLTOFlag "-flto")
+ endif()
+ rcc_append_flags("${rccLTOFlag}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ if(NOT RCC_LINKER_IS_LLD_LINK)
+ rcc_append_flags("${rccLTOFlag}" CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+ endif()
+ if(rccLTOMode STREQUAL "THIN")
+ if(APPLE)
+ rcc_append_flags("-Wl,-cache_path_lto,${RCC_THINLTO_CACHE_PATH}"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ elseif(CMAKE_SYSTEM_NAME MATCHES "AIX")
+ rcc_append_flags("-bplugin_opt:-legacy-thinlto-cache-dir=${RCC_THINLTO_CACHE_PATH}"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ elseif((UNIX OR MINGW) AND RCC_USE_LINKER STREQUAL "lld")
+ rcc_append_flags("-Wl,--thinlto-cache-dir=${RCC_THINLTO_CACHE_PATH}"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ elseif(RCC_USE_LINKER STREQUAL "gold")
+ rcc_append_flags("-Wl,--plugin-opt,cache-dir=${RCC_THINLTO_CACHE_PATH}"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ elseif(RCC_LINKER_IS_LLD_LINK)
+ rcc_append_flags("/lldltocache:${RCC_THINLTO_CACHE_PATH}"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
+ endif()
+ endif()
+ if(RCC_ENABLE_FATLTO AND ((UNIX AND NOT APPLE) OR FUCHSIA))
+ rcc_append_flags("-ffat-lto-objects" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ if(NOT RCC_LINKER_IS_LLD_LINK)
+ rcc_append_flags("-ffat-lto-objects"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS)
+ endif()
+ endif()
+endmacro()
+
+macro(rcc_configure_pch_and_cache)
+ if(NOT DEFINED CMAKE_DISABLE_PRECOMPILE_HEADERS)
+ if(CMAKE_SYSTEM_NAME MATCHES "OS390")
+ message(NOTICE "Precompiled headers are disabled by default on z/OS. "
+ "Pass -DCMAKE_DISABLE_PRECOMPILE_HEADERS=OFF to override.")
+ set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON)
+ endif()
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ message(NOTICE "Precompiled headers are disabled by default with GCC. "
+ "Pass -DCMAKE_DISABLE_PRECOMPILE_HEADERS=OFF to override.")
+ set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON)
+ endif()
+ if(CMAKE_CXX_COMPILER_LAUNCHER MATCHES "sccache")
+ message(NOTICE "Precompiled headers are disabled by default with sccache. "
+ "Pass -DCMAKE_DISABLE_PRECOMPILE_HEADERS=OFF to override.")
+ set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON)
+ elseif(CMAKE_CXX_COMPILER_LAUNCHER MATCHES "clang-cache")
+ message(NOTICE "Precompiled headers are disabled by default with clang-cache. "
+ "Pass -DCMAKE_DISABLE_PRECOMPILE_HEADERS=OFF to override.")
+ set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON)
+ elseif(RCC_CCACHE_BUILD OR CMAKE_CXX_COMPILER_LAUNCHER MATCHES "ccache")
+ if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ message(WARNING "Using ccache with precompiled headers with non-Clang "
+ "compilers is not supported and may lead to false positives. "
+ "Set CMAKE_DISABLE_PRECOMPILE_HEADERS to ON/OFF to silence this warning.")
+ set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON)
+ endif()
+ if(CMAKE_HOST_WIN32)
+ message(WARNING "Using ccache with precompiled headers on Windows is "
+ "currently not supported. "
+ "Pass -DCMAKE_DISABLE_PRECOMPILE_HEADERS=OFF to override.")
+ set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON)
+ endif()
+ endif()
+ endif()
+ if(NOT CMAKE_DISABLE_PRECOMPILE_HEADERS)
+ message(STATUS "Precompiled headers enabled.")
+ set(CMAKE_PCH_PROLOGUE "")
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ rcc_append_flags("-Xclang -fno-pch-timestamp" CMAKE_CXX_FLAGS)
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ rcc_append_flags("-fpch-preprocess" CMAKE_CXX_FLAGS)
+ endif()
+ else()
+ message(STATUS "Precompiled headers disabled.")
+ endif()
+ if(RCC_CCACHE_BUILD)
+ find_program(RCC_CCACHE_PROGRAM ccache)
+ if(NOT RCC_CCACHE_PROGRAM)
+ message(FATAL_ERROR "ccache was not found; install it or disable RCC_CCACHE_BUILD")
+ endif()
+ set(RCC_CCACHE_MAXSIZE "" CACHE STRING "ccache size limit")
+ set(RCC_CCACHE_DIR "" CACHE STRING "ccache storage directory")
+ set(RCC_CCACHE_PARAMS "CCACHE_CPP2=yes CCACHE_HASHDIR=yes CCACHE_SLOPPINESS=pch_defines,time_macros"
+ CACHE STRING "Environment assignments for ccache")
+ if(NOT CMAKE_HOST_WIN32)
+ set(rccCacheCommand "${RCC_CCACHE_PARAMS} \"${RCC_CCACHE_PROGRAM}\"")
+ if(NOT CMAKE_DISABLE_PRECOMPILE_HEADERS)
+ set(rccCacheCommand "CCACHE_DEPEND=1 ${rccCacheCommand}")
+ endif()
+ if(RCC_CCACHE_MAXSIZE)
+ set(rccCacheCommand "CCACHE_MAXSIZE=${RCC_CCACHE_MAXSIZE} ${rccCacheCommand}")
+ endif()
+ if(RCC_CCACHE_DIR)
+ set(rccCacheCommand "CCACHE_DIR=\"${RCC_CCACHE_DIR}\" ${rccCacheCommand}")
+ endif()
+ set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${rccCacheCommand}")
+ message(STATUS "ccache program: ${rccCacheCommand}")
+ else()
+ if(RCC_CCACHE_MAXSIZE OR RCC_CCACHE_DIR OR
+ NOT RCC_CCACHE_PARAMS MATCHES "CCACHE_CPP2=yes CCACHE_HASHDIR=yes CCACHE_SLOPPINESS=pch_defines,time_macros")
+ message(FATAL_ERROR "Configure ccache through environment variables on Windows")
+ endif()
+ set(CMAKE_C_COMPILER_LAUNCHER "${RCC_CCACHE_PROGRAM}")
+ set(CMAKE_CXX_COMPILER_LAUNCHER "${RCC_CCACHE_PROGRAM}")
+ message(STATUS "ccache program: ${RCC_CCACHE_PROGRAM}")
+ endif()
+ endif()
+endmacro()
+
+macro(rcc_configure_relative_paths)
+ if(RCC_USE_RELATIVE_PATHS_IN_DEBUG_INFO OR RCC_USE_RELATIVE_PATHS_IN_FILES)
+ if(RCC_ENABLE_PROJECTS)
+ get_filename_component(rccSourceRoot "${PROJECT_SOURCE_DIR}/.." ABSOLUTE)
+ else()
+ set(rccSourceRoot "${PROJECT_SOURCE_DIR}")
+ endif()
+ file(RELATIVE_PATH rccRelativeRoot "${CMAKE_BINARY_DIR}" "${rccSourceRoot}")
+ endif()
+ if(RCC_USE_RELATIVE_PATHS_IN_DEBUG_INFO)
+ check_c_compiler_flag("-fdebug-prefix-map=foo=bar" RCC_SUPPORTS_FDEBUG_PREFIX_MAP)
+ if(RCC_SUPPORTS_FDEBUG_PREFIX_MAP)
+ rcc_append_flags("-fdebug-prefix-map=\"${CMAKE_BINARY_DIR}=${rccRelativeRoot}\" -fdebug-prefix-map=\"${rccSourceRoot}/=${RCC_SOURCE_PREFIX}\""
+ CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ if(RCC_GCC_COMPATIBLE)
+ rcc_append_flags("-no-canonical-prefixes" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ endif()
+ if(RCC_USE_RELATIVE_PATHS_IN_FILES)
+ check_c_compiler_flag("-ffile-prefix-map=foo=bar" RCC_SUPPORTS_FFILE_PREFIX_MAP)
+ if(RCC_SUPPORTS_FFILE_PREFIX_MAP)
+ rcc_append_flags("-ffile-prefix-map=\"${CMAKE_BINARY_DIR}=${rccRelativeRoot}\" -ffile-prefix-map=\"${rccSourceRoot}/=${RCC_SOURCE_PREFIX}\""
+ CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ if(RCC_GCC_COMPATIBLE)
+ rcc_append_flags("-no-canonical-prefixes" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+ endif()
+endmacro()
+
+function(rcc_apply_link_options target)
+ if(NOT buildType STREQUAL "DEBUG")
+ if(NOT RCC_NO_DEAD_STRIP)
+ if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
+ target_link_options(${target} PRIVATE "LINKER:-dead_strip")
+ elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND RCC_LINKER_IS_SOLARISLD)
+ check_linker_flag(CXX "-Wl,-z,discard-unused=sections" RCC_LINKER_SUPPORTS_DISCARD_UNUSED)
+ if(RCC_LINKER_SUPPORTS_DISCARD_UNUSED)
+ target_link_options(${target} PRIVATE "LINKER:-z,discard-unused=sections")
+ endif()
+ elseif(NOT MSVC AND NOT CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC" AND NOT CMAKE_SYSTEM_NAME MATCHES "AIX|OS390")
+ target_link_options(${target} PRIVATE "LINKER:--gc-sections")
+ endif()
+ elseif(CMAKE_SYSTEM_NAME MATCHES "AIX")
+ target_link_options(${target} PRIVATE "LINKER:-bnogc")
+ endif()
+ endif()
+ if(RCC_LINKER_SUPPORTS_NO_WARN_DUPLICATE_LIBRARIES)
+ target_link_options(${target} PRIVATE "LINKER:-no_warn_duplicate_libraries")
+ endif()
+endfunction()
diff --git a/rcc/cmake/modules/HandleRCCStdlib.cmake b/rcc/cmake/modules/HandleRCCStdlib.cmake
new file mode 100644
index 0000000..5dcaf2e
--- /dev/null
+++ b/rcc/cmake/modules/HandleRCCStdlib.cmake
@@ -0,0 +1,54 @@
+# This CMake module is responsible for setting the standard library to libc++
+# if the user has requested it.
+
+include(DetermineGCCCompatible)
+
+if(NOT DEFINED RCC_STDLIB_HANDLED)
+ set(RCC_STDLIB_HANDLED ON)
+
+ function(append value)
+ foreach(variable ${ARGN})
+ set(${variable} "${${variable}} ${value}" PARENT_SCOPE)
+ endforeach(variable)
+ endfunction()
+
+ include(CheckCXXCompilerFlag)
+ include(CheckLinkerFlag)
+ set(RCC_LIBCXX_USED 0)
+ if(RCC_ENABLE_LIBCXX)
+ if(RCC_COMPILER_IS_GCC_COMPATIBLE)
+ check_cxx_compiler_flag("-stdlib=libc++" CXX_COMPILER_SUPPORTS_STDLIB)
+ check_linker_flag(CXX "-stdlib=libc++" CXX_LINKER_SUPPORTS_STDLIB)
+ if(CXX_COMPILER_SUPPORTS_STDLIB AND CXX_LINKER_SUPPORTS_STDLIB)
+ append("-stdlib=libc++"
+ CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS
+ CMAKE_MODULE_LINKER_FLAGS)
+ set(RCC_LIBCXX_USED 1)
+ else()
+ message(WARNING "Can't specify libc++ with '-stdlib='")
+ endif()
+ else()
+ message(WARNING "Not sure how to specify libc++ for this compiler")
+ endif()
+ endif()
+
+ if(RCC_STATIC_LINK_CXX_STDLIB)
+ if(RCC_COMPILER_IS_GCC_COMPATIBLE)
+ check_cxx_compiler_flag("-static-libstdc++"
+ CXX_COMPILER_SUPPORTS_STATIC_STDLIB)
+ check_linker_flag(CXX "-static-libstdc++" CXX_LINKER_SUPPORTS_STATIC_STDLIB)
+ if(CXX_COMPILER_SUPPORTS_STATIC_STDLIB AND
+ CXX_LINKER_SUPPORTS_STATIC_STDLIB)
+ append("-static-libstdc++"
+ CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS
+ CMAKE_MODULE_LINKER_FLAGS)
+ else()
+ message(WARNING
+ "Can't specify static linking for the C++ standard library")
+ endif()
+ else()
+ message(WARNING "Not sure how to specify static linking of C++ standard "
+ "library for this compiler")
+ endif()
+ endif()
+endif()
diff --git a/rcc/cmake/modules/RCCConfig.cmake.in b/rcc/cmake/modules/RCCConfig.cmake.in
new file mode 100644
index 0000000..3454a58
--- /dev/null
+++ b/rcc/cmake/modules/RCCConfig.cmake.in
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+@PACKAGE_INIT@
+
+set(RCC_VERSION "@RCC_VERSION@")
+set(RCC_VERSION_MAJOR "@RCC_VERSION_MAJOR@")
+set(RCC_VERSION_MINOR "@RCC_VERSION_MINOR@")
+set(RCC_VERSION_PATCH "@RCC_VERSION_PATCH@")
+set(RCC_CMAKE_DIR "@RCC_PACKAGE_MODULE_DIR@")
+set(RCC_INCLUDE_DIRS "@RCC_PACKAGE_INCLUDE_DIRS@")
+set(RCC_LIBRARY_DIR "@RCC_PACKAGE_LIBRARY_DIR@")
+set(RCC_BUILD_LIBRARY_DIR "@RCC_PACKAGE_BUILD_LIBRARY_DIR@")
+set(RCC_INSTALL_PREFIX "@RCC_PACKAGE_INSTALL_PREFIX@")
+set(RCC_ENABLE_ASSERTIONS "@RCC_ENABLE_ASSERTIONS@")
+set(RCC_ENABLE_EH "@RCC_ENABLE_EH@")
+set(RCC_ENABLE_RTTI "@RCC_ENABLE_RTTI@")
+set(RCC_ENABLE_UNWIND_TABLES "@RCC_ENABLE_UNWIND_TABLES@")
+set(RCC_ENABLE_WARNINGS "@RCC_ENABLE_WARNINGS@")
+set(RCC_ENABLE_WARNING_SUPPRESSIONS "@RCC_ENABLE_WARNING_SUPPRESSIONS@")
+set(RCC_ENABLE_LIBCXX "@RCC_LIBCXX_USED@")
+set(RCC_STATIC_LINK_CXX_STDLIB "@RCC_STATIC_LINK_CXX_STDLIB@")
+set(GLIBCXX_USE_CXX11_ABI "@GLIBCXX_USE_CXX11_ABI@")
+set(RCC_DEFINITIONS "@RCC_DEFINITIONS@")
+if(MSVC)
+ set(CMAKE_MSVC_RUNTIME_LIBRARY "@RCC_PACKAGE_MSVC_RUNTIME_LIBRARY@")
+endif()
+include("${CMAKE_CURRENT_LIST_DIR}/RCCTargets.cmake")
diff --git a/rcc/cmake/modules/RCCConfigVersion.cmake.in b/rcc/cmake/modules/RCCConfigVersion.cmake.in
new file mode 100644
index 0000000..f7d5ea4
--- /dev/null
+++ b/rcc/cmake/modules/RCCConfigVersion.cmake.in
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set(PACKAGE_VERSION "@PROJECT_VERSION@")
+
+# Match major and minor versions; accept the requested patch version or newer.
+if("@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@" VERSION_EQUAL
+ "${PACKAGE_FIND_VERSION_MAJOR}.${PACKAGE_FIND_VERSION_MINOR}"
+ AND NOT "@PROJECT_VERSION_PATCH@" VERSION_LESS "${PACKAGE_FIND_VERSION_PATCH}")
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ if("@PROJECT_VERSION_PATCH@" VERSION_EQUAL "${PACKAGE_FIND_VERSION_PATCH}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ endif()
+endif()