diff options
92 files changed, 4295 insertions, 379 deletions
diff --git a/Copyright.txt b/Copyright.txt index 19f3deb..b867d01 100644 --- a/Copyright.txt +++ b/Copyright.txt @@ -99,6 +99,7 @@ The following individuals and institutions are among the Contributors: * Sebastian Holtermann <sebholt@xwmw.org> * Stephen Kelly <steveire@gmail.com> * Sylvain Joubert <joubert.sy@gmail.com> +* The Qt Company Ltd. * Thomas Sondergaard <ts@medical-insight.com> * Tobias Hunger <tobias.hunger@qt.io> * Todd Gamblin <tgamblin@llnl.gov> diff --git a/Help/manual/ID_RESERVE.txt b/Help/manual/ID_RESERVE.txt new file mode 100644 index 0000000..be2b163 --- /dev/null +++ b/Help/manual/ID_RESERVE.txt @@ -0,0 +1,7 @@ +.. note:: + + CMake reserves identifiers that: + + * begin with ``CMAKE_`` (upper-, lower-, or mixed-case), or + * begin with ``_CMAKE_`` (upper-, lower-, or mixed-case), or + * begin with ``_`` followed by the name of any :manual:`CMake Command <cmake-commands(7)>`. diff --git a/Help/manual/cmake-language.7.rst b/Help/manual/cmake-language.7.rst index 4ca8e3a..b7f0861 100644 --- a/Help/manual/cmake-language.7.rst +++ b/Help/manual/cmake-language.7.rst @@ -567,6 +567,8 @@ The :manual:`cmake-variables(7)` manual documents the many variables that are provided by CMake or have meaning to CMake when set by project code. +.. include:: ID_RESERVE.txt + .. _`CMake Language Environment Variables`: Environment Variables diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 63deda5..1bcd9bd 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -14,6 +14,7 @@ For general information on variables, see the :ref:`Variables <CMake Language Variables>` section in the cmake-language manual. +.. include:: ID_RESERVE.txt Variables that Provide Information ================================== diff --git a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst index 69957bf..6eda26c 100644 --- a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst +++ b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst @@ -26,6 +26,9 @@ See :prop_tgt:`AUTOGEN_TARGET_DEPENDS` for reference. By default :prop_tgt:`AUTOMOC_DEPEND_FILTERS` is initialized from :variable:`CMAKE_AUTOMOC_DEPEND_FILTERS`, which is empty by default. +From Qt 5.15.0 on this variable is ignored as moc is able to output the correct +dependencies. + See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake index c02aa2c..69a8417 100644 --- a/Modules/CMakeAddFortranSubdirectory.cmake +++ b/Modules/CMakeAddFortranSubdirectory.cmake @@ -149,17 +149,9 @@ function(cmake_add_fortran_subdirectory subdir) -P ${build_dir}/config_mingw.cmake BUILD_COMMAND ${CMAKE_COMMAND} -P ${build_dir}/build_mingw.cmake + BUILD_ALWAYS 1 INSTALL_COMMAND "" ) - # make the external project always run make with each build - externalproject_add_step(${project_name}_build forcebuild - COMMAND ${CMAKE_COMMAND} - -E rm -f - ${CMAKE_CURRENT_BUILD_DIR}/${project_name}-prefix/src/${project_name}-stamp/${project_name}-build - DEPENDEES configure - DEPENDERS build - ALWAYS 1 - ) # create imported targets for all libraries foreach(lib ${libraries}) add_library(${lib} SHARED IMPORTED GLOBAL) diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index 23b5fa7..ed11364 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -41,6 +41,7 @@ The following variables may be set to influence this module's behavior: * ``Intel10_64lp_seq`` (intel mkl v10+ 64 bit, sequential code, lp64 model) * ``Intel10_64ilp`` (intel mkl v10+ 64 bit, threaded code, ilp64 model) * ``Intel10_64ilp_seq`` (intel mkl v10+ 64 bit, sequential code, ilp64 model) + * ``Intel10_64_dyn`` (intel mkl v10+ 64 bit, single dynamic library) * ``Intel`` (obsolete versions of mkl 32 and 64 bit) * ``ACML`` * ``ACML_MP`` @@ -76,7 +77,8 @@ This module defines the following variables: .. note:: - C or CXX must be enabled to use Intel Math Kernel Library (MKL) + C, CXX or Fortran must be enabled to detect a BLAS library. + C or CXX must be enabled to use Intel Math Kernel Library (MKL). For example, to use Intel MKL libraries and/or Intel compiler: @@ -88,8 +90,10 @@ This module defines the following variables: Hints ^^^^^ -Set ``MKLROOT`` environment variable to a directory that contains an MKL -installation. +Set the ``MKLROOT`` environment variable to a directory that contains an MKL +installation, or add the directory to the dynamic library loader environment +variable for your platform (``LIB``, ``DYLD_LIBRARY_PATH`` or +``LD_LIBRARY_PATH``). #]=======================================================================] @@ -113,8 +117,6 @@ include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) cmake_push_check_state() set(CMAKE_REQUIRED_QUIET ${BLAS_FIND_QUIETLY}) -set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - if(BLA_PREFER_PKGCONFIG) find_package(PkgConfig) pkg_check_modules(PKGC_BLAS blas) @@ -125,9 +127,23 @@ if(BLA_PREFER_PKGCONFIG) endif() endif() +set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) +if(BLA_STATIC) + if(WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() +else() + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + # for ubuntu's libblas3gf and liblapack3gf packages + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) + endif() +endif() + # TODO: move this stuff to a separate module -macro(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs) +macro(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _addlibdir _subdirs) # This macro checks for the existence of the combination of fortran libraries # given by _list. If the combination is found, this macro checks (using the # Check_Fortran_Function_Exists macro) whether can link against that library @@ -138,52 +154,42 @@ macro(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs) # N.B. _prefix is the prefix applied to the names of all cached variables that # are generated internally and marked advanced by this macro. - - set(_libdir ${ARGN}) + # _addlibdir is a list of additional search paths. _subdirs is a list of path + # suffixes to be used by find_library(). set(_libraries_work TRUE) set(${LIBRARIES}) set(_combined_name) - if(NOT _libdir) - if(WIN32) - set(_libdir ENV LIB) - elseif(APPLE) - set(_libdir ENV DYLD_LIBRARY_PATH) - else() - set(_libdir ENV LD_LIBRARY_PATH) - endif() - endif() - list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + if(WIN32) + list(APPEND _addlibdir ENV LIB) + elseif(APPLE) + list(APPEND _addlibdir ENV DYLD_LIBRARY_PATH) + else() + list(APPEND _addlibdir ENV LD_LIBRARY_PATH) + endif() + list(APPEND _addlibdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") foreach(_library ${_list}) - set(_combined_name ${_combined_name}_${_library}) - if(NOT "${_threadlibs}" STREQUAL "") - set(_combined_name ${_combined_name}_threadlibs) - endif() - if(_libraries_work) - if(BLA_STATIC) - if(WIN32) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) - endif() - if(APPLE) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) - else() - set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) - endif() - else() - if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - # for ubuntu's libblas3gf and liblapack3gf packages - set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) - endif() + if(_library MATCHES "^-Wl,--(start|end)-group$") + # Respect linker flags like --start/end-group (required by MKL) + set(${LIBRARIES} ${${LIBRARIES}} "${_library}") + else() + set(_combined_name ${_combined_name}_${_library}) + if(NOT "${_threadlibs}" STREQUAL "") + set(_combined_name ${_combined_name}_threadlibs) + endif() + if(_libraries_work) + find_library(${_prefix}_${_library}_LIBRARY + NAMES ${_library} + PATHS ${_addlibdir} + PATH_SUFFIXES ${_subdirs} + ) + #message("DEBUG: find_library(${_library}) got ${${_prefix}_${_library}_LIBRARY}") + mark_as_advanced(${_prefix}_${_library}_LIBRARY) + set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) + set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) endif() - find_library(${_prefix}_${_library}_LIBRARY - NAMES ${_library} - PATHS ${_libdir} - ) - mark_as_advanced(${_prefix}_${_library}_LIBRARY) - set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) - set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) endif() endforeach() @@ -233,6 +239,8 @@ if(BLA_VENDOR STREQUAL "All") "" "" "" + "" + "" ) endif() endif() @@ -249,6 +257,13 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") set(BLAS_mkl_DLL_SUFFIX "_dll") endif() else() + if(BLA_STATIC) + set(BLAS_mkl_START_GROUP "-Wl,--start-group") + set(BLAS_mkl_END_GROUP "-Wl,--end-group") + else() + set(BLAS_mkl_START_GROUP "") + set(BLAS_mkl_END_GROUP "") + endif() # Switch to GNU Fortran support layer if needed (but not on Apple, where MKL does not provide it) if(CMAKE_Fortran_COMPILER_LOADED AND CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND NOT APPLE) set(BLAS_mkl_INTFACE "gf") @@ -287,6 +302,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN "mkl_blas95${BLAS_mkl_DLL_SUFFIX} mkl_intel_c${BLAS_mkl_DLL_SUFFIX}") endif() + if(BLA_VENDOR MATCHES "^Intel10_64i?lp" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN "mkl_blas95_${BLAS_mkl_ILP_MODE}${BLAS_mkl_DLL_SUFFIX} mkl_intel_${BLAS_mkl_ILP_MODE}${BLAS_mkl_DLL_SUFFIX}") @@ -294,11 +310,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # Add threading/sequential libs set(BLAS_SEARCH_LIBS_WIN_THREAD "") - if(BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All") - list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD - "mkl_sequential${BLAS_mkl_DLL_SUFFIX}") - endif() - if(NOT BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All") + if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All") # old version list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}") @@ -306,6 +318,10 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}") endif() + if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD + "mkl_sequential${BLAS_mkl_DLL_SUFFIX}") + endif() # Cartesian product of the above foreach(MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN}) @@ -322,7 +338,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # mkl >= 10.3 list(APPEND BLAS_SEARCH_LIBS - "mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}") + "${BLAS_mkl_START_GROUP} mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}") endif() if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All") # old version @@ -331,11 +347,11 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # mkl >= 10.3 list(APPEND BLAS_SEARCH_LIBS - "mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}") + "${BLAS_mkl_START_GROUP} mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}") endif() if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS - "mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core") + "${BLAS_mkl_START_GROUP} mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core ${BLAS_mkl_END_GROUP}") endif() endif() else() @@ -355,7 +371,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # Add threading/sequential libs set(BLAS_SEARCH_LIBS_WIN_THREAD "") - if(NOT BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All") + if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All") # old version list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}") @@ -363,7 +379,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}") endif() - if(BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All") + if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD "mkl_sequential${BLAS_mkl_DLL_SUFFIX}") endif() @@ -383,7 +399,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # mkl >= 10.3 list(APPEND BLAS_SEARCH_LIBS - "mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}") + "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}") endif() if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All") # old version @@ -392,11 +408,11 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # mkl >= 10.3 list(APPEND BLAS_SEARCH_LIBS - "mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}") + "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}") endif() if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS - "mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core") + "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core ${BLAS_mkl_END_GROUP}") endif() #older vesions of intel mkl libs @@ -411,22 +427,32 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") endif() endif() - if(DEFINED ENV{MKLROOT}) - if(BLA_VENDOR STREQUAL "Intel10_32") - set(_BLAS_MKLROOT_LIB_DIR "$ENV{MKLROOT}/lib/ia32") - elseif(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$") - set(_BLAS_MKLROOT_LIB_DIR "$ENV{MKLROOT}/lib/intel64") - endif() + if(BLA_VENDOR MATCHES "^Intel10_64_dyn$" OR BLA_VENDOR STREQUAL "All") + # mkl >= 10.3 with single dynamic library + list(APPEND BLAS_SEARCH_LIBS + "mkl_rt") endif() - if(_BLAS_MKLROOT_LIB_DIR) - if(WIN32) - string(APPEND _BLAS_MKLROOT_LIB_DIR "_win") - elseif(APPLE) - string(APPEND _BLAS_MKLROOT_LIB_DIR "_mac") - else() - string(APPEND _BLAS_MKLROOT_LIB_DIR "_lin") - endif() + + # MKL uses a multitude of partially platform-specific subdirectories: + if(BLA_VENDOR STREQUAL "Intel10_32") + set(BLAS_mkl_ARCH_NAME "ia32") + else() + set(BLAS_mkl_ARCH_NAME "intel64") + endif() + if(WIN32) + set(BLAS_mkl_OS_NAME "win") + elseif(APPLE) + set(BLAS_mkl_OS_NAME "mac") + else() + set(BLAS_mkl_OS_NAME "lin") + endif() + if(DEFINED ENV{MKLROOT}) + set(BLAS_mkl_MKLROOT "$ENV{MKLROOT}") endif() + set(BLAS_mkl_LIB_PATH_SUFFIXES + "compiler/lib" "compiler/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}" + "mkl/lib" "mkl/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}" + "lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}") foreach(IT ${BLAS_SEARCH_LIBS}) string(REPLACE " " ";" SEARCH_LIBS ${IT}) @@ -438,7 +464,8 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") "" "${SEARCH_LIBS}" "${CMAKE_THREAD_LIBS_INIT};${BLAS_mkl_LM};${BLAS_mkl_LDL}" - "${_BLAS_MKLROOT_LIB_DIR}" + "${BLAS_mkl_MKLROOT}" + "${BLAS_mkl_LIB_PATH_SUFFIXES}" ) endif() endforeach() @@ -450,6 +477,10 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") unset(BLAS_mkl_DLL_SUFFIX) unset(BLAS_mkl_LM) unset(BLAS_mkl_LDL) + unset(BLAS_mkl_MKLROOT) + unset(BLAS_mkl_ARCH_NAME) + unset(BLAS_mkl_OS_NAME) + unset(BLAS_mkl_LIB_PATH_SUFFIXES) endif() endif() endif() @@ -472,6 +503,8 @@ if(BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") "" "goto2" "" + "" + "" ) endif() endif() @@ -486,6 +519,8 @@ if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All") "" "openblas" "" + "" + "" ) endif() if(NOT BLAS_LIBRARIES AND (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED)) @@ -501,6 +536,8 @@ if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All") "" "openblas" "${CMAKE_THREAD_LIBS_INIT}" + "" + "" ) endif() endif() @@ -515,6 +552,8 @@ if(BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All") "" "blis" "" + "" + "" ) endif() endif() @@ -529,6 +568,8 @@ if(BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All") "" "blas;f77blas;atlas" "" + "" + "" ) endif() endif() @@ -543,6 +584,8 @@ if(BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All") "" "sgemm;dgemm;blas" "" + "" + "" ) endif() endif() @@ -557,6 +600,8 @@ if(BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All") "" "cxml" "" + "" + "" ) endif() endif() @@ -571,6 +616,8 @@ if(BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All") "" "dxml" "" + "" + "" ) endif() endif() @@ -585,6 +632,8 @@ if(BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All") "-xlic_lib=sunperf" "sunperf;sunmath" "" + "" + "" ) if(BLAS_LIBRARIES) set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf") @@ -602,6 +651,8 @@ if(BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All") "" "scsl" "" + "" + "" ) endif() endif() @@ -616,6 +667,8 @@ if(BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All") "" "complib.sgimath" "" + "" + "" ) endif() endif() @@ -630,6 +683,8 @@ if(BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All") "" "essl;blas" "" + "" + "" ) endif() endif() @@ -706,7 +761,7 @@ if(BLA_VENDOR STREQUAL "ACML_MP") BLAS_LIBRARIES BLAS sgemm - "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS} + "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS} "" ) if(BLAS_LIBRARIES) break() @@ -718,7 +773,7 @@ elseif(BLA_VENDOR STREQUAL "ACML_GPU") BLAS_LIBRARIES BLAS sgemm - "" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS} + "" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS} "" ) if(BLAS_LIBRARIES) break() @@ -730,7 +785,7 @@ else() BLAS_LIBRARIES BLAS sgemm - "" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS} + "" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS} "" ) if(BLAS_LIBRARIES) break() @@ -747,6 +802,8 @@ if(NOT BLAS_LIBRARIES) "" "acml;acml_mv" "" + "" + "" ) endif() if(NOT BLAS_LIBRARIES) @@ -757,6 +814,8 @@ if(NOT BLAS_LIBRARIES) "" "acml_mp;acml_mv" "" + "" + "" ) endif() if(NOT BLAS_LIBRARIES) @@ -767,6 +826,8 @@ if(NOT BLAS_LIBRARIES) "" "acml;acml_mv;CALBLAS" "" + "" + "" ) endif() endif() # ACML @@ -781,6 +842,8 @@ if(BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") "" "Accelerate" "" + "" + "" ) endif() endif() @@ -795,6 +858,8 @@ if(BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") "" "vecLib" "" + "" + "" ) endif() endif() @@ -809,6 +874,8 @@ if(BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All") "" "blas" "" + "" + "" ) endif() endif() diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index deac9ef..3c52466 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -1470,43 +1470,6 @@ _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_ADDITIONAL_VERSIONS") _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_NO_SYSTEM_PATHS") -# Supply Boost_LIB_DIAGNOSTIC_DEFINITIONS as a convenience target. It -# will only contain any interface definitions on WIN32, but is created -# on all platforms to keep end user code free from platform dependent -# code. Also provide convenience targets to disable autolinking and -# enable dynamic linking. -if(NOT TARGET Boost::diagnostic_definitions) - add_library(Boost::diagnostic_definitions INTERFACE IMPORTED) - add_library(Boost::disable_autolinking INTERFACE IMPORTED) - add_library(Boost::dynamic_linking INTERFACE IMPORTED) - set_target_properties(Boost::dynamic_linking PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_DYN_LINK") -endif() -if(WIN32) - # In windows, automatic linking is performed, so you do not have - # to specify the libraries. If you are linking to a dynamic - # runtime, then you can choose to link to either a static or a - # dynamic Boost library, the default is to do a static link. You - # can alter this for a specific library "whatever" by defining - # BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be - # linked dynamically. Alternatively you can force all Boost - # libraries to dynamic link by defining BOOST_ALL_DYN_LINK. - - # This feature can be disabled for Boost library "whatever" by - # defining BOOST_WHATEVER_NO_LIB, or for all of Boost by defining - # BOOST_ALL_NO_LIB. - - # If you want to observe which libraries are being linked against - # then defining BOOST_LIB_DIAGNOSTIC will cause the auto-linking - # code to emit a #pragma message each time a library is selected - # for linking. - set(Boost_LIB_DIAGNOSTIC_DEFINITIONS "-DBOOST_LIB_DIAGNOSTIC") - set_target_properties(Boost::diagnostic_definitions PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "BOOST_LIB_DIAGNOSTIC") - set_target_properties(Boost::disable_autolinking PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_NO_LIB") -endif() - cmake_policy(GET CMP0074 _Boost_CMP0074) if(NOT "x${_Boost_CMP0074}x" STREQUAL "xNEWx") _Boost_CHECK_SPELLING(Boost_ROOT) @@ -2299,6 +2262,43 @@ if(Boost_FOUND) endif() endif() endforeach() + + # Supply Boost_LIB_DIAGNOSTIC_DEFINITIONS as a convenience target. It + # will only contain any interface definitions on WIN32, but is created + # on all platforms to keep end user code free from platform dependent + # code. Also provide convenience targets to disable autolinking and + # enable dynamic linking. + if(NOT TARGET Boost::diagnostic_definitions) + add_library(Boost::diagnostic_definitions INTERFACE IMPORTED) + add_library(Boost::disable_autolinking INTERFACE IMPORTED) + add_library(Boost::dynamic_linking INTERFACE IMPORTED) + set_target_properties(Boost::dynamic_linking PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_DYN_LINK") + endif() + if(WIN32) + # In windows, automatic linking is performed, so you do not have + # to specify the libraries. If you are linking to a dynamic + # runtime, then you can choose to link to either a static or a + # dynamic Boost library, the default is to do a static link. You + # can alter this for a specific library "whatever" by defining + # BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be + # linked dynamically. Alternatively you can force all Boost + # libraries to dynamic link by defining BOOST_ALL_DYN_LINK. + + # This feature can be disabled for Boost library "whatever" by + # defining BOOST_WHATEVER_NO_LIB, or for all of Boost by defining + # BOOST_ALL_NO_LIB. + + # If you want to observe which libraries are being linked against + # then defining BOOST_LIB_DIAGNOSTIC will cause the auto-linking + # code to emit a #pragma message each time a library is selected + # for linking. + set(Boost_LIB_DIAGNOSTIC_DEFINITIONS "-DBOOST_LIB_DIAGNOSTIC") + set_target_properties(Boost::diagnostic_definitions PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "BOOST_LIB_DIAGNOSTIC") + set_target_properties(Boost::disable_autolinking PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_NO_LIB") + endif() endif() # ------------------------------------------------------------------------ diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index a6523ef..62749ed 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake @@ -732,12 +732,9 @@ endif() if(CUDAToolkit_FOUND) function(_CUDAToolkit_find_and_add_import_lib lib_name) + cmake_parse_arguments(arg "" "" "ALT;DEPS" ${ARGN}) - if(ARGC GREATER 1) - set(search_names ${ARGN}) - else() - set(search_names ${lib_name}) - endif() + set(search_names ${lib_name} ${arg_ALT}) find_library(CUDA_${lib_name}_LIBRARY NAMES ${search_names} @@ -746,62 +743,81 @@ if(CUDAToolkit_FOUND) PATH_SUFFIXES nvidia/current lib64 lib64/stubs lib/x64 lib lib/stubs ) - if (NOT CUDA::${lib_name} AND CUDA_${lib_name}_LIBRARY) + if (NOT TARGET CUDA::${lib_name} AND CUDA_${lib_name}_LIBRARY) add_library(CUDA::${lib_name} IMPORTED INTERFACE) target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}") target_link_libraries(CUDA::${lib_name} INTERFACE "${CUDA_${lib_name}_LIBRARY}") - endif() - endfunction() - - function(_CUDAToolkit_add_link_dependency lib_name) - if(TARGET CUDA::${lib_name}) - foreach(dependency IN LISTS ARGN) - if(TARGET CUDA::${dependency}) - target_link_libraries(CUDA::${lib_name} INTERFACE CUDA::${dependency}) + foreach(dep ${arg_DEPS}) + if(TARGET CUDA::${dep}) + target_link_libraries(CUDA::${lib_name} INTERFACE CUDA::${dep}) endif() endforeach() endif() endfunction() - add_library(CUDA::toolkit IMPORTED INTERFACE) - target_include_directories(CUDA::toolkit SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}") - target_link_directories(CUDA::toolkit INTERFACE "${CUDAToolkit_LIBRARY_DIR}") - + if(NOT TARGET CUDA::toolkit) + add_library(CUDA::toolkit IMPORTED INTERFACE) + target_include_directories(CUDA::toolkit SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}") + target_link_directories(CUDA::toolkit INTERFACE "${CUDAToolkit_LIBRARY_DIR}") + endif() - _CUDAToolkit_find_and_add_import_lib(cuda_driver cuda) + _CUDAToolkit_find_and_add_import_lib(cuda_driver ALT cuda) _CUDAToolkit_find_and_add_import_lib(cudart) _CUDAToolkit_find_and_add_import_lib(cudart_static) - foreach (cuda_lib cublas cufft cufftw curand cusolver cusparse nvgraph nvjpeg) - _CUDAToolkit_find_and_add_import_lib(${cuda_lib}) + # setup dependencies that are required for cudart_static when building + # on linux. These are generally only required when using the CUDA toolkit + # when CUDA language is disabled + if(NOT TARGET CUDA::cudart_static_deps + AND TARGET CUDA::cudart_static) + + add_library(CUDA::cudart_static_deps IMPORTED INTERFACE) + target_link_libraries(CUDA::cudart_static INTERFACE CUDA::cudart_static_deps) + + if(UNIX AND (CMAKE_C_COMPILER OR CMAKE_CXX_COMPILER)) + find_package(Threads REQUIRED) + target_link_libraries(CUDA::cudart_static_deps INTERFACE Threads::Threads ${CMAKE_DL_LIBS}) + endif() - _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static) + if(UNIX AND NOT APPLE) + # On Linux, you must link against librt when using the static cuda runtime. + find_library(CUDAToolkit_rt_LIBRARY rt) + if(NOT CUDAToolkit_rt_LIBRARY) + message(WARNING "Could not find librt library, needed by CUDA::cudart_static") + else() + target_link_libraries(CUDA::cudart_static_deps INTERFACE ${CUDAToolkit_rt_LIBRARY}) + endif() + endif() + endif() + + _CUDAToolkit_find_and_add_import_lib(culibos) # it's a static library + foreach (cuda_lib cublas cufft curand cusparse nppc nvjpeg) + _CUDAToolkit_find_and_add_import_lib(${cuda_lib}) + _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS culibos) endforeach() + # cuFFTW depends on cuFFT + _CUDAToolkit_find_and_add_import_lib(cufftw DEPS cufft) + _CUDAToolkit_find_and_add_import_lib(cufftw DEPS cufft_static) + # cuSOLVER depends on cuBLAS, and cuSPARSE - _CUDAToolkit_add_link_dependency(cusolver cublas cusparse) - _CUDAToolkit_add_link_dependency(cusolver_static cublas_static cusparse) + _CUDAToolkit_find_and_add_import_lib(cusolver DEPS cublas cusparse) + _CUDAToolkit_find_and_add_import_lib(cusolver_static DEPS cublas_static cusparse_static culibos) # nvGRAPH depends on cuRAND, and cuSOLVER. - _CUDAToolkit_add_link_dependency(nvgraph curand cusolver) - _CUDAToolkit_add_link_dependency(nvgraph_static curand_static cusolver_static) - - _CUDAToolkit_find_and_add_import_lib(nppc) - _CUDAToolkit_find_and_add_import_lib(nppc_static) + _CUDAToolkit_find_and_add_import_lib(nvgraph DEPS curand cusolver) + _CUDAToolkit_find_and_add_import_lib(nvgraph_static DEPS curand_static cusolver_static) # Process the majority of the NPP libraries. foreach (cuda_lib nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppicom nppisu) - _CUDAToolkit_find_and_add_import_lib(${cuda_lib}) - _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static) - _CUDAToolkit_add_link_dependency(${cuda_lib} nppc) - _CUDAToolkit_add_link_dependency(${cuda_lib}_static nppc_static) + _CUDAToolkit_find_and_add_import_lib(${cuda_lib} DEPS nppc) + _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS nppc_static) endforeach() - _CUDAToolkit_find_and_add_import_lib(nvrtc) - _CUDAToolkit_add_link_dependency(nvrtc cuda_driver) + _CUDAToolkit_find_and_add_import_lib(nvrtc DEPS cuda_driver) - _CUDAToolkit_find_and_add_import_lib(nvml nvidia-ml nvml) + _CUDAToolkit_find_and_add_import_lib(nvml ALT nvidia-ml nvml) if(WIN32) # nvtools can be installed outside the CUDA toolkit directory @@ -814,17 +830,9 @@ if(CUDAToolkit_FOUND) PATH_SUFFIXES lib/x64 lib ) endif() - _CUDAToolkit_find_and_add_import_lib(nvToolsExt nvToolsExt nvToolsExt64) + _CUDAToolkit_find_and_add_import_lib(nvToolsExt ALT nvToolsExt64) _CUDAToolkit_find_and_add_import_lib(OpenCL) - - _CUDAToolkit_find_and_add_import_lib(culibos) - if(TARGET CUDA::culibos) - foreach (cuda_lib cublas cufft cusparse curand nppc nvjpeg) - _CUDAToolkit_add_link_dependency(${cuda_lib}_static culibos) - endforeach() - endif() - endif() if(_CUDAToolkit_Pop_ROOT_PATH) diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake index 3aa3de4..8ade0b1 100644 --- a/Modules/FindLAPACK.cmake +++ b/Modules/FindLAPACK.cmake @@ -33,6 +33,7 @@ The following variables may be set to influence this module's behavior: * ``Intel10_64lp_seq`` (intel mkl v10+ 64 bit, sequential code, lp64 model) * ``Intel10_64ilp`` (intel mkl v10+ 64 bit, threaded code, ilp64 model) * ``Intel10_64ilp_seq`` (intel mkl v10+ 64 bit, sequential code, ilp64 model) + * ``Intel10_64_dyn`` (intel mkl v10+ 64 bit, single dynamic library) * ``Intel`` (obsolete versions of mkl 32 and 64 bit) * ``ACML`` * ``Apple`` @@ -62,7 +63,8 @@ This module defines the following variables: .. note:: - C or CXX must be enabled to use Intel Math Kernel Library (MKL) + C, CXX or Fortran must be enabled to detect a BLAS/LAPACK library. + C or CXX must be enabled to use Intel Math Kernel Library (MKL). For example, to use Intel MKL libraries and/or Intel compiler: @@ -92,14 +94,26 @@ include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake) cmake_push_check_state() set(CMAKE_REQUIRED_QUIET ${LAPACK_FIND_QUIETLY}) -set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - set(LAPACK_FOUND FALSE) set(LAPACK95_FOUND FALSE) +set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) +if(BLA_STATIC) + if(WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() +else() + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + # for ubuntu's libblas3gf and liblapack3gf packages + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) + endif() +endif() + # TODO: move this stuff to a separate module -macro(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _blas) +macro(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _addlibdir _subdirs _blas) # This macro checks for the existence of the combination of fortran libraries # given by _list. If the combination is found, this macro checks (using the # Check_Fortran_Function_Exists macro) whether can link against that library @@ -110,58 +124,45 @@ macro(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _b # N.B. _prefix is the prefix applied to the names of all cached variables that # are generated internally and marked advanced by this macro. + # _addlibdir is a list of additional search paths. _subdirs is a list of path + # suffixes to be used by find_library(). set(_libraries_work TRUE) set(${LIBRARIES}) set(_combined_name) - if(NOT _libdir) - if(WIN32) - set(_libdir ENV LIB) - elseif(APPLE) - set(_libdir ENV DYLD_LIBRARY_PATH) - else() - set(_libdir ENV LD_LIBRARY_PATH) - endif() - endif() - list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + if(WIN32) + list(APPEND _addlibdir ENV LIB) + elseif(APPLE) + list(APPEND _addlibdir ENV DYLD_LIBRARY_PATH) + else() + list(APPEND _addlibdir ENV LD_LIBRARY_PATH) + endif() + list(APPEND _addlibdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") foreach(_library ${_list}) - set(_combined_name ${_combined_name}_${_library}) - - if(_libraries_work) - if(BLA_STATIC) - if(WIN32) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) - endif() - if(APPLE) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) - else() - set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) - endif() - else() - if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - # for ubuntu's libblas3gf and liblapack3gf packages - set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) - endif() + if(_library MATCHES "^-Wl,--(start|end)-group$") + # Respect linker flags like --start/end-group (required by MKL) + set(${LIBRARIES} ${${LIBRARIES}} "${_library}") + else() + set(_combined_name ${_combined_name}_${_library}) + if(_libraries_work) + find_library(${_prefix}_${_library}_LIBRARY + NAMES ${_library} + PATHS ${_addlibdir} + PATH_SUFFIXES ${_subdirs} + ) + #message("DEBUG: find_library(${_library}) got ${${_prefix}_${_library}_LIBRARY}") + mark_as_advanced(${_prefix}_${_library}_LIBRARY) + set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) + set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) endif() - find_library(${_prefix}_${_library}_LIBRARY - NAMES ${_library} - PATHS ${_libdir} - ) - mark_as_advanced(${_prefix}_${_library}_LIBRARY) - set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) - set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) endif() endforeach() if(_libraries_work) # Test this combination of libraries. - if(UNIX AND BLA_STATIC) - set(CMAKE_REQUIRED_LIBRARIES ${_flags} "-Wl,--start-group" ${${LIBRARIES}} ${_blas} "-Wl,--end-group" ${_threadlibs}) - else() - set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threadlibs}) - endif() + set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threadlibs}) #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") if(CMAKE_Fortran_COMPILER_LOADED) check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS) @@ -246,11 +247,32 @@ if(BLAS_FOUND) set(_LIBRARIES LAPACK_LIBRARIES) set(_BLAS_LIBRARIES ${BLAS_LIBRARIES}) - # old + # old and new >= 10.3 list(APPEND LAPACK_SEARCH_LIBS "mkl_lapack") endif() + # MKL uses a multitude of partially platform-specific subdirectories: + if(BLA_VENDOR STREQUAL "Intel10_32") + set(LAPACK_mkl_ARCH_NAME "ia32") + else() + set(LAPACK_mkl_ARCH_NAME "intel64") + endif() + if(WIN32) + set(LAPACK_mkl_OS_NAME "win") + elseif(APPLE) + set(LAPACK_mkl_OS_NAME "mac") + else() + set(LAPACK_mkl_OS_NAME "lin") + endif() + if(DEFINED ENV{MKLROOT}) + set(LAPACK_mkl_MKLROOT "$ENV{MKLROOT}") + endif() + set(LAPACK_mkl_LIB_PATH_SUFFIXES + "compiler/lib" "compiler/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}" + "mkl/lib" "mkl/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}" + "lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}") + # First try empty lapack libs if(NOT ${_LIBRARIES}) check_lapack_libraries( @@ -259,20 +281,26 @@ if(BLAS_FOUND) ${LAPACK_mkl_SEARCH_SYMBOL} "" "" - "" + "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}" + "${LAPACK_mkl_MKLROOT}" + "${LAPACK_mkl_LIB_PATH_SUFFIXES}" "${_BLAS_LIBRARIES}" ) endif() + # Then try the search libs foreach(IT ${LAPACK_SEARCH_LIBS}) + string(REPLACE " " ";" SEARCH_LIBS ${IT}) if(NOT ${_LIBRARIES}) check_lapack_libraries( ${_LIBRARIES} LAPACK ${LAPACK_mkl_SEARCH_SYMBOL} "" - "${IT}" + "${SEARCH_LIBS}" "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}" + "${LAPACK_mkl_MKLROOT}" + "${LAPACK_mkl_LIB_PATH_SUFFIXES}" "${_BLAS_LIBRARIES}" ) endif() @@ -282,6 +310,10 @@ if(BLAS_FOUND) unset(LAPACK_mkl_SEARCH_SYMBOL) unset(LAPACK_mkl_LM) unset(LAPACK_mkl_LDL) + unset(LAPACK_mkl_MKLROOT) + unset(LAPACK_mkl_ARCH_NAME) + unset(LAPACK_mkl_OS_NAME) + unset(LAPACK_mkl_LIB_PATH_SUFFIXES) endif() endif() endif() @@ -296,6 +328,8 @@ if(BLAS_FOUND) "" "goto2" "" + "" + "" "${BLAS_LIBRARIES}" ) endif() @@ -311,6 +345,8 @@ if(BLAS_FOUND) "" "openblas" "" + "" + "" "${BLAS_LIBRARIES}" ) endif() @@ -326,6 +362,8 @@ if(BLAS_FOUND) "" "flame" "" + "" + "" "${BLAS_LIBRARIES}" ) endif() @@ -348,6 +386,8 @@ if(BLAS_FOUND) "" "Accelerate" "" + "" + "" "${BLAS_LIBRARIES}" ) endif() @@ -363,6 +403,8 @@ if(BLAS_FOUND) "" "vecLib" "" + "" + "" "${BLAS_LIBRARIES}" ) endif() @@ -380,6 +422,8 @@ if(BLAS_FOUND) "" "lapack" "" + "" + "" "${BLAS_LIBRARIES}" ) endif() diff --git a/Modules/GNUInstallDirs.cmake b/Modules/GNUInstallDirs.cmake index f95e6e2..9ef22b9 100644 --- a/Modules/GNUInstallDirs.cmake +++ b/Modules/GNUInstallDirs.cmake @@ -221,6 +221,11 @@ if(NOT DEFINED CMAKE_INSTALL_LIBDIR OR (_libdir_set # default one. When CMAKE_INSTALL_PREFIX changes, the value is # updated to the new default, unless the user explicitly changed it. endif() + if (NOT DEFINED CMAKE_SYSTEM_NAME OR NOT DEFINED CMAKE_SIZEOF_VOID_P) + message(AUTHOR_WARNING + "Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. " + "Please enable at least one language before including GNUInstallDirs.") + endif() if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$" AND NOT CMAKE_CROSSCOMPILING AND NOT EXISTS "/etc/arch-release") @@ -235,16 +240,10 @@ if(NOT DEFINED CMAKE_INSTALL_LIBDIR OR (_libdir_set endif() endif() else() # not debian, rely on CMAKE_SIZEOF_VOID_P: - if(NOT DEFINED CMAKE_SIZEOF_VOID_P) - message(AUTHOR_WARNING - "Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. " - "Please enable at least one language before including GNUInstallDirs.") - else() - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - set(_LIBDIR_DEFAULT "lib64") - if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX) - set(__LAST_LIBDIR_DEFAULT "lib64") - endif() + if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") + set(_LIBDIR_DEFAULT "lib64") + if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX) + set(__LAST_LIBDIR_DEFAULT "lib64") endif() endif() endif() diff --git a/Modules/Platform/AIX-XL.cmake b/Modules/Platform/AIX-XL.cmake index 64b0bc1..2a67c4f 100644 --- a/Modules/Platform/AIX-XL.cmake +++ b/Modules/Platform/AIX-XL.cmake @@ -18,14 +18,24 @@ macro(__aix_compiler_xl lang) set(CMAKE_${lang}_LINK_FLAGS "-Wl,-bnoipath") + set(_OBJECTS " <OBJECTS>") + if(DEFINED CMAKE_XL_CreateExportList AND CMAKE_XL_CreateExportList STREQUAL "") + # Prior to CMake 3.16, CMAKE_XL_CreateExportList held the path to the XL CreateExportList tool. + # Users could set it to an empty value to skip automatic exports in favor of manual -bE: flags. + # Preserve that behavior for compatibility (even though it was undocumented). + set(_OBJECTS "") + endif() + # Construct the export list ourselves to pass only the object files so # that we export only the symbols actually provided by the sources. set(CMAKE_${lang}_CREATE_SHARED_LIBRARY - "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/objects.exp <OBJECTS>" + "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/objects.exp${_OBJECTS}" "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/objects.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" ) set(CMAKE_${lang}_LINK_EXECUTABLE_WITH_EXPORTS "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -l . <OBJECTS>" "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> -Wl,-bE:<TARGET_IMPLIB> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") + + unset(_OBJECTS) endmacro() diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index ff313d6..c57f713 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -134,6 +134,9 @@ set(SRCS LexerParser/cmFortranParser.cxx LexerParser/cmFortranParserTokens.h LexerParser/cmFortranParser.y + LexerParser/cmGccDepfileLexer.cxx + LexerParser/cmGccDepfileLexer.h + LexerParser/cmGccDepfileLexer.in.l LexerParser/cmListFileLexer.c LexerParser/cmListFileLexer.in.l @@ -270,6 +273,10 @@ set(SRCS cmFortranParserImpl.cxx cmFSPermissions.cxx cmFSPermissions.h + cmGccDepfileLexerHelper.cxx + cmGccDepfileLexerHelper.h + cmGccDepfileReader.cxx + cmGccDepfileReader.h cmGeneratedFileStream.cxx cmGeneratorExpressionContext.cxx cmGeneratorExpressionContext.h diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 74d779f..6478de0 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 16) -set(CMake_VERSION_PATCH 20200128) +set(CMake_VERSION_PATCH 20200203) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/LexerParser/.gitattributes b/Source/LexerParser/.gitattributes index bf70249..63d9afb 100644 --- a/Source/LexerParser/.gitattributes +++ b/Source/LexerParser/.gitattributes @@ -16,4 +16,6 @@ /cmFortranLexer.h generated /cmFortranParser.cxx generated /cmFortranParserTokens.h generated +/cmGccDepfileLexer.cxx generated +/cmGccDepfileLexer.h generated /cmListFileLexer.c generated diff --git a/Source/LexerParser/cmGccDepfileLexer.cxx b/Source/LexerParser/cmGccDepfileLexer.cxx new file mode 100644 index 0000000..a98969d --- /dev/null +++ b/Source/LexerParser/cmGccDepfileLexer.cxx @@ -0,0 +1,2210 @@ +#include "cmStandardLexer.h" + +#define FLEXINT_H 1 +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +#ifdef yy_create_buffer +#define cmGccDepfile_yy_create_buffer_ALREADY_DEFINED +#else +#define yy_create_buffer cmGccDepfile_yy_create_buffer +#endif + +#ifdef yy_delete_buffer +#define cmGccDepfile_yy_delete_buffer_ALREADY_DEFINED +#else +#define yy_delete_buffer cmGccDepfile_yy_delete_buffer +#endif + +#ifdef yy_scan_buffer +#define cmGccDepfile_yy_scan_buffer_ALREADY_DEFINED +#else +#define yy_scan_buffer cmGccDepfile_yy_scan_buffer +#endif + +#ifdef yy_scan_string +#define cmGccDepfile_yy_scan_string_ALREADY_DEFINED +#else +#define yy_scan_string cmGccDepfile_yy_scan_string +#endif + +#ifdef yy_scan_bytes +#define cmGccDepfile_yy_scan_bytes_ALREADY_DEFINED +#else +#define yy_scan_bytes cmGccDepfile_yy_scan_bytes +#endif + +#ifdef yy_init_buffer +#define cmGccDepfile_yy_init_buffer_ALREADY_DEFINED +#else +#define yy_init_buffer cmGccDepfile_yy_init_buffer +#endif + +#ifdef yy_flush_buffer +#define cmGccDepfile_yy_flush_buffer_ALREADY_DEFINED +#else +#define yy_flush_buffer cmGccDepfile_yy_flush_buffer +#endif + +#ifdef yy_load_buffer_state +#define cmGccDepfile_yy_load_buffer_state_ALREADY_DEFINED +#else +#define yy_load_buffer_state cmGccDepfile_yy_load_buffer_state +#endif + +#ifdef yy_switch_to_buffer +#define cmGccDepfile_yy_switch_to_buffer_ALREADY_DEFINED +#else +#define yy_switch_to_buffer cmGccDepfile_yy_switch_to_buffer +#endif + +#ifdef yypush_buffer_state +#define cmGccDepfile_yypush_buffer_state_ALREADY_DEFINED +#else +#define yypush_buffer_state cmGccDepfile_yypush_buffer_state +#endif + +#ifdef yypop_buffer_state +#define cmGccDepfile_yypop_buffer_state_ALREADY_DEFINED +#else +#define yypop_buffer_state cmGccDepfile_yypop_buffer_state +#endif + +#ifdef yyensure_buffer_stack +#define cmGccDepfile_yyensure_buffer_stack_ALREADY_DEFINED +#else +#define yyensure_buffer_stack cmGccDepfile_yyensure_buffer_stack +#endif + +#ifdef yylex +#define cmGccDepfile_yylex_ALREADY_DEFINED +#else +#define yylex cmGccDepfile_yylex +#endif + +#ifdef yyrestart +#define cmGccDepfile_yyrestart_ALREADY_DEFINED +#else +#define yyrestart cmGccDepfile_yyrestart +#endif + +#ifdef yylex_init +#define cmGccDepfile_yylex_init_ALREADY_DEFINED +#else +#define yylex_init cmGccDepfile_yylex_init +#endif + +#ifdef yylex_init_extra +#define cmGccDepfile_yylex_init_extra_ALREADY_DEFINED +#else +#define yylex_init_extra cmGccDepfile_yylex_init_extra +#endif + +#ifdef yylex_destroy +#define cmGccDepfile_yylex_destroy_ALREADY_DEFINED +#else +#define yylex_destroy cmGccDepfile_yylex_destroy +#endif + +#ifdef yyget_debug +#define cmGccDepfile_yyget_debug_ALREADY_DEFINED +#else +#define yyget_debug cmGccDepfile_yyget_debug +#endif + +#ifdef yyset_debug +#define cmGccDepfile_yyset_debug_ALREADY_DEFINED +#else +#define yyset_debug cmGccDepfile_yyset_debug +#endif + +#ifdef yyget_extra +#define cmGccDepfile_yyget_extra_ALREADY_DEFINED +#else +#define yyget_extra cmGccDepfile_yyget_extra +#endif + +#ifdef yyset_extra +#define cmGccDepfile_yyset_extra_ALREADY_DEFINED +#else +#define yyset_extra cmGccDepfile_yyset_extra +#endif + +#ifdef yyget_in +#define cmGccDepfile_yyget_in_ALREADY_DEFINED +#else +#define yyget_in cmGccDepfile_yyget_in +#endif + +#ifdef yyset_in +#define cmGccDepfile_yyset_in_ALREADY_DEFINED +#else +#define yyset_in cmGccDepfile_yyset_in +#endif + +#ifdef yyget_out +#define cmGccDepfile_yyget_out_ALREADY_DEFINED +#else +#define yyget_out cmGccDepfile_yyget_out +#endif + +#ifdef yyset_out +#define cmGccDepfile_yyset_out_ALREADY_DEFINED +#else +#define yyset_out cmGccDepfile_yyset_out +#endif + +#ifdef yyget_leng +#define cmGccDepfile_yyget_leng_ALREADY_DEFINED +#else +#define yyget_leng cmGccDepfile_yyget_leng +#endif + +#ifdef yyget_text +#define cmGccDepfile_yyget_text_ALREADY_DEFINED +#else +#define yyget_text cmGccDepfile_yyget_text +#endif + +#ifdef yyget_lineno +#define cmGccDepfile_yyget_lineno_ALREADY_DEFINED +#else +#define yyget_lineno cmGccDepfile_yyget_lineno +#endif + +#ifdef yyset_lineno +#define cmGccDepfile_yyset_lineno_ALREADY_DEFINED +#else +#define yyset_lineno cmGccDepfile_yyset_lineno +#endif + +#ifdef yyget_column +#define cmGccDepfile_yyget_column_ALREADY_DEFINED +#else +#define yyget_column cmGccDepfile_yyget_column +#endif + +#ifdef yyset_column +#define cmGccDepfile_yyset_column_ALREADY_DEFINED +#else +#define yyset_column cmGccDepfile_yyset_column +#endif + +#ifdef yywrap +#define cmGccDepfile_yywrap_ALREADY_DEFINED +#else +#define yywrap cmGccDepfile_yywrap +#endif + +#ifdef yyalloc +#define cmGccDepfile_yyalloc_ALREADY_DEFINED +#else +#define yyalloc cmGccDepfile_yyalloc +#endif + +#ifdef yyrealloc +#define cmGccDepfile_yyrealloc_ALREADY_DEFINED +#else +#define yyrealloc cmGccDepfile_yyrealloc +#endif + +#ifdef yyfree +#define cmGccDepfile_yyfree_ALREADY_DEFINED +#else +#define yyfree cmGccDepfile_yyfree +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yyg->yy_start = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yyg->yy_start - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin , yyscanner ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = yyg->yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ + ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] + +void yyrestart ( FILE *input_file , yyscan_t yyscanner ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); +void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); +void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); +void yypop_buffer_state ( yyscan_t yyscanner ); + +static void yyensure_buffer_stack ( yyscan_t yyscanner ); +static void yy_load_buffer_state ( yyscan_t yyscanner ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); + +void *yyalloc ( yy_size_t , yyscan_t yyscanner ); +void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); +void yyfree ( void * , yyscan_t yyscanner ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define cmGccDepfile_yywrap(yyscanner) (/*CONSTCOND*/1) +#define YY_SKIP_YYWRAP +typedef flex_uint8_t YY_CHAR; + +typedef int yy_state_type; + +#define yytext_ptr yytext_r + +static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); +static int yy_get_next_buffer ( yyscan_t yyscanner ); +static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yyg->yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yyg->yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yyg->yy_c_buf_p = yy_cp; +#define YY_NUM_RULES 11 +#define YY_END_OF_BUFFER 12 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[26] = + { 0, + 0, 0, 12, 10, 8, 6, 10, 9, 10, 10, + 10, 8, 0, 6, 9, 1, 7, 5, 0, 3, + 2, 0, 4, 0, 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 5, 6, 1, 7, 8, 6, 1, 1, 6, + 6, 1, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 9, 1, 1, + 6, 1, 1, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 10, 6, 1, 6, 1, 6, 6, 6, 6, + + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 1, 6, 6, 1, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6 + } ; + +static const YY_CHAR yy_meta[11] = + { 0, + 1, 2, 1, 1, 2, 1, 1, 1, 1, 3 + } ; + +static const flex_int16_t yy_base[28] = + { 0, + 0, 0, 29, 35, 18, 35, 22, 18, 15, 0, + 8, 12, 16, 35, 11, 35, 0, 35, 13, 35, + 35, 16, 35, 22, 35, 31, 12 + } ; + +static const flex_int16_t yy_def[28] = + { 0, + 25, 1, 25, 25, 26, 25, 25, 25, 25, 27, + 25, 26, 25, 25, 25, 25, 27, 25, 25, 25, + 25, 25, 25, 25, 0, 25, 25 + } ; + +static const flex_int16_t yy_nxt[46] = + { 0, + 4, 5, 6, 7, 5, 8, 4, 9, 10, 11, + 18, 19, 20, 17, 21, 18, 15, 22, 18, 19, + 23, 13, 16, 15, 14, 24, 20, 13, 25, 25, + 25, 22, 12, 12, 3, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25 + } ; + +static const flex_int16_t yy_chk[46] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 11, 11, 11, 27, 11, 19, 15, 11, 13, 13, + 22, 12, 9, 8, 7, 22, 24, 5, 3, 0, + 0, 24, 26, 26, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25 + } ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +/* IWYU pragma: no_forward_declare yyguts_t */ + +#ifndef __clang_analyzer__ /* Suppress clang scan-build warnings */ + +#include <cmGccDepfileLexerHelper.h> +#include <string> + +#define INITIAL 0 + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Holds the entire state of the reentrant scanner. */ +struct yyguts_t + { + + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE yyextra_r; + + /* The rest are the same as the globals declared in the non-reentrant scanner. */ + FILE *yyin_r, *yyout_r; + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ + char yy_hold_char; + int yy_n_chars; + int yyleng_r; + char *yy_c_buf_p; + int yy_init; + int yy_start; + int yy_did_buffer_switch_on_eof; + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + int yylineno_r; + int yy_flex_debug_r; + + char *yytext_r; + int yy_more_flag; + int yy_more_len; + + }; /* end struct yyguts_t */ + +static int yy_init_globals ( yyscan_t yyscanner ); + +int yylex_init (yyscan_t* scanner); + +int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( yyscan_t yyscanner ); + +int yyget_debug ( yyscan_t yyscanner ); + +void yyset_debug ( int debug_flag , yyscan_t yyscanner ); + +YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); + +FILE *yyget_in ( yyscan_t yyscanner ); + +void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); + +FILE *yyget_out ( yyscan_t yyscanner ); + +void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); + + int yyget_leng ( yyscan_t yyscanner ); + +char *yyget_text ( yyscan_t yyscanner ); + +int yyget_lineno ( yyscan_t yyscanner ); + +void yyset_lineno ( int _line_number , yyscan_t yyscanner ); + +int yyget_column ( yyscan_t yyscanner ); + +void yyset_column ( int _column_no , yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( yyscan_t yyscanner ); +#else +extern int yywrap ( yyscan_t yyscanner ); +#endif +#endif + +#ifndef YY_NO_UNPUT + + static void yyunput ( int c, char *buf_ptr , yyscan_t yyscanner); + +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * , yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput ( yyscan_t yyscanner ); +#else +static int input ( yyscan_t yyscanner ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (yyscan_t yyscanner); + +#define YY_DECL int yylex (yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( !yyg->yy_init ) + { + yyg->yy_init = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yyg->yy_start ) + yyg->yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); + } + + yy_load_buffer_state( yyscanner ); + } + + { + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yy_cp = yyg->yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yyg->yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yyg->yy_start; +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 26 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 35 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yyg->yy_hold_char; + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +{ + // Unescape the dollar sign. + yyextra->addToCurrentPath("$"); + } + YY_BREAK +case 2: +YY_RULE_SETUP +{ + // Unescape the hash. + yyextra->addToCurrentPath("#"); + } + YY_BREAK +case 3: +YY_RULE_SETUP +{ + // 2N+1 backslashes plus space -> N backslashes plus space. + size_t c = (strlen(yytext) - 1) / 2; + std::string s(c, '\\'); + s.push_back(' '); + yyextra->addToCurrentPath(s.c_str()); + } + YY_BREAK +case 4: +YY_RULE_SETUP +{ + // 2N backslashes plus space -> 2N backslashes, end of filename. + yytext[strlen(yytext) - 1] = 0; + yyextra->addToCurrentPath(yytext); + yyextra->newDependency(); + } + YY_BREAK +case 5: +/* rule 5 can match eol */ +YY_RULE_SETUP +{ + // A line continuation ends the current file name. + yyextra->newDependency(); + } + YY_BREAK +case 6: +/* rule 6 can match eol */ +YY_RULE_SETUP +{ + // A newline ends the current file name and the current rule. + yyextra->newEntry(); + } + YY_BREAK +case 7: +YY_RULE_SETUP +{ + // A colon followed by space ends the rules and starts a new dependency. + yyextra->newDependency(); + } + YY_BREAK +case 8: +YY_RULE_SETUP +{ + // Rules and dependencies are separated by blocks of whitespace. + yyextra->newRuleOrDependency(); + } + YY_BREAK +case 9: +YY_RULE_SETUP +{ + // Got a span of plain text. + yyextra->addToCurrentPath(yytext); + } + YY_BREAK +case 10: +YY_RULE_SETUP +{ + // Got an otherwise unmatched character. + yyextra->addToCurrentPath(yytext); + } + YY_BREAK +case 11: +YY_RULE_SETUP +ECHO; + YY_BREAK +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yyg->yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); + + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yyg->yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yyg->yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_END_OF_FILE: + { + yyg->yy_did_buffer_switch_on_eof = 0; + + if ( yywrap( yyscanner ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = + yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yyg->yy_c_buf_p = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = yyg->yytext_ptr; + int number_to_move, i; + int ret_val; + + if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) (yyg->yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + yyg->yy_n_chars, num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + if ( yyg->yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin , yyscanner); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + yyg->yy_n_chars += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (yyscan_t yyscanner) +{ + yy_state_type yy_current_state; + char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_current_state = yyg->yy_start; + + for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 26 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) +{ + int yy_is_jam; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ + char *yy_cp = yyg->yy_c_buf_p; + + YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 26 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 25); + + (void)yyg; + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT + + static void yyunput (int c, char * yy_bp , yyscan_t yyscanner) +{ + char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_cp = yyg->yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yyg->yy_hold_char; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + int number_to_move = yyg->yy_n_chars + 2; + char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + yyg->yy_n_chars = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + yyg->yytext_ptr = yy_bp; + yyg->yy_hold_char = *yy_cp; + yyg->yy_c_buf_p = yy_cp; +} + +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (yyscan_t yyscanner) +#else + static int input (yyscan_t yyscanner) +#endif + +{ + int c; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + *yyg->yy_c_buf_p = yyg->yy_hold_char; + + if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + /* This was really a NUL. */ + *yyg->yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); + ++yyg->yy_c_buf_p; + + switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin , yyscanner); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( yyscanner ) ) + return 0; + + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(yyscanner); +#else + return input(yyscanner); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = yyg->yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ + *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ + yyg->yy_hold_char = *++yyg->yy_c_buf_p; + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * @param yyscanner The scanner object. + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner); + yy_load_buffer_state( yyscanner ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * @param yyscanner The scanner object. + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (yyscanner); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( yyscanner ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yyg->yy_did_buffer_switch_on_eof = 1; +} + +static void yy_load_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + yyg->yy_hold_char = *yyg->yy_c_buf_p; +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * @param yyscanner The scanner object. + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file , yyscanner); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * @param yyscanner The scanner object. + */ + void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf , yyscanner ); + + yyfree( (void *) b , yyscanner ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) + +{ + int oerrno = errno; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_flush_buffer( b , yyscanner); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * @param yyscanner The scanner object. + */ + void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( yyscanner ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * @param yyscanner The scanner object. + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(yyscanner); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + yyg->yy_buffer_stack_top++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * @param yyscanner The scanner object. + */ +void yypop_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner); + YY_CURRENT_BUFFER_LVALUE = NULL; + if (yyg->yy_buffer_stack_top > 0) + --yyg->yy_buffer_stack_top; + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (yyscan_t yyscanner) +{ + yy_size_t num_to_alloc; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (!yyg->yy_buffer_stack) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + yyg->yy_buffer_stack_max = num_to_alloc; + yyg->yy_buffer_stack_top = 0; + return; + } + + if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = yyg->yy_buffer_stack_max + grow_size; + yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc + (yyg->yy_buffer_stack, + num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); + yyg->yy_buffer_stack_max = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return NULL; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b , yyscanner ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner) +{ + + return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n , yyscanner ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n , yyscanner); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = yyg->yy_hold_char; \ + yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ + yyg->yy_hold_char = *yyg->yy_c_buf_p; \ + *yyg->yy_c_buf_p = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the user-defined data for this scanner. + * @param yyscanner The scanner object. + */ +YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyextra; +} + +/** Get the current line number. + * @param yyscanner The scanner object. + */ +int yyget_lineno (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yylineno; +} + +/** Get the current column number. + * @param yyscanner The scanner object. + */ +int yyget_column (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yycolumn; +} + +/** Get the input stream. + * @param yyscanner The scanner object. + */ +FILE *yyget_in (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyin; +} + +/** Get the output stream. + * @param yyscanner The scanner object. + */ +FILE *yyget_out (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyout; +} + +/** Get the length of the current token. + * @param yyscanner The scanner object. + */ +int yyget_leng (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyleng; +} + +/** Get the current token. + * @param yyscanner The scanner object. + */ + +char *yyget_text (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yytext; +} + +/** Set the user-defined data. This data is never touched by the scanner. + * @param user_defined The data to be associated with this scanner. + * @param yyscanner The scanner object. + */ +void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyextra = user_defined ; +} + +/** Set the current line number. + * @param _line_number line number + * @param yyscanner The scanner object. + */ +void yyset_lineno (int _line_number , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* lineno is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); + + yylineno = _line_number; +} + +/** Set the current column. + * @param _column_no column number + * @param yyscanner The scanner object. + */ +void yyset_column (int _column_no , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* column is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + YY_FATAL_ERROR( "yyset_column called with no buffer" ); + + yycolumn = _column_no; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * @param yyscanner The scanner object. + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * _in_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyin = _in_str ; +} + +void yyset_out (FILE * _out_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyout = _out_str ; +} + +int yyget_debug (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yy_flex_debug; +} + +void yyset_debug (int _bdebug , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yy_flex_debug = _bdebug ; +} + +/* Accessor methods for yylval and yylloc */ + +/* User-visible API */ + +/* yylex_init is special because it creates the scanner itself, so it is + * the ONLY reentrant function that doesn't take the scanner as the last argument. + * That's why we explicitly handle the declaration, instead of using our macros. + */ +int yylex_init(yyscan_t* ptr_yy_globals) +{ + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + return yy_init_globals ( *ptr_yy_globals ); +} + +/* yylex_init_extra has the same functionality as yylex_init, but follows the + * convention of taking the scanner as the last argument. Note however, that + * this is a *pointer* to a scanner, as it will be allocated by this call (and + * is the reason, too, why this function also must handle its own declaration). + * The user defined value in the first argument will be available to yyalloc in + * the yyextra field. + */ +int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals ) +{ + struct yyguts_t dummy_yyguts; + + yyset_extra (yy_user_defined, &dummy_yyguts); + + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in + yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + yyset_extra (yy_user_defined, *ptr_yy_globals); + + return yy_init_globals ( *ptr_yy_globals ); +} + +static int yy_init_globals (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + yyg->yy_buffer_stack = NULL; + yyg->yy_buffer_stack_top = 0; + yyg->yy_buffer_stack_max = 0; + yyg->yy_c_buf_p = NULL; + yyg->yy_init = 0; + yyg->yy_start = 0; + + yyg->yy_start_stack_ptr = 0; + yyg->yy_start_stack_depth = 0; + yyg->yy_start_stack = NULL; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = NULL; + yyout = NULL; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(yyscanner); + } + + /* Destroy the stack itself. */ + yyfree(yyg->yy_buffer_stack , yyscanner); + yyg->yy_buffer_stack = NULL; + + /* Destroy the start condition stack. */ + yyfree( yyg->yy_start_stack , yyscanner ); + yyg->yy_start_stack = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( yyscanner); + + /* Destroy the main struct (reentrant only). */ + yyfree ( yyscanner , yyscanner ); + yyscanner = NULL; + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s , yyscan_t yyscanner) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +/*--------------------------------------------------------------------------*/ + +#endif /* __clang_analyzer__ */ diff --git a/Source/LexerParser/cmGccDepfileLexer.h b/Source/LexerParser/cmGccDepfileLexer.h new file mode 100644 index 0000000..7d34060 --- /dev/null +++ b/Source/LexerParser/cmGccDepfileLexer.h @@ -0,0 +1,687 @@ +#ifndef cmGccDepfile_yyHEADER_H +#define cmGccDepfile_yyHEADER_H 1 +#define cmGccDepfile_yyIN_HEADER 1 + +#define FLEXINT_H 1 +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +#ifdef yy_create_buffer +#define cmGccDepfile_yy_create_buffer_ALREADY_DEFINED +#else +#define yy_create_buffer cmGccDepfile_yy_create_buffer +#endif + +#ifdef yy_delete_buffer +#define cmGccDepfile_yy_delete_buffer_ALREADY_DEFINED +#else +#define yy_delete_buffer cmGccDepfile_yy_delete_buffer +#endif + +#ifdef yy_scan_buffer +#define cmGccDepfile_yy_scan_buffer_ALREADY_DEFINED +#else +#define yy_scan_buffer cmGccDepfile_yy_scan_buffer +#endif + +#ifdef yy_scan_string +#define cmGccDepfile_yy_scan_string_ALREADY_DEFINED +#else +#define yy_scan_string cmGccDepfile_yy_scan_string +#endif + +#ifdef yy_scan_bytes +#define cmGccDepfile_yy_scan_bytes_ALREADY_DEFINED +#else +#define yy_scan_bytes cmGccDepfile_yy_scan_bytes +#endif + +#ifdef yy_init_buffer +#define cmGccDepfile_yy_init_buffer_ALREADY_DEFINED +#else +#define yy_init_buffer cmGccDepfile_yy_init_buffer +#endif + +#ifdef yy_flush_buffer +#define cmGccDepfile_yy_flush_buffer_ALREADY_DEFINED +#else +#define yy_flush_buffer cmGccDepfile_yy_flush_buffer +#endif + +#ifdef yy_load_buffer_state +#define cmGccDepfile_yy_load_buffer_state_ALREADY_DEFINED +#else +#define yy_load_buffer_state cmGccDepfile_yy_load_buffer_state +#endif + +#ifdef yy_switch_to_buffer +#define cmGccDepfile_yy_switch_to_buffer_ALREADY_DEFINED +#else +#define yy_switch_to_buffer cmGccDepfile_yy_switch_to_buffer +#endif + +#ifdef yypush_buffer_state +#define cmGccDepfile_yypush_buffer_state_ALREADY_DEFINED +#else +#define yypush_buffer_state cmGccDepfile_yypush_buffer_state +#endif + +#ifdef yypop_buffer_state +#define cmGccDepfile_yypop_buffer_state_ALREADY_DEFINED +#else +#define yypop_buffer_state cmGccDepfile_yypop_buffer_state +#endif + +#ifdef yyensure_buffer_stack +#define cmGccDepfile_yyensure_buffer_stack_ALREADY_DEFINED +#else +#define yyensure_buffer_stack cmGccDepfile_yyensure_buffer_stack +#endif + +#ifdef yylex +#define cmGccDepfile_yylex_ALREADY_DEFINED +#else +#define yylex cmGccDepfile_yylex +#endif + +#ifdef yyrestart +#define cmGccDepfile_yyrestart_ALREADY_DEFINED +#else +#define yyrestart cmGccDepfile_yyrestart +#endif + +#ifdef yylex_init +#define cmGccDepfile_yylex_init_ALREADY_DEFINED +#else +#define yylex_init cmGccDepfile_yylex_init +#endif + +#ifdef yylex_init_extra +#define cmGccDepfile_yylex_init_extra_ALREADY_DEFINED +#else +#define yylex_init_extra cmGccDepfile_yylex_init_extra +#endif + +#ifdef yylex_destroy +#define cmGccDepfile_yylex_destroy_ALREADY_DEFINED +#else +#define yylex_destroy cmGccDepfile_yylex_destroy +#endif + +#ifdef yyget_debug +#define cmGccDepfile_yyget_debug_ALREADY_DEFINED +#else +#define yyget_debug cmGccDepfile_yyget_debug +#endif + +#ifdef yyset_debug +#define cmGccDepfile_yyset_debug_ALREADY_DEFINED +#else +#define yyset_debug cmGccDepfile_yyset_debug +#endif + +#ifdef yyget_extra +#define cmGccDepfile_yyget_extra_ALREADY_DEFINED +#else +#define yyget_extra cmGccDepfile_yyget_extra +#endif + +#ifdef yyset_extra +#define cmGccDepfile_yyset_extra_ALREADY_DEFINED +#else +#define yyset_extra cmGccDepfile_yyset_extra +#endif + +#ifdef yyget_in +#define cmGccDepfile_yyget_in_ALREADY_DEFINED +#else +#define yyget_in cmGccDepfile_yyget_in +#endif + +#ifdef yyset_in +#define cmGccDepfile_yyset_in_ALREADY_DEFINED +#else +#define yyset_in cmGccDepfile_yyset_in +#endif + +#ifdef yyget_out +#define cmGccDepfile_yyget_out_ALREADY_DEFINED +#else +#define yyget_out cmGccDepfile_yyget_out +#endif + +#ifdef yyset_out +#define cmGccDepfile_yyset_out_ALREADY_DEFINED +#else +#define yyset_out cmGccDepfile_yyset_out +#endif + +#ifdef yyget_leng +#define cmGccDepfile_yyget_leng_ALREADY_DEFINED +#else +#define yyget_leng cmGccDepfile_yyget_leng +#endif + +#ifdef yyget_text +#define cmGccDepfile_yyget_text_ALREADY_DEFINED +#else +#define yyget_text cmGccDepfile_yyget_text +#endif + +#ifdef yyget_lineno +#define cmGccDepfile_yyget_lineno_ALREADY_DEFINED +#else +#define yyget_lineno cmGccDepfile_yyget_lineno +#endif + +#ifdef yyset_lineno +#define cmGccDepfile_yyset_lineno_ALREADY_DEFINED +#else +#define yyset_lineno cmGccDepfile_yyset_lineno +#endif + +#ifdef yyget_column +#define cmGccDepfile_yyget_column_ALREADY_DEFINED +#else +#define yyget_column cmGccDepfile_yyget_column +#endif + +#ifdef yyset_column +#define cmGccDepfile_yyset_column_ALREADY_DEFINED +#else +#define yyset_column cmGccDepfile_yyset_column +#endif + +#ifdef yywrap +#define cmGccDepfile_yywrap_ALREADY_DEFINED +#else +#define yywrap cmGccDepfile_yywrap +#endif + +#ifdef yyalloc +#define cmGccDepfile_yyalloc_ALREADY_DEFINED +#else +#define yyalloc cmGccDepfile_yyalloc +#endif + +#ifdef yyrealloc +#define cmGccDepfile_yyrealloc_ALREADY_DEFINED +#else +#define yyrealloc cmGccDepfile_yyrealloc +#endif + +#ifdef yyfree +#define cmGccDepfile_yyfree_ALREADY_DEFINED +#else +#define yyfree cmGccDepfile_yyfree +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +void yyrestart ( FILE *input_file , yyscan_t yyscanner ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); +void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); +void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); +void yypop_buffer_state ( yyscan_t yyscanner ); + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); + +void *yyalloc ( yy_size_t , yyscan_t yyscanner ); +void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); +void yyfree ( void * , yyscan_t yyscanner ); + +/* Begin user sect3 */ + +#define cmGccDepfile_yywrap(yyscanner) (/*CONSTCOND*/1) +#define YY_SKIP_YYWRAP + +#define yytext_ptr yytext_r + +#ifdef YY_HEADER_EXPORT_START_CONDITIONS +#define INITIAL 0 + +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +int yylex_init (yyscan_t* scanner); + +int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( yyscan_t yyscanner ); + +int yyget_debug ( yyscan_t yyscanner ); + +void yyset_debug ( int debug_flag , yyscan_t yyscanner ); + +YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); + +FILE *yyget_in ( yyscan_t yyscanner ); + +void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); + +FILE *yyget_out ( yyscan_t yyscanner ); + +void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); + + int yyget_leng ( yyscan_t yyscanner ); + +char *yyget_text ( yyscan_t yyscanner ); + +int yyget_lineno ( yyscan_t yyscanner ); + +void yyset_lineno ( int _line_number , yyscan_t yyscanner ); + +int yyget_column ( yyscan_t yyscanner ); + +void yyset_column ( int _column_no , yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( yyscan_t yyscanner ); +#else +extern int yywrap ( yyscan_t yyscanner ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * , yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (yyscan_t yyscanner); + +#define YY_DECL int yylex (yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif + +#ifndef cmGccDepfile_yy_create_buffer_ALREADY_DEFINED +#undef yy_create_buffer +#endif +#ifndef cmGccDepfile_yy_delete_buffer_ALREADY_DEFINED +#undef yy_delete_buffer +#endif +#ifndef cmGccDepfile_yy_scan_buffer_ALREADY_DEFINED +#undef yy_scan_buffer +#endif +#ifndef cmGccDepfile_yy_scan_string_ALREADY_DEFINED +#undef yy_scan_string +#endif +#ifndef cmGccDepfile_yy_scan_bytes_ALREADY_DEFINED +#undef yy_scan_bytes +#endif +#ifndef cmGccDepfile_yy_init_buffer_ALREADY_DEFINED +#undef yy_init_buffer +#endif +#ifndef cmGccDepfile_yy_flush_buffer_ALREADY_DEFINED +#undef yy_flush_buffer +#endif +#ifndef cmGccDepfile_yy_load_buffer_state_ALREADY_DEFINED +#undef yy_load_buffer_state +#endif +#ifndef cmGccDepfile_yy_switch_to_buffer_ALREADY_DEFINED +#undef yy_switch_to_buffer +#endif +#ifndef cmGccDepfile_yypush_buffer_state_ALREADY_DEFINED +#undef yypush_buffer_state +#endif +#ifndef cmGccDepfile_yypop_buffer_state_ALREADY_DEFINED +#undef yypop_buffer_state +#endif +#ifndef cmGccDepfile_yyensure_buffer_stack_ALREADY_DEFINED +#undef yyensure_buffer_stack +#endif +#ifndef cmGccDepfile_yylex_ALREADY_DEFINED +#undef yylex +#endif +#ifndef cmGccDepfile_yyrestart_ALREADY_DEFINED +#undef yyrestart +#endif +#ifndef cmGccDepfile_yylex_init_ALREADY_DEFINED +#undef yylex_init +#endif +#ifndef cmGccDepfile_yylex_init_extra_ALREADY_DEFINED +#undef yylex_init_extra +#endif +#ifndef cmGccDepfile_yylex_destroy_ALREADY_DEFINED +#undef yylex_destroy +#endif +#ifndef cmGccDepfile_yyget_debug_ALREADY_DEFINED +#undef yyget_debug +#endif +#ifndef cmGccDepfile_yyset_debug_ALREADY_DEFINED +#undef yyset_debug +#endif +#ifndef cmGccDepfile_yyget_extra_ALREADY_DEFINED +#undef yyget_extra +#endif +#ifndef cmGccDepfile_yyset_extra_ALREADY_DEFINED +#undef yyset_extra +#endif +#ifndef cmGccDepfile_yyget_in_ALREADY_DEFINED +#undef yyget_in +#endif +#ifndef cmGccDepfile_yyset_in_ALREADY_DEFINED +#undef yyset_in +#endif +#ifndef cmGccDepfile_yyget_out_ALREADY_DEFINED +#undef yyget_out +#endif +#ifndef cmGccDepfile_yyset_out_ALREADY_DEFINED +#undef yyset_out +#endif +#ifndef cmGccDepfile_yyget_leng_ALREADY_DEFINED +#undef yyget_leng +#endif +#ifndef cmGccDepfile_yyget_text_ALREADY_DEFINED +#undef yyget_text +#endif +#ifndef cmGccDepfile_yyget_lineno_ALREADY_DEFINED +#undef yyget_lineno +#endif +#ifndef cmGccDepfile_yyset_lineno_ALREADY_DEFINED +#undef yyset_lineno +#endif +#ifndef cmGccDepfile_yyget_column_ALREADY_DEFINED +#undef yyget_column +#endif +#ifndef cmGccDepfile_yyset_column_ALREADY_DEFINED +#undef yyset_column +#endif +#ifndef cmGccDepfile_yywrap_ALREADY_DEFINED +#undef yywrap +#endif +#ifndef cmGccDepfile_yyget_lval_ALREADY_DEFINED +#undef yyget_lval +#endif +#ifndef cmGccDepfile_yyset_lval_ALREADY_DEFINED +#undef yyset_lval +#endif +#ifndef cmGccDepfile_yyget_lloc_ALREADY_DEFINED +#undef yyget_lloc +#endif +#ifndef cmGccDepfile_yyset_lloc_ALREADY_DEFINED +#undef yyset_lloc +#endif +#ifndef cmGccDepfile_yyalloc_ALREADY_DEFINED +#undef yyalloc +#endif +#ifndef cmGccDepfile_yyrealloc_ALREADY_DEFINED +#undef yyrealloc +#endif +#ifndef cmGccDepfile_yyfree_ALREADY_DEFINED +#undef yyfree +#endif +#ifndef cmGccDepfile_yytext_ALREADY_DEFINED +#undef yytext +#endif +#ifndef cmGccDepfile_yyleng_ALREADY_DEFINED +#undef yyleng +#endif +#ifndef cmGccDepfile_yyin_ALREADY_DEFINED +#undef yyin +#endif +#ifndef cmGccDepfile_yyout_ALREADY_DEFINED +#undef yyout +#endif +#ifndef cmGccDepfile_yy_flex_debug_ALREADY_DEFINED +#undef yy_flex_debug +#endif +#ifndef cmGccDepfile_yylineno_ALREADY_DEFINED +#undef yylineno +#endif +#ifndef cmGccDepfile_yytables_fload_ALREADY_DEFINED +#undef yytables_fload +#endif +#ifndef cmGccDepfile_yytables_destroy_ALREADY_DEFINED +#undef yytables_destroy +#endif +#ifndef cmGccDepfile_yyTABLES_NAME_ALREADY_DEFINED +#undef yyTABLES_NAME +#endif + +#undef cmGccDepfile_yyIN_HEADER +#endif /* cmGccDepfile_yyHEADER_H */ diff --git a/Source/LexerParser/cmGccDepfileLexer.in.l b/Source/LexerParser/cmGccDepfileLexer.in.l new file mode 100644 index 0000000..08f8577 --- /dev/null +++ b/Source/LexerParser/cmGccDepfileLexer.in.l @@ -0,0 +1,72 @@ +%{ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +/* IWYU pragma: no_forward_declare yyguts_t */ + +#ifndef __clang_analyzer__ /* Suppress clang scan-build warnings */ + +#include <cmGccDepfileLexerHelper.h> +#include <string> +%} + +%option prefix="cmGccDepfile_yy" +%option noyywrap +%option reentrant +%pointer + +WSPACE [ \t] +NEWLINE \r?\n + +%% +\${2} { + // Unescape the dollar sign. + yyextra->addToCurrentPath("$"); + } +\\# { + // Unescape the hash. + yyextra->addToCurrentPath("#"); + } +(\\\\)*\\[ ] { + // 2N+1 backslashes plus space -> N backslashes plus space. + size_t c = (strlen(yytext) - 1) / 2; + std::string s(c, '\\'); + s.push_back(' '); + yyextra->addToCurrentPath(s.c_str()); + } +(\\\\)+[ ] { + // 2N backslashes plus space -> 2N backslashes, end of filename. + yytext[strlen(yytext) - 1] = 0; + yyextra->addToCurrentPath(yytext); + yyextra->newDependency(); + } +{WSPACE}*\\{NEWLINE} { + // A line continuation ends the current file name. + yyextra->newDependency(); + } +{NEWLINE} { + // A newline ends the current file name and the current rule. + yyextra->newEntry(); + } +:{WSPACE}+ { + // A colon followed by space ends the rules and starts a new dependency. + yyextra->newDependency(); + } +{WSPACE}+ { + // Rules and dependencies are separated by blocks of whitespace. + yyextra->newRuleOrDependency(); + } +[a-zA-Z0-9+,/_.~()}{%=@\x5B\x5D!\x80-\xFF-]+ { + // Got a span of plain text. + yyextra->addToCurrentPath(yytext); + } +. { + // Got an otherwise unmatched character. + yyextra->addToCurrentPath(yytext); + } + +%% + +/*--------------------------------------------------------------------------*/ + +#endif /* __clang_analyzer__ */ diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index e5eea79..f8d1aa7 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -200,8 +200,10 @@ bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix, bool cmArchiveWrite::AddPath(const char* path, size_t skip, const char* prefix, bool recursive) { - if (!this->AddFile(path, skip, prefix)) { - return false; + if (strcmp(path, ".") != 0 || this->Format != "zip") { + if (!this->AddFile(path, skip, prefix)) { + return false; + } } if ((!cmSystemTools::FileIsDirectory(path) || !recursive) || cmSystemTools::FileIsSymlink(path)) { @@ -210,6 +212,9 @@ bool cmArchiveWrite::AddPath(const char* path, size_t skip, const char* prefix, cmsys::Directory d; if (d.Load(path)) { std::string next = cmStrCat(path, '/'); + if (next == "./" && this->Format == "zip") { + next.clear(); + } std::string::size_type end = next.size(); unsigned long n = d.GetNumberOfFiles(); for (unsigned long i = 0; i < n; ++i) { diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index f9f5b72..7be6d2c 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -8,6 +8,8 @@ #include <sstream> #include <utility> +#include <cm/memory> + #include "cmAlgorithms.h" #include "cmComputeLinkDepends.h" #include "cmGeneratorExpression.h" @@ -257,11 +259,10 @@ cmComputeLinkInformation::cmComputeLinkInformation( "FIND_LIBRARY_USE_OPENBSD_VERSIONING"); // Allocate internals. - this->OrderLinkerSearchPath = new cmOrderDirectories( + this->OrderLinkerSearchPath = cm::make_unique<cmOrderDirectories>( this->GlobalGenerator, target, "linker search path"); - this->OrderRuntimeSearchPath = new cmOrderDirectories( + this->OrderRuntimeSearchPath = cm::make_unique<cmOrderDirectories>( this->GlobalGenerator, target, "runtime search path"); - this->OrderDependentRPath = nullptr; // Get the language used for linking this target. this->LinkLanguage = this->Target->GetLinkerLanguage(config); @@ -359,7 +360,7 @@ cmComputeLinkInformation::cmComputeLinkInformation( this->SharedDependencyMode = SharedDepModeLibDir; } else if (!this->RPathLinkFlag.empty()) { this->SharedDependencyMode = SharedDepModeDir; - this->OrderDependentRPath = new cmOrderDirectories( + this->OrderDependentRPath = cm::make_unique<cmOrderDirectories>( this->GlobalGenerator, target, "dependent library path"); } @@ -401,12 +402,7 @@ cmComputeLinkInformation::cmComputeLinkInformation( "CMAKE_POLICY_WARNING_CMP0060"); } -cmComputeLinkInformation::~cmComputeLinkInformation() -{ - delete this->OrderLinkerSearchPath; - delete this->OrderRuntimeSearchPath; - delete this->OrderDependentRPath; -} +cmComputeLinkInformation::~cmComputeLinkInformation() = default; void cmComputeLinkInformation::AppendValues( std::string& result, std::vector<BT<std::string>>& values) @@ -790,10 +786,10 @@ void cmComputeLinkInformation::AddSharedDepItem(std::string const& item, if (this->SharedDependencyMode == SharedDepModeLibDir && !this->LinkWithRuntimePath /* AddLibraryRuntimeInfo adds it */) { // Add the item to the linker search path. - order = this->OrderLinkerSearchPath; + order = this->OrderLinkerSearchPath.get(); } else if (this->SharedDependencyMode == SharedDepModeDir) { // Add the item to the separate dependent library search path. - order = this->OrderDependentRPath; + order = this->OrderDependentRPath.get(); } if (order) { if (tgt) { diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index 46f6705..3bc9c16 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -6,6 +6,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <iosfwd> +#include <memory> #include <set> #include <string> #include <utility> @@ -29,6 +30,9 @@ class cmComputeLinkInformation public: cmComputeLinkInformation(cmGeneratorTarget const* target, const std::string& config); + cmComputeLinkInformation(const cmComputeLinkInformation&) = delete; + cmComputeLinkInformation& operator=(const cmComputeLinkInformation&) = + delete; ~cmComputeLinkInformation(); bool Compute(); @@ -164,7 +168,7 @@ private: cmsys::RegularExpression SplitFramework; // Linker search path computation. - cmOrderDirectories* OrderLinkerSearchPath; + std::unique_ptr<cmOrderDirectories> OrderLinkerSearchPath; bool FinishLinkerSearchDirectories(); void PrintLinkPolicyDiagnosis(std::ostream&); @@ -185,9 +189,9 @@ private: std::vector<std::string> OldUserFlagItems; std::set<std::string> CMP0060WarnItems; // Dependent library path computation. - cmOrderDirectories* OrderDependentRPath; + std::unique_ptr<cmOrderDirectories> OrderDependentRPath; // Runtime path computation. - cmOrderDirectories* OrderRuntimeSearchPath; + std::unique_ptr<cmOrderDirectories> OrderRuntimeSearchPath; bool OldLinkDirMode; bool OpenBSD; diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 34f815f..2432d2b 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -139,7 +139,7 @@ const char* cmCustomCommandGenerator::GetArgv0Location(unsigned int c) const (target->IsImported() || target->GetProperty("CROSSCOMPILING_EMULATOR") || !this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING"))) { - return target->GetLocation(this->Config); + return target->GetLocation(this->Config).c_str(); } return nullptr; } diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 27e9906..6441e6f 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -61,9 +61,9 @@ void cmExportFileGenerator::SetExportFile(const char* mainFile) cmSystemTools::GetFilenameLastExtension(this->MainImportFile); } -const char* cmExportFileGenerator::GetMainExportFileName() const +const std::string& cmExportFileGenerator::GetMainExportFileName() const { - return this->MainImportFile.c_str(); + return this->MainImportFile; } bool cmExportFileGenerator::GenerateImportFile() diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 0d69779..e9d0da7 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -46,7 +46,7 @@ public: /** Set the full path to the export file to generate. */ void SetExportFile(const char* mainFile); - const char* GetMainExportFileName() const; + const std::string& GetMainExportFileName() const; /** Set the namespace in which to place exported target names. */ void SetNamespace(const std::string& ns) { this->Namespace = ns; } diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 603fea3..413449c 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -297,8 +297,7 @@ void cmExtraSublimeTextGenerator::AppendTarget( fout << "\t{\n\t\t\t\"name\": \"" << lg->GetProjectName() << " - " << targetName << "\",\n"; fout << "\t\t\t\"cmd\": [" - << this->BuildMakeCommand(make, makefileName.c_str(), targetName) - << "],\n"; + << this->BuildMakeCommand(make, makefileName, targetName) << "],\n"; fout << "\t\t\t\"working_dir\": \"${project_path}\",\n"; fout << "\t\t\t\"file_regex\": \"" "^(..[^:]*)(?::|\\\\()([0-9]+)(?::|\\\\))(?:([0-9]+):)?\\\\s*(.*)" @@ -309,7 +308,8 @@ void cmExtraSublimeTextGenerator::AppendTarget( // Create the command line for building the given target using the selected // make std::string cmExtraSublimeTextGenerator::BuildMakeCommand( - const std::string& make, const char* makefile, const std::string& target) + const std::string& make, const std::string& makefile, + const std::string& target) { std::string command = cmStrCat('"', make, '"'); std::string generator = this->GlobalGenerator->GetName(); diff --git a/Source/cmExtraSublimeTextGenerator.h b/Source/cmExtraSublimeTextGenerator.h index 7e8f2d4..078cfe7 100644 --- a/Source/cmExtraSublimeTextGenerator.h +++ b/Source/cmExtraSublimeTextGenerator.h @@ -44,7 +44,8 @@ private: /** Returns the build command that needs to be executed to build the * specified target. */ - std::string BuildMakeCommand(const std::string& make, const char* makefile, + std::string BuildMakeCommand(const std::string& make, + const std::string& makefile, const std::string& target); /** Appends the specified target to the generated project file as a Sublime * Text build system. diff --git a/Source/cmGccDepfileLexerHelper.cxx b/Source/cmGccDepfileLexerHelper.cxx new file mode 100644 index 0000000..957896f --- /dev/null +++ b/Source/cmGccDepfileLexerHelper.cxx @@ -0,0 +1,126 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmGccDepfileLexerHelper.h" + +#include <cstdio> +#include <memory> +#include <string> +#include <vector> + +#include "cmGccDepfileReaderTypes.h" + +#include "LexerParser/cmGccDepfileLexer.h" + +#ifdef _WIN32 +# include "cmsys/Encoding.h" +#endif + +bool cmGccDepfileLexerHelper::readFile(const char* filePath) +{ +#ifdef _WIN32 + wchar_t* wpath = cmsysEncoding_DupToWide(filePath); + FILE* file = _wfopen(wpath, L"rb"); + free(wpath); +#else + FILE* file = fopen(filePath, "r"); +#endif + if (!file) { + return false; + } + newEntry(); + yyscan_t scanner; + cmGccDepfile_yylex_init(&scanner); + cmGccDepfile_yyset_extra(this, scanner); + cmGccDepfile_yyrestart(file, scanner); + cmGccDepfile_yylex(scanner); + cmGccDepfile_yylex_destroy(scanner); + sanitizeContent(); + fclose(file); + return true; +} + +void cmGccDepfileLexerHelper::newEntry() +{ + this->HelperState = State::Rule; + this->Content.emplace_back(); + newRule(); +} + +void cmGccDepfileLexerHelper::newRule() +{ + auto& entry = this->Content.back(); + if (entry.rules.empty() || !entry.rules.back().empty()) { + entry.rules.emplace_back(); + } +} + +void cmGccDepfileLexerHelper::newDependency() +{ + // printf("NEW DEP\n"); + this->HelperState = State::Dependency; + if (this->Content.back().paths.empty() || + !this->Content.back().paths.back().empty()) { + this->Content.back().paths.emplace_back(); + } +} + +void cmGccDepfileLexerHelper::newRuleOrDependency() +{ + if (this->HelperState == State::Rule) { + newRule(); + } else { + newDependency(); + } +} + +void cmGccDepfileLexerHelper::addToCurrentPath(const char* s) +{ + if (this->Content.empty()) { + return; + } + cmGccStyleDependency* dep = &this->Content.back(); + std::string* dst = nullptr; + switch (this->HelperState) { + case State::Rule: { + if (dep->rules.empty()) { + return; + } + dst = &dep->rules.back(); + } break; + case State::Dependency: { + if (dep->paths.empty()) { + return; + } + dst = &dep->paths.back(); + } break; + } + dst->append(s); +} + +void cmGccDepfileLexerHelper::sanitizeContent() +{ + for (auto it = this->Content.begin(); it != this->Content.end();) { + // Remove empty rules + for (auto rit = it->rules.begin(); rit != it->rules.end();) { + if (rit->empty()) { + rit = it->rules.erase(rit); + } else { + ++rit; + } + } + // Remove the entry if rules are empty + if (it->rules.empty()) { + it = this->Content.erase(it); + } else { + // Remove empty paths + for (auto pit = it->paths.begin(); pit != it->paths.end();) { + if (pit->empty()) { + pit = it->paths.erase(pit); + } else { + ++pit; + } + } + ++it; + } + } +} diff --git a/Source/cmGccDepfileLexerHelper.h b/Source/cmGccDepfileLexerHelper.h new file mode 100644 index 0000000..e6b2fcf --- /dev/null +++ b/Source/cmGccDepfileLexerHelper.h @@ -0,0 +1,40 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmGccDepfileLexerHelper_h +#define cmGccDepfileLexerHelper_h + +#include <utility> + +#include <cmGccDepfileReaderTypes.h> + +class cmGccDepfileLexerHelper +{ +public: + cmGccDepfileLexerHelper() = default; + + bool readFile(const char* filePath); + cmGccDepfileContent extractContent() && { return std::move(this->Content); } + + // Functions called by the lexer + void newEntry(); + void newRule(); + void newDependency(); + void newRuleOrDependency(); + void addToCurrentPath(const char* s); + +private: + void sanitizeContent(); + + cmGccDepfileContent Content; + + enum class State + { + Rule, + Dependency + }; + State HelperState = State::Rule; +}; + +#define YY_EXTRA_TYPE cmGccDepfileLexerHelper* + +#endif diff --git a/Source/cmGccDepfileReader.cxx b/Source/cmGccDepfileReader.cxx new file mode 100644 index 0000000..9d70ede --- /dev/null +++ b/Source/cmGccDepfileReader.cxx @@ -0,0 +1,18 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmGccDepfileReader.h" + +#include <type_traits> +#include <utility> + +#include "cmGccDepfileLexerHelper.h" + +cmGccDepfileContent cmReadGccDepfile(const char* filePath) +{ + cmGccDepfileContent result; + cmGccDepfileLexerHelper helper; + if (helper.readFile(filePath)) { + result = std::move(helper).extractContent(); + } + return result; +} diff --git a/Source/cmGccDepfileReader.h b/Source/cmGccDepfileReader.h new file mode 100644 index 0000000..9313010 --- /dev/null +++ b/Source/cmGccDepfileReader.h @@ -0,0 +1,10 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmGccDepfileReader_h +#define cmGccDepfileReader_h + +#include "cmGccDepfileReaderTypes.h" + +cmGccDepfileContent cmReadGccDepfile(const char* filePath); + +#endif diff --git a/Source/cmGccDepfileReaderTypes.h b/Source/cmGccDepfileReaderTypes.h new file mode 100644 index 0000000..8b15c73 --- /dev/null +++ b/Source/cmGccDepfileReaderTypes.h @@ -0,0 +1,17 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmGccDepfileReaderTypes_h +#define cmGccDepfileReaderTypes_h + +#include <string> +#include <vector> + +struct cmGccStyleDependency +{ + std::vector<std::string> rules; + std::vector<std::string> paths; +}; + +using cmGccDepfileContent = std::vector<cmGccStyleDependency>; + +#endif diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index c525a6e..4dfc33d 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -54,11 +54,11 @@ const char* cmTargetPropertyComputer::GetSources<cmGeneratorTarget>( cmGeneratorTarget const* tgt, cmMessenger* /* messenger */, cmListFileBacktrace const& /* context */) { - return tgt->GetSourcesProperty(); + return tgt->GetSourcesProperty().c_str(); } template <> -const char* +const std::string& cmTargetPropertyComputer::ComputeLocationForBuild<cmGeneratorTarget>( cmGeneratorTarget const* tgt) { @@ -66,7 +66,8 @@ cmTargetPropertyComputer::ComputeLocationForBuild<cmGeneratorTarget>( } template <> -const char* cmTargetPropertyComputer::ComputeLocation<cmGeneratorTarget>( +const std::string& +cmTargetPropertyComputer::ComputeLocation<cmGeneratorTarget>( cmGeneratorTarget const* tgt, const std::string& config) { return tgt->GetLocation(config); @@ -310,7 +311,7 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg) cmGeneratorTarget::~cmGeneratorTarget() = default; -const char* cmGeneratorTarget::GetSourcesProperty() const +const std::string& cmGeneratorTarget::GetSourcesProperty() const { std::vector<std::string> values; for (auto& se : this->SourceEntries) { @@ -319,7 +320,7 @@ const char* cmGeneratorTarget::GetSourcesProperty() const static std::string value; value.clear(); value = cmJoin(values, ";"); - return value.c_str(); + return value; } cmGlobalGenerator* cmGeneratorTarget::GetGlobalGenerator() const @@ -996,7 +997,8 @@ void cmGeneratorTarget::GetXamlSources(std::vector<cmSourceFile const*>& data, IMPLEMENT_VISIT(SourceKindXaml); } -const char* cmGeneratorTarget::GetLocation(const std::string& config) const +const std::string& cmGeneratorTarget::GetLocation( + const std::string& config) const { static std::string location; if (this->IsImported()) { @@ -1005,7 +1007,7 @@ const char* cmGeneratorTarget::GetLocation(const std::string& config) const } else { location = this->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact); } - return location.c_str(); + return location; } std::vector<cmCustomCommand> const& cmGeneratorTarget::GetPreBuildCommands() @@ -1036,13 +1038,13 @@ bool cmGeneratorTarget::IsImportedGloballyVisible() const return this->Target->IsImportedGloballyVisible(); } -const char* cmGeneratorTarget::GetLocationForBuild() const +const std::string& cmGeneratorTarget::GetLocationForBuild() const { static std::string location; if (this->IsImported()) { location = this->Target->ImportedGetFullPath( "", cmStateEnums::RuntimeBinaryArtifact); - return location.c_str(); + return location; } // Now handle the deprecated build-time configuration location. @@ -1062,7 +1064,7 @@ const char* cmGeneratorTarget::GetLocationForBuild() const } location += "/"; location += this->GetFullName("", cmStateEnums::RuntimeBinaryArtifact); - return location.c_str(); + return location; } bool cmGeneratorTarget::IsSystemIncludeDirectory( diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index ac254c1..b647b25 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -46,7 +46,7 @@ public: bool IsImported() const; bool IsImportedGloballyVisible() const; - const char* GetLocation(const std::string& config) const; + const std::string& GetLocation(const std::string& config) const; std::vector<cmCustomCommand> const& GetPreBuildCommands() const; std::vector<cmCustomCommand> const& GetPreLinkCommands() const; @@ -65,7 +65,7 @@ public: /** Get the location of the target in the build tree with a placeholder referencing the configuration in the native build system. This location is suitable for use as the LOCATION target property. */ - const char* GetLocationForBuild() const; + const std::string& GetLocationForBuild() const; cmComputeLinkInformation* GetLinkInformation( const std::string& config) const; @@ -770,7 +770,7 @@ public: std::string GetFortranModuleDirectory(std::string const& working_dir) const; - const char* GetSourcesProperty() const; + const std::string& GetSourcesProperty() const; private: void AddSourceCommon(const std::string& src, bool before = false); diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 45e13bc..1f084f5 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2527,6 +2527,7 @@ void cmGlobalGenerator::AddGlobalTarget_RebuildCache( gti.PerConfig = false; cmCustomCommandLine singleLine; singleLine.push_back(cmSystemTools::GetCMakeCommand()); + singleLine.push_back("--regenerate-during-build"); singleLine.push_back("-S$(CMAKE_SOURCE_DIR)"); singleLine.push_back("-B$(CMAKE_BINARY_DIR)"); gti.CommandLines.push_back(std::move(singleLine)); diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 2dd89e3..f6613d0 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -528,6 +528,19 @@ void cmGlobalNinjaGenerator::Generate() this->CloseRulesFileStream(); this->CloseBuildFileStreams(); +#ifdef _WIN32 + // The ninja tools will not be able to update metadata on Windows + // when we are re-generating inside an existing 'ninja' invocation + // because the outer tool has the files open for write. + if (!this->GetCMakeInstance()->GetRegenerateDuringBuild()) +#endif + { + this->CleanMetaData(); + } +} + +void cmGlobalNinjaGenerator::CleanMetaData() +{ auto run_ninja_tool = [this](std::vector<char const*> const& args) { std::vector<std::string> command; command.push_back(this->NinjaCommand); @@ -549,22 +562,33 @@ void cmGlobalNinjaGenerator::Generate() } }; + // Can the tools below expect 'build.ninja' to be loadable? + bool const expectBuildManifest = + !this->IsMultiConfig() && this->OutputPathPrefix.empty(); + + // Skip some ninja tools if they need 'build.ninja' but it is missing. + bool const missingBuildManifest = expectBuildManifest && + (this->NinjaSupportsCleanDeadTool || + this->NinjaSupportsUnconditionalRecompactTool) && + !cmSystemTools::FileExists("build.ninja"); + // The `cleandead` tool needs to know about all outputs in the build we just // wrote out. Ninja-Multi doesn't have a single `build.ninja` we can use that // is the union of all generated configurations, so we can't run it reliably // in that case. - if (this->NinjaSupportsCleanDeadTool && !this->IsMultiConfig()) { + if (this->NinjaSupportsCleanDeadTool && expectBuildManifest && + !missingBuildManifest) { run_ninja_tool({ "cleandead" }); } // The `recompact` tool loads the manifest. As above, we don't have a single // `build.ninja` to load for this in Ninja-Multi. This may be relaxed in the // future pending further investigation into how Ninja works upstream // (ninja#1721). - if (this->NinjaSupportsUnconditionalRecompactTool && - !this->IsMultiConfig()) { + if (this->NinjaSupportsUnconditionalRecompactTool && expectBuildManifest && + !missingBuildManifest) { run_ninja_tool({ "recompact" }); } - if (this->NinjaSupportsRestatTool) { + if (this->NinjaSupportsRestatTool && this->OutputPathPrefix.empty()) { // XXX(ninja): We only list `build.ninja` entry files here because CMake // *always* rewrites these files on a reconfigure. If CMake ever gets // smarter about this, all CMake-time created/edited files listed as @@ -660,6 +684,17 @@ bool cmGlobalNinjaGenerator::CheckLanguages( if (cmContains(languages, "Fortran")) { return this->CheckFortran(mf); } + if (cmContains(languages, "Swift")) { + const std::string architectures = + mf->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES"); + if (architectures.find_first_of(';') != std::string::npos) { + mf->IssueMessage(MessageType::FATAL_ERROR, + "multiple values for CMAKE_OSX_ARCHITECTURES not " + "supported with Swift"); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + } return true; } @@ -1514,7 +1549,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) { cmNinjaRule rule("RERUN_CMAKE"); rule.Command = - cmStrCat(CMakeCmd(), " -S", + cmStrCat(CMakeCmd(), " --regenerate-during-build -S", lg->ConvertToOutputFormat(lg->GetSourceDirectory(), cmOutputConverter::SHELL), " -B", diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index d00a061..9d5521a 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -438,6 +438,7 @@ private: bool OpenRulesFileStream(); void CloseRulesFileStream(); + void CleanMetaData(); /// Write the common disclaimer text at the top of each build file. void WriteDisclaimer(std::ostream& os); diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index a720cc3..fd65584 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -615,7 +615,7 @@ void cmGlobalVisualStudio10Generator::Generate() "To avoid this problem CMake must use a full path for this file " "which then triggers the VS 10 property dialog bug."; /* clang-format on */ - lg->IssueMessage(MessageType::WARNING, e.str().c_str()); + lg->IssueMessage(MessageType::WARNING, e.str()); } } @@ -836,7 +836,7 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf) // Prepare the work directory. if (!cmSystemTools::MakeDirectory(wd)) { std::string e = "Failed to make directory:\n " + wd; - mf->IssueMessage(MessageType::FATAL_ERROR, e.c_str()); + mf->IssueMessage(MessageType::FATAL_ERROR, e); cmSystemTools::SetFatalErrorOccured(); return false; } @@ -957,7 +957,7 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf) if (ret != 0) { e << "Exit code: " << ret << "\n"; } - mf->IssueMessage(MessageType::FATAL_ERROR, e.str().c_str()); + mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); cmSystemTools::SetFatalErrorOccured(); return false; } @@ -1131,8 +1131,7 @@ std::string cmGlobalVisualStudio10Generator::GenerateRuleFile( // Hide them away under the CMakeFiles directory. std::string ruleDir = cmStrCat( this->GetCMakeInstance()->GetHomeOutputDirectory(), "/CMakeFiles/", - cmSystemTools::ComputeStringMD5( - cmSystemTools::GetFilenamePath(output).c_str())); + cmSystemTools::ComputeStringMD5(cmSystemTools::GetFilenamePath(output))); std::string ruleFile = cmStrCat(ruleDir, '/', cmSystemTools::GetFilenameName(output), ".rule"); return ruleFile; @@ -1326,7 +1325,7 @@ cmIDEFlagTable const* cmGlobalVisualStudio10Generator::LoadFlagTable( e << "JSON flag table \"" << filename << "\" could not be loaded.\n"; /* clang-format on */ - mf->IssueMessage(MessageType::FATAL_ERROR, e.str().c_str()); + mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); } return ret; } diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index e8e9ece..ec1380b 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -87,7 +87,7 @@ void cmGlobalVisualStudio71Generator::WriteSolutionConfigurations( // the libraries it uses are also done here void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout, const std::string& dspname, - const char* dir, + const std::string& dir, cmGeneratorTarget const* t) { // check to see if this is a fortran build @@ -109,7 +109,7 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout, std::string guid = this->GetGUID(dspname); fout << project << dspname << "\", \"" << this->ConvertToSolutionPath(dir) - << (dir[0] ? "\\" : "") << dspname << ext << "\", \"{" << guid + << (!dir.empty() ? "\\" : "") << dspname << ext << "\", \"{" << guid << "}\"\n"; fout << "\tProjectSection(ProjectDependencies) = postProject\n"; this->WriteProjectDepends(fout, dspname, dir, t); @@ -138,7 +138,7 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout, // Note, that dependencies from executables to // the libraries it uses are also done here void cmGlobalVisualStudio71Generator::WriteProjectDepends( - std::ostream& fout, const std::string&, const char*, + std::ostream& fout, const std::string&, const std::string&, cmGeneratorTarget const* target) { VSDependSet const& depends = this->VSTargetDepends[target]; @@ -156,7 +156,7 @@ void cmGlobalVisualStudio71Generator::WriteProjectDepends( // Write a dsp file into the SLN file, Note, that dependencies from // executables to the libraries it uses are also done here void cmGlobalVisualStudio71Generator::WriteExternalProject( - std::ostream& fout, const std::string& name, const char* location, + std::ostream& fout, const std::string& name, const std::string& location, const char* typeGuid, const std::set<BT<std::string>>& depends) { fout << "Project(\"{" diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h index 85755af..61a2f6f 100644 --- a/Source/cmGlobalVisualStudio71Generator.h +++ b/Source/cmGlobalVisualStudio71Generator.h @@ -22,9 +22,10 @@ protected: virtual void WriteSolutionConfigurations( std::ostream& fout, std::vector<std::string> const& configs); void WriteProject(std::ostream& fout, const std::string& name, - const char* path, const cmGeneratorTarget* t) override; + const std::string& path, + const cmGeneratorTarget* t) override; void WriteProjectDepends(std::ostream& fout, const std::string& name, - const char* path, + const std::string& path, cmGeneratorTarget const* t) override; void WriteProjectConfigurations( std::ostream& fout, const std::string& name, @@ -32,7 +33,7 @@ protected: const std::set<std::string>& configsPartOfDefaultBuild, const std::string& platformMapping = "") override; void WriteExternalProject(std::ostream& fout, const std::string& name, - const char* path, const char* typeGuid, + const std::string& path, const char* typeGuid, const std::set<BT<std::string>>& depends) override; // Folders are not supported by VS 7.1. diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 04ec7b3..9799124 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -186,7 +186,7 @@ std::string cmGlobalVisualStudio7Generator::FindDevEnvCommand() } const char* cmGlobalVisualStudio7Generator::ExternalProjectType( - const char* location) + const std::string& location) { std::string extension = cmSystemTools::GetFilenameLastExtension(location); if (extension == ".vbproj") { @@ -346,8 +346,8 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations( if (expath) { std::set<std::string> allConfigurations(configs.begin(), configs.end()); const char* mapping = target->GetProperty("VS_PLATFORM_MAPPING"); - this->WriteProjectConfigurations(fout, target->GetName().c_str(), - *target, configs, allConfigurations, + this->WriteProjectConfigurations(fout, target->GetName(), *target, + configs, allConfigurations, mapping ? mapping : ""); } else { const std::set<std::string>& configsPartOfDefaultBuild = @@ -380,7 +380,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution( std::string project = target->GetName(); std::string location = expath; - this->WriteExternalProject(fout, project.c_str(), location.c_str(), + this->WriteExternalProject(fout, project, location, target->GetProperty("VS_PROJECT_TYPE"), target->GetUtilities()); written = true; @@ -389,11 +389,11 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution( if (vcprojName) { cmLocalGenerator* lg = target->GetLocalGenerator(); std::string dir = lg->GetCurrentBinaryDirectory(); - dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir.c_str()); + dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir); if (dir == ".") { dir.clear(); // msbuild cannot handle ".\" prefix } - this->WriteProject(fout, vcprojName, dir.c_str(), target); + this->WriteProject(fout, vcprojName, dir, target); written = true; } } @@ -483,7 +483,7 @@ void cmGlobalVisualStudio7Generator::WriteFoldersContent(std::ostream& fout) } std::string cmGlobalVisualStudio7Generator::ConvertToSolutionPath( - const char* path) + const std::string& path) { // Convert to backslashes. Do not use ConvertToOutputPath because // we will add quoting ourselves, and we know these projects always diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index 974bb1d..699f091 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -110,16 +110,17 @@ protected: std::string const& GetDevEnvCommand(); virtual std::string FindDevEnvCommand(); - static const char* ExternalProjectType(const char* location); + static const char* ExternalProjectType(const std::string& location); virtual void OutputSLNFile(cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators); virtual void WriteSLNFile(std::ostream& fout, cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators) = 0; virtual void WriteProject(std::ostream& fout, const std::string& name, - const char* path, const cmGeneratorTarget* t) = 0; + const std::string& path, + const cmGeneratorTarget* t) = 0; virtual void WriteProjectDepends(std::ostream& fout, const std::string& name, - const char* path, + const std::string& path, cmGeneratorTarget const* t) = 0; virtual void WriteProjectConfigurations( std::ostream& fout, const std::string& name, @@ -141,10 +142,10 @@ protected: OrderedTargetDependSet const& projectTargets); virtual void WriteExternalProject( - std::ostream& fout, const std::string& name, const char* path, + std::ostream& fout, const std::string& name, const std::string& path, const char* typeGuid, const std::set<BT<std::string>>& dependencies) = 0; - std::string ConvertToSolutionPath(const char* path); + std::string ConvertToSolutionPath(const std::string& path); std::set<std::string> IsPartOfDefaultBuild( std::vector<std::string> const& configs, diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index ba54f98..c0551f7 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -307,7 +307,7 @@ bool cmGlobalVisualStudio8Generator::ComputeTargetDepends() } void cmGlobalVisualStudio8Generator::WriteProjectDepends( - std::ostream& fout, const std::string&, const char*, + std::ostream& fout, const std::string&, const std::string&, cmGeneratorTarget const* gt) { TargetDependSet const& unordered = this->GetTargetDirectDepends(gt); diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index 352bc3c..8f8e33b 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -74,7 +74,7 @@ protected: const std::string& platformMapping = "") override; bool ComputeTargetDepends() override; void WriteProjectDepends(std::ostream& fout, const std::string& name, - const char* path, + const std::string& path, const cmGeneratorTarget* t) override; bool UseFolderProperty() const override; diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index be5cfd4..012a77c 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -308,7 +308,7 @@ void cmGlobalVisualStudioGenerator::CallVisualStudioMacro( if (!dir.empty()) { std::string macrosFile = dir + "/CMakeMacros/" CMAKE_VSMACROS_FILENAME; std::string nextSubkeyName; - if (cmSystemTools::FileExists(macrosFile.c_str()) && + if (cmSystemTools::FileExists(macrosFile) && IsVisualStudioMacrosFileRegistered( macrosFile, this->GetUserMacrosRegKeyBase(), nextSubkeyName)) { if (m == MacroReload) { @@ -593,7 +593,7 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile, std::string filepath; std::string filepathname; std::string filepathpath; - if (cmSystemTools::FileExists(fullname.c_str())) { + if (cmSystemTools::FileExists(fullname)) { filename = cmSystemTools::GetFilenameName(fullname); filepath = cmSystemTools::GetFilenamePath(fullname); filepathname = cmSystemTools::GetFilenameName(filepath); @@ -917,7 +917,7 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand( std::string objFile = it; // replace $(ConfigurationName) in the object names cmSystemTools::ReplaceString(objFile, this->GetCMakeCFGIntDir(), - configName.c_str()); + configName); if (cmHasLiteralSuffix(objFile, ".obj")) { fout << objFile << "\n"; } diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index da56f3f..3d5c9c4 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -528,7 +528,8 @@ void cmGlobalXCodeGenerator::AddExtraTargets( root->GetMakefile()->IsOn("CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY"); bool isTopLevel = !root->GetStateSnapshot().GetBuildsystemDirectoryParent().IsValid(); - if (regenerate && (isTopLevel || !generateTopLevelProjectOnly)) { + bool isGenerateProject = isTopLevel || !generateTopLevelProjectOnly; + if (regenerate && isGenerateProject) { this->CreateReRunCMakeFile(root, gens); std::string file = this->ConvertToRelativeForMake(this->CurrentReRunCMakeMakefile); @@ -558,7 +559,8 @@ void cmGlobalXCodeGenerator::AddExtraTargets( // run the depend check makefile as a post build rule // this will make sure that when the next target is built // things are up-to-date - if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) { + if (isGenerateProject && + target->GetType() == cmStateEnums::OBJECT_LIBRARY) { commandLines.front().back() = // fill placeholder this->PostBuildMakeTarget(target->GetName(), "$(CONFIGURATION)"); gen->AddCustomCommandToTarget( diff --git a/Source/cmIncludeExternalMSProjectCommand.cxx b/Source/cmIncludeExternalMSProjectCommand.cxx index e59c428..86a0921 100644 --- a/Source/cmIncludeExternalMSProjectCommand.cxx +++ b/Source/cmIncludeExternalMSProjectCommand.cxx @@ -77,8 +77,8 @@ bool cmIncludeExternalMSProjectCommand(std::vector<std::string> const& args, if (!customGuid.empty()) { std::string guidVariable = utility_name + "_GUID_CMAKE"; - mf.GetCMakeInstance()->AddCacheEntry(guidVariable.c_str(), - customGuid.c_str(), "Stored GUID", + mf.GetCMakeInstance()->AddCacheEntry(guidVariable, customGuid.c_str(), + "Stored GUID", cmStateEnums::INTERNAL); } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 261413a..cf6802d 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2749,11 +2749,11 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags( } void cmLocalGenerator::AppendCompileOptions(std::string& options, - const char* options_list, + std::string const& options_list, const char* regex) const { // Short-circuit if there are no options. - if (!options_list) { + if (options_list.empty()) { return; } @@ -2807,11 +2807,11 @@ void cmLocalGenerator::AppendCompileOptions( } void cmLocalGenerator::AppendIncludeDirectories( - std::vector<std::string>& includes, const char* includes_list, + std::vector<std::string>& includes, const std::string& includes_list, const cmSourceFile& sourceFile) const { // Short-circuit if there are no includes. - if (!includes_list) { + if (includes_list.empty()) { return; } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index b91d5f7..88194b7 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -167,15 +167,8 @@ public: * Process a list of include directories */ void AppendIncludeDirectories(std::vector<std::string>& includes, - const char* includes_list, - const cmSourceFile& sourceFile) const; - void AppendIncludeDirectories(std::vector<std::string>& includes, std::string const& includes_list, - const cmSourceFile& sourceFile) const - { - this->AppendIncludeDirectories(includes, includes_list.c_str(), - sourceFile); - } + const cmSourceFile& sourceFile) const; void AppendIncludeDirectories(std::vector<std::string>& includes, const std::vector<std::string>& includes_vec, const cmSourceFile& sourceFile) const; @@ -195,14 +188,9 @@ public: * Encode a list of compile options for the compiler * command line. */ - void AppendCompileOptions(std::string& options, const char* options_list, - const char* regex = nullptr) const; void AppendCompileOptions(std::string& options, std::string const& options_list, - const char* regex = nullptr) const - { - this->AppendCompileOptions(options, options_list.c_str(), regex); - } + const char* regex = nullptr) const; void AppendCompileOptions(std::string& options, const std::vector<std::string>& options_vec, const char* regex = nullptr) const; diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 1420f7c..d037b93 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -1972,18 +1972,18 @@ void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os) } void cmLocalUnixMakefileGenerator3::WriteCMakeArgument(std::ostream& os, - const char* s) + const std::string& s) { // Write the given string to the stream with escaping to get it back // into CMake through the lexical scanner. os << "\""; - for (const char* c = s; *c; ++c) { - if (*c == '\\') { + for (char c : s) { + if (c == '\\') { os << "\\\\"; - } else if (*c == '"') { + } else if (c == '"') { os << "\\\""; } else { - os << *c; + os << c; } } os << "\""; diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index 1629e63..68eeb29 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -77,7 +77,7 @@ public: void SetBorlandMakeCurlyHack(bool b) { this->BorlandMakeCurlyHack = b; } // used in writing out Cmake files such as WriteDirectoryInformation - static void WriteCMakeArgument(std::ostream& os, const char* s); + static void WriteCMakeArgument(std::ostream& os, const std::string& s); /** creates the common disclaimer text at the top of each makefile */ void WriteDisclaimer(std::ostream& os); diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx index 6f456c6..02e2c6d 100644 --- a/Source/cmLocalVisualStudio10Generator.cxx +++ b/Source/cmLocalVisualStudio10Generator.cxx @@ -128,8 +128,7 @@ void cmLocalVisualStudio10Generator::ReadAndStoreExternalGUID( std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE"); // save the GUID in the cache this->GlobalGenerator->GetCMakeInstance()->AddCacheEntry( - guidStoreName.c_str(), parser.GUID.c_str(), "Stored GUID", - cmStateEnums::INTERNAL); + guidStoreName, parser.GUID.c_str(), "Stored GUID", cmStateEnums::INTERNAL); } const char* cmLocalVisualStudio10Generator::ReportErrorLabel() const diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index e43ee8a..b2e59bd 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -7,7 +7,6 @@ #include <algorithm> #include <cassert> #include <cctype> -#include <cstdint> #include <cstdio> #include <cstdlib> #include <cstring> @@ -334,7 +333,7 @@ void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const Json::StreamWriterBuilder builder; builder["indentation"] = ""; val["file"] = full_path; - val["line"] = static_cast<std::int64_t>(lff.Line); + val["line"] = static_cast<Json::Value::Int64>(lff.Line); val["cmd"] = lff.Name.Original; val["args"] = Json::Value(Json::arrayValue); for (std::string const& arg : args) { @@ -342,7 +341,7 @@ void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const } val["time"] = cmSystemTools::GetTime(); val["frame"] = - static_cast<std::uint64_t>(this->ExecutionStatusStack.size()); + static_cast<Json::Value::UInt64>(this->ExecutionStatusStack.size()); msg << Json::writeString(builder, val); #endif break; diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 9e9c2b8..f1a68c2 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -135,7 +135,7 @@ public: std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker(); /** - * Try running cmake and building a file. This is used for dynalically + * Try running cmake and building a file. This is used for dynamically * loaded commands, not as part of the usual build process. */ int TryCompile(const std::string& srcdir, const std::string& bindir, @@ -419,9 +419,9 @@ public: { this->ComplainFileRegularExpression = regex; } - const char* GetComplainRegularExpression() const + const std::string& GetComplainRegularExpression() const { - return this->ComplainFileRegularExpression.c_str(); + return this->ComplainFileRegularExpression; } // -- List of targets diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index acd85a0..0493c0f 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -1171,13 +1171,51 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() } } + std::vector<std::string> dependencies( + this->AutogenTarget.DependFiles.begin(), + this->AutogenTarget.DependFiles.end()); + + const bool useNinjaDepfile = this->QtVersion >= IntegerVersion(5, 15) && + this->GlobalGen->GetName().find("Ninja") != std::string::npos; + if (useNinjaDepfile) { + // Create a custom command that generates a timestamp file and + // has a depfile assigned. The depfile is created by JobDepFilesMergeT. + + // Add additional autogen target dependencies + for (const cmTarget* t : this->AutogenTarget.DependTargets) { + dependencies.push_back(t->GetName()); + } + const char timestampFileName[] = "timestamp"; + const std::string outputFile = + cmStrCat(this->Dir.Build, "/", timestampFileName); + this->AutogenTarget.DepFile = cmStrCat(this->Dir.Build, "/deps"); + this->AutogenTarget.DepFileRuleName = + cmStrCat(this->GenTarget->GetName(), "_autogen/", timestampFileName); + commandLines.push_back(cmMakeCommandLine( + { cmSystemTools::GetCMakeCommand(), "-E", "touch", outputFile })); + + this->AddGeneratedSource(outputFile, this->Moc); + const std::string no_main_dependency; + this->LocalGen->AddCustomCommandToOutput( + outputFile, dependencies, no_main_dependency, commandLines, + autogenComment.c_str(), this->Dir.Work.c_str(), /*replace=*/false, + /*escapeOldStyle=*/false, + /*uses_terminal=*/false, + /*command_expand_lists=*/false, this->AutogenTarget.DepFile); + + // Alter variables for the autogen target which now merely wraps the + // custom command + dependencies.clear(); + dependencies.push_back(outputFile); + commandLines.clear(); + autogenComment.clear(); + } + // Create autogen target cmTarget* autogenTarget = this->LocalGen->AddUtilityCommand( this->AutogenTarget.Name, true, this->Dir.Work.c_str(), /*byproducts=*/autogenProvides, - std::vector<std::string>(this->AutogenTarget.DependFiles.begin(), - this->AutogenTarget.DependFiles.end()), - commandLines, false, autogenComment.c_str()); + /*depends=*/dependencies, commandLines, false, autogenComment.c_str()); // Create autogen generator target this->LocalGen->AddGeneratorTarget( cm::make_unique<cmGeneratorTarget>(autogenTarget, this->LocalGen)); @@ -1188,9 +1226,11 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() autogenTarget->AddUtility(depName.Value, this->Makefile); } } - // Add additional autogen target dependencies to autogen target - for (cmTarget* depTarget : this->AutogenTarget.DependTargets) { - autogenTarget->AddUtility(depTarget->GetName(), this->Makefile); + if (!useNinjaDepfile) { + // Add additional autogen target dependencies to autogen target + for (cmTarget* depTarget : this->AutogenTarget.DependTargets) { + autogenTarget->AddUtility(depTarget->GetName(), this->Makefile); + } } // Set FOLDER property in autogen target @@ -1408,12 +1448,15 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() info.SetConfig("INCLUDE_DIR", this->Dir.Include); info.SetUInt("QT_VERSION_MAJOR", this->QtVersion.Major); + info.SetUInt("QT_VERSION_MINOR", this->QtVersion.Minor); info.Set("QT_MOC_EXECUTABLE", this->Moc.Executable); info.Set("QT_UIC_EXECUTABLE", this->Uic.Executable); info.Set("CMAKE_EXECUTABLE", cmSystemTools::GetCMakeCommand()); info.SetConfig("SETTINGS_FILE", this->AutogenTarget.SettingsFile); info.SetConfig("PARSE_CACHE_FILE", this->AutogenTarget.ParseCacheFile); + info.Set("DEP_FILE", this->AutogenTarget.DepFile); + info.Set("DEP_FILE_RULE_NAME", this->AutogenTarget.DepFileRuleName); info.SetArray("HEADER_EXTENSIONS", this->Makefile->GetCMakeInstance()->GetHeaderExtensions()); info.SetArrayArray( diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index 8cedf14..48ec1a0 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -191,6 +191,8 @@ private: bool DependOrigin = false; std::set<std::string> DependFiles; std::set<cmTarget*> DependTargets; + std::string DepFile; + std::string DepFileRuleName; // Sources to process std::unordered_map<cmSourceFile*, MUFileHandle> Headers; std::unordered_map<cmSourceFile*, MUFileHandle> Sources; diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx index fa5129d..893bd6b 100644 --- a/Source/cmQtAutoMocUic.cxx +++ b/Source/cmQtAutoMocUic.cxx @@ -25,6 +25,8 @@ #include "cmCryptoHash.h" #include "cmFileTime.h" +#include "cmGccDepfileReader.h" +#include "cmGccDepfileReaderTypes.h" #include "cmGeneratedFileStream.h" #include "cmQtAutoGen.h" #include "cmQtAutoGenerator.h" @@ -170,7 +172,7 @@ public: // -- Attributes // - Config bool MultiConfig = false; - unsigned int QtVersionMajor = 4; + IntegerVersion QtVersion = { 4, 0 }; unsigned int ThreadCount = 0; // - Directories std::string AutogenBuildDir; @@ -179,6 +181,8 @@ public: std::string CMakeExecutable; cmFileTime CMakeExecutableTime; std::string ParseCacheFile; + std::string DepFile; + std::string DepFileRuleName; std::vector<std::string> HeaderExtensions; }; @@ -216,6 +220,7 @@ public: bool SettingsChanged = false; bool RelaxedMode = false; bool PathPrefix = false; + bool CanOutputDependencies = false; cmFileTime ExecutableTime; std::string Executable; std::string CompFileAbs; @@ -485,8 +490,17 @@ public: class JobCompileMocT : public JobCompileT { public: - using JobCompileT::JobCompileT; + JobCompileMocT(MappingHandleT uicMapping, + std::unique_ptr<std::string> reason, + ParseCacheT::FileHandleT cacheEntry) + : JobCompileT(std::move(uicMapping), std::move(reason)) + , CacheEntry(std::move(cacheEntry)) + { + } void Process() override; + + protected: + ParseCacheT::FileHandleT CacheEntry; }; /** uic compiles a file. */ @@ -504,6 +518,12 @@ public: void Process() override; }; + class JobDepFilesMergeT : public JobFenceT + { + private: + void Process() override; + }; + /** @brief The last job. */ class JobFinishT : public JobFenceT { @@ -546,6 +566,9 @@ private: void Abort(bool error); // -- Generation bool CreateDirectories(); + // -- Support for depfiles + static std::vector<std::string> dependenciesFromDepFile( + const char* filePath); private: // -- Settings @@ -951,7 +974,7 @@ void cmQtAutoMocUicT::JobParseT::MocMacro() void cmQtAutoMocUicT::JobParseT::MocDependecies() { - if (MocConst().DependFilters.empty()) { + if (MocConst().DependFilters.empty() || MocConst().CanOutputDependencies) { return; } @@ -1674,8 +1697,13 @@ bool cmQtAutoMocUicT::JobProbeDepsMocT::Generate(MappingHandleT const& mapping, if (Probe(*mapping, reason.get())) { // Register the parent directory for creation MocEval().OutputDirs.emplace(cmQtAutoGen::ParentDir(mapping->OutputFile)); + // Fetch the cache entry for the source file + std::string const& sourceFile = mapping->SourceFile->FileName; + ParseCacheT::GetOrInsertT cacheEntry = + BaseEval().ParseCache.GetOrInsert(sourceFile); // Add moc job - Gen()->WorkerPool().EmplaceJob<JobCompileMocT>(mapping, std::move(reason)); + Gen()->WorkerPool().EmplaceJob<JobCompileMocT>( + mapping, std::move(reason), std::move(cacheEntry.first)); // Check if a moc job for a mocs_compilation.cpp entry was generated if (compFile) { MocEval().CompUpdated = true; @@ -1779,6 +1807,14 @@ cmQtAutoMocUicT::JobProbeDepsMocT::FindDependency( std::string const& sourceDir, std::string const& includeString) const { using ResPair = std::pair<std::string, cmFileTime>; + // moc's dependency file contains absolute paths + if (MocConst().CanOutputDependencies) { + ResPair res{ includeString, {} }; + if (res.second.Load(res.first)) { + return res; + } + return {}; + } // Search in vicinity of the source { ResPair res{ sourceDir + includeString, {} }; @@ -1898,6 +1934,11 @@ void cmQtAutoMocUicT::JobProbeDepsFinishT::Process() Gen()->WorkerPool().EmplaceJob<JobMocsCompilationT>(); } + if (!BaseConst().DepFile.empty()) { + // Add job to merge dep files + Gen()->WorkerPool().EmplaceJob<JobDepFilesMergeT>(); + } + // Add finish job Gen()->WorkerPool().EmplaceJob<JobFinishT>(); } @@ -1947,6 +1988,9 @@ void cmQtAutoMocUicT::JobCompileMocT::Process() } // Add extra options cm::append(cmd, MocConst().OptionsExtra); + if (MocConst().CanOutputDependencies) { + cmd.emplace_back("--output-dep-file"); + } // Add output file cmd.emplace_back("-o"); cmd.push_back(outputFile); @@ -1956,12 +2000,7 @@ void cmQtAutoMocUicT::JobCompileMocT::Process() // Execute moc command cmWorkerPool::ProcessResultT result; - if (RunProcess(GenT::MOC, result, cmd, Reason.get())) { - // Moc command success. Print moc output. - if (!result.StdOut.empty()) { - Log().Info(GenT::MOC, result.StdOut); - } - } else { + if (!RunProcess(GenT::MOC, result, cmd, Reason.get())) { // Moc command failed std::string includers; if (!Mapping->IncluderFiles.empty()) { @@ -1976,6 +2015,28 @@ void cmQtAutoMocUicT::JobCompileMocT::Process() MessagePath(outputFile), '\n', includers, result.ErrorMessage), cmd, result.StdOut); + return; + } + + // Moc command success. Print moc output. + if (!result.StdOut.empty()) { + Log().Info(GenT::MOC, result.StdOut); + } + + // Extract dependencies from the dep file moc generated for us + if (MocConst().CanOutputDependencies) { + const std::string depfile = outputFile + ".d"; + if (Log().Verbose()) { + Log().Info(GenT::MOC, + "Reading dependencies from " + MessagePath(depfile)); + } + if (!cmSystemTools::FileExists(depfile)) { + Log().Warning(GenT::MOC, + "Dependency file " + MessagePath(depfile) + + " does not exist."); + return; + } + CacheEntry->Moc.Depends = dependenciesFromDepFile(depfile.c_str()); } } @@ -1992,7 +2053,7 @@ void cmQtAutoMocUicT::JobCompileUicT::Process() auto optionIt = UicConst().UiFiles.find(sourceFile); if (optionIt != UicConst().UiFiles.end()) { UicMergeOptions(allOpts, optionIt->second.Options, - (BaseConst().QtVersionMajor == 5)); + (BaseConst().QtVersion.Major == 5)); } cm::append(cmd, allOpts); } @@ -2067,6 +2128,106 @@ void cmQtAutoMocUicT::JobMocsCompilationT::Process() } } +/* + * Escapes paths for Ninja depfiles. + * This is a re-implementation of what moc does when writing depfiles. + */ +std::string escapeDependencyPath(cm::string_view path) +{ + std::string escapedPath; + escapedPath.reserve(path.size()); + const size_t s = path.size(); + int backslashCount = 0; + for (size_t i = 0; i < s; ++i) { + if (path[i] == '\\') { + ++backslashCount; + } else { + if (path[i] == '$') { + escapedPath.push_back('$'); + } else if (path[i] == '#') { + escapedPath.push_back('\\'); + } else if (path[i] == ' ') { + // Double the amount of written backslashes, + // and add one more to escape the space. + while (backslashCount-- >= 0) { + escapedPath.push_back('\\'); + } + } + backslashCount = 0; + } + escapedPath.push_back(path[i]); + } + return escapedPath; +} + +void cmQtAutoMocUicT::JobDepFilesMergeT::Process() +{ + if (Log().Verbose()) { + Log().Info(GenT::MOC, "Merging MOC dependencies"); + } + auto processDepFile = + [](const std::string& mocOutputFile) -> std::vector<std::string> { + std::string f = mocOutputFile + ".d"; + if (!cmSystemTools::FileExists(f)) { + return {}; + } + return dependenciesFromDepFile(f.c_str()); + }; + + std::vector<std::string> dependencies; + ParseCacheT& parseCache = BaseEval().ParseCache; + auto processMappingEntry = [&](const MappingMapT::value_type& m) { + auto cacheEntry = parseCache.GetOrInsert(m.first); + if (cacheEntry.first->Moc.Depends.empty()) { + cacheEntry.first->Moc.Depends = processDepFile(m.second->OutputFile); + } + dependencies.insert(dependencies.end(), + cacheEntry.first->Moc.Depends.begin(), + cacheEntry.first->Moc.Depends.end()); + }; + + std::for_each(MocEval().HeaderMappings.begin(), + MocEval().HeaderMappings.end(), processMappingEntry); + std::for_each(MocEval().SourceMappings.begin(), + MocEval().SourceMappings.end(), processMappingEntry); + + // Remove duplicates to make the depfile smaller + std::sort(dependencies.begin(), dependencies.end()); + dependencies.erase(std::unique(dependencies.begin(), dependencies.end()), + dependencies.end()); + + // Add form files + for (const auto& uif : UicEval().UiFiles) { + dependencies.push_back(uif.first); + } + + // Write the file + cmsys::ofstream ofs; + ofs.open(BaseConst().DepFile.c_str(), + (std::ios::out | std::ios::binary | std::ios::trunc)); + if (!ofs) { + LogError(GenT::GEN, + cmStrCat("Cannot open ", MessagePath(BaseConst().DepFile), + " for writing.")); + return; + } + ofs << BaseConst().DepFileRuleName << ": \\" << std::endl; + for (const std::string& file : dependencies) { + ofs << '\t' << escapeDependencyPath(file) << " \\" << std::endl; + if (!ofs.good()) { + LogError(GenT::GEN, + cmStrCat("Writing depfile", MessagePath(BaseConst().DepFile), + " failed.")); + return; + } + } + + // Add the CMake executable to re-new cache data if necessary. + // Also, this is the last entry, so don't add a backslash. + ofs << '\t' << escapeDependencyPath(BaseConst().CMakeExecutable) + << std::endl; +} + void cmQtAutoMocUicT::JobFinishT::Process() { Gen()->AbortSuccess(); @@ -2082,7 +2243,8 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info) { // -- Required settings if (!info.GetBool("MULTI_CONFIG", BaseConst_.MultiConfig, true) || - !info.GetUInt("QT_VERSION_MAJOR", BaseConst_.QtVersionMajor, true) || + !info.GetUInt("QT_VERSION_MAJOR", BaseConst_.QtVersion.Major, true) || + !info.GetUInt("QT_VERSION_MINOR", BaseConst_.QtVersion.Minor, true) || !info.GetUInt("PARALLEL", BaseConst_.ThreadCount, false) || !info.GetString("BUILD_DIR", BaseConst_.AutogenBuildDir, true) || !info.GetStringConfig("INCLUDE_DIR", BaseConst_.AutogenIncludeDir, @@ -2090,6 +2252,9 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info) !info.GetString("CMAKE_EXECUTABLE", BaseConst_.CMakeExecutable, true) || !info.GetStringConfig("PARSE_CACHE_FILE", BaseConst_.ParseCacheFile, true) || + !info.GetString("DEP_FILE", BaseConst_.DepFile, false) || + !info.GetString("DEP_FILE_RULE_NAME", BaseConst_.DepFileRuleName, + false) || !info.GetStringConfig("SETTINGS_FILE", SettingsFile_, true) || !info.GetArray("HEADER_EXTENSIONS", BaseConst_.HeaderExtensions, true) || !info.GetString("QT_MOC_EXECUTABLE", MocConst_.Executable, false) || @@ -2143,8 +2308,10 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info) MocConst_.MacroFilters.emplace_back( item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]")); } - // Dependency filters - { + // Can moc output dependencies or do we need to setup dependency filters? + if (BaseConst_.QtVersion >= IntegerVersion(5, 15)) { + MocConst_.CanOutputDependencies = true; + } else { Json::Value const& val = info.GetValue("MOC_DEPEND_FILTERS"); if (!val.isArray()) { return info.LogError("MOC_DEPEND_FILTERS JSON value is not an array."); @@ -2660,6 +2827,19 @@ bool cmQtAutoMocUicT::CreateDirectories() return true; } +std::vector<std::string> cmQtAutoMocUicT::dependenciesFromDepFile( + const char* filePath) +{ + cmGccDepfileContent content = cmReadGccDepfile(filePath); + if (content.empty()) { + return {}; + } + + // Moc outputs a depfile with exactly one rule. + // Discard the rule and return the dependencies. + return content.front().paths; +} + void cmQtAutoMocUicT::Abort(bool error) { if (error) { diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index b69d4e8..a0c217b 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -39,13 +39,13 @@ #include "cmake.h" template <> -const char* cmTargetPropertyComputer::ComputeLocationForBuild<cmTarget>( +const std::string& cmTargetPropertyComputer::ComputeLocationForBuild<cmTarget>( cmTarget const* tgt) { static std::string loc; if (tgt->IsImported()) { loc = tgt->ImportedGetFullPath("", cmStateEnums::RuntimeBinaryArtifact); - return loc.c_str(); + return loc; } cmGlobalGenerator* gg = tgt->GetGlobalGenerator(); @@ -54,18 +54,18 @@ const char* cmTargetPropertyComputer::ComputeLocationForBuild<cmTarget>( } cmGeneratorTarget* gt = gg->FindGeneratorTarget(tgt->GetName()); loc = gt->GetLocationForBuild(); - return loc.c_str(); + return loc; } template <> -const char* cmTargetPropertyComputer::ComputeLocation<cmTarget>( +const std::string& cmTargetPropertyComputer::ComputeLocation<cmTarget>( cmTarget const* tgt, const std::string& config) { static std::string loc; if (tgt->IsImported()) { loc = tgt->ImportedGetFullPath(config, cmStateEnums::RuntimeBinaryArtifact); - return loc.c_str(); + return loc; } cmGlobalGenerator* gg = tgt->GetGlobalGenerator(); @@ -74,7 +74,7 @@ const char* cmTargetPropertyComputer::ComputeLocation<cmTarget>( } cmGeneratorTarget* gt = gg->FindGeneratorTarget(tgt->GetName()); loc = gt->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact); - return loc.c_str(); + return loc; } template <> diff --git a/Source/cmTargetPropertyComputer.h b/Source/cmTargetPropertyComputer.h index 3b11acd..df34f18 100644 --- a/Source/cmTargetPropertyComputer.h +++ b/Source/cmTargetPropertyComputer.h @@ -46,10 +46,10 @@ private: cmListFileBacktrace const& context); template <typename Target> - static const char* ComputeLocationForBuild(Target const* tgt); + static const std::string& ComputeLocationForBuild(Target const* tgt); template <typename Target> - static const char* ComputeLocation(Target const* tgt, - std::string const& config); + static const std::string& ComputeLocation(Target const* tgt, + std::string const& config); template <typename Target> static const char* GetLocation(Target const* tgt, std::string const& prop, @@ -71,7 +71,7 @@ private: context)) { return nullptr; } - return ComputeLocationForBuild(tgt); + return ComputeLocationForBuild(tgt).c_str(); } // Support "LOCATION_<CONFIG>". @@ -82,7 +82,7 @@ private: return nullptr; } std::string configName = prop.substr(9); - return ComputeLocation(tgt, configName); + return ComputeLocation(tgt, configName).c_str(); } // Support "<CONFIG>_LOCATION". @@ -95,7 +95,7 @@ private: context)) { return nullptr; } - return ComputeLocation(tgt, configName); + return ComputeLocation(tgt, configName).c_str(); } } } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 5ef5597..8264b80 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1455,6 +1455,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( std::string comment = lg->ConstructComment(ccg); comment = cmVS10EscapeComment(comment); std::string script = lg->ConstructScript(ccg); + bool symbolic = false; // input files for custom command std::stringstream additional_inputs; { @@ -1481,6 +1482,12 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( ConvertToWindowsSlash(dep); additional_inputs << sep << dep; sep = ";"; + if (!symbolic) { + if (cmSourceFile* sf = this->Makefile->GetSource( + dep, cmSourceFileLocationKind::Known)) { + symbolic = sf->GetPropertyAsBool("SYMBOLIC"); + } + } } } if (this->ProjectType != csproj) { @@ -1489,7 +1496,6 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( } // output files for custom command std::stringstream outputs; - bool symbolic = false; { const char* sep = ""; for (std::string const& o : ccg.GetOutputs()) { diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 721d535..5fa40d5 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -389,7 +389,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) } } cmsys::RegularExpression regex( - cmsys::Glob::PatternToRegex(entryPattern, true, true).c_str()); + cmsys::Glob::PatternToRegex(entryPattern, true, true)); // go through all cache entries and collect the vars which will be // removed std::vector<std::string> entriesToDelete; @@ -663,6 +663,8 @@ void cmake::SetArgs(const std::vector<std::string>& args) } else if ((i < args.size() - 1) && (arg.find("--check-stamp-list", 0) == 0)) { this->CheckStampList = args[++i]; + } else if (arg == "--regenerate-during-build") { + this->RegenerateDuringBuild = true; } #if defined(CMAKE_HAVE_VS_GENERATORS) else if ((i < args.size() - 1) && diff --git a/Source/cmake.h b/Source/cmake.h index c65b821..35425ec 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -547,6 +547,8 @@ public: } cmStateSnapshot GetCurrentSnapshot() const { return this->CurrentSnapshot; } + bool GetRegenerateDuringBuild() const { return this->RegenerateDuringBuild; } + protected: void RunCheckForUnusedVariables(); int HandleDeleteCacheVariables(const std::string& var); @@ -621,6 +623,7 @@ private: FileExtensions FortranFileExtensions; bool ClearBuildSystem = false; bool DebugTryCompile = false; + bool RegenerateDuringBuild = false; std::unique_ptr<cmFileTimeCache> FileTimeCache; std::string GraphVizFile; InstalledFilesMap InstalledFiles; diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt index 25d2de6..bb50d76 100644 --- a/Tests/CMakeLib/CMakeLists.txt +++ b/Tests/CMakeLib/CMakeLists.txt @@ -11,6 +11,7 @@ set(CMakeLib_TESTS testCTestResourceAllocator.cxx testCTestResourceSpec.cxx testCTestResourceGroups.cxx + testGccDepfileReader.cxx testGeneratedFileStream.cxx testRST.cxx testRange.cxx @@ -35,6 +36,7 @@ set(testRST_ARGS ${CMAKE_CURRENT_SOURCE_DIR}) set(testUVProcessChain_ARGS $<TARGET_FILE:testUVProcessChainHelper>) set(testUVStreambuf_ARGS $<TARGET_FILE:cmake>) set(testCTestResourceSpec_ARGS ${CMAKE_CURRENT_SOURCE_DIR}) +set(testGccDepfileReader_ARGS ${CMAKE_CURRENT_SOURCE_DIR}) if(WIN32) list(APPEND CMakeLib_TESTS diff --git a/Tests/CMakeLib/testGccDepfileReader.cxx b/Tests/CMakeLib/testGccDepfileReader.cxx new file mode 100644 index 0000000..924d87b --- /dev/null +++ b/Tests/CMakeLib/testGccDepfileReader.cxx @@ -0,0 +1,131 @@ +#include <cstddef> +#include <iostream> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "cmsys/FStream.hxx" + +#include "cmGccDepfileReader.h" +#include "cmGccDepfileReaderTypes.h" // for cmGccDepfileContent, cmGccStyle... +#include "cmSystemTools.h" + +namespace { + +cmGccDepfileContent readPlainDepfile(const char* filePath) +{ + cmGccDepfileContent result; + cmsys::ifstream is(filePath); + if (!is.is_open()) + return result; + std::string line; + + cmGccStyleDependency dep; + bool readingRules = true; + while (cmSystemTools::GetLineFromStream(is, line)) { + if (line == "--RULES--") { + if (!dep.rules.empty()) { + result.push_back(std::move(dep)); + dep = cmGccStyleDependency(); + } + readingRules = true; + } else if (line == "--DEPENDENCIES--") { + readingRules = false; + } else { + std::vector<std::string>& dst = readingRules ? dep.rules : dep.paths; + dst.push_back(std::move(line)); + line = std::string(); + } + } + + if (!dep.rules.empty()) { + result.push_back(std::move(dep)); + } + + return result; +} + +bool compare(const std::vector<std::string>& actual, + const std::vector<std::string>& expected, const char* msg) +{ + if (actual.size() != expected.size()) { + std::cerr << msg << "expected " << expected.size() << " entries." + << std::endl + << "Actual number of entries: " << actual.size() << std::endl; + return false; + } + for (std::size_t i = 0; i < actual.size(); ++i) { + if (actual[i] != expected[i]) { + std::cerr << msg << std::endl + << "expected: " << expected[i] << std::endl + << "actual: " << actual[i] << std::endl; + return false; + } + } + return true; +} + +bool compare(const cmGccDepfileContent& actual, + const cmGccDepfileContent& expected) +{ + if (actual.size() != expected.size()) { + std::cerr << "Expected " << expected.size() << " entries." << std::endl + << "Actual number of entries: " << actual.size() << std::endl; + return false; + } + for (std::size_t i = 0; i < actual.size(); ++i) { + if (!compare(actual[i].rules, expected[i].rules, "Rules differ: ") || + !compare(actual[i].paths, expected[i].paths, "Paths differ: ")) { + return false; + } + } + return true; +} + +void dump(const char* label, const cmGccDepfileContent& dfc) +{ + std::cerr << label << std::endl; + for (const auto& entry : dfc) { + auto rit = entry.rules.cbegin(); + if (rit != entry.rules.cend()) { + std::cerr << *rit; + for (++rit; rit != entry.rules.cend(); ++rit) { + std::cerr << " " << *rit; + } + std::cerr << ": " << std::endl; + } + for (const auto& path : entry.paths) { + std::cerr << " " << path << std::endl; + } + } +} + +} // anonymous namespace + +int testGccDepfileReader(int argc, char* argv[]) +{ + if (argc < 2) { + std::cout << "Invalid arguments.\n"; + return -1; + } + + std::string dataDirPath = argv[1]; + dataDirPath += "/testGccDepfileReader_data"; + const int numberOfTestFiles = 3; + for (int i = 1; i <= numberOfTestFiles; ++i) { + const std::string base = dataDirPath + "/deps" + std::to_string(i); + const std::string depfile = base + ".d"; + const std::string plainDepfile = base + ".txt"; + std::cout << "Comparing " << base << " with " << plainDepfile << std::endl; + const auto actual = cmReadGccDepfile(depfile.c_str()); + const auto expected = readPlainDepfile(plainDepfile.c_str()); + if (!compare(actual, expected)) { + dump("actual", actual); + dump("expected", expected); + return 1; + } + } + + return 0; +} diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps1.d b/Tests/CMakeLib/testGccDepfileReader_data/deps1.d new file mode 100644 index 0000000..9e34863 --- /dev/null +++ b/Tests/CMakeLib/testGccDepfileReader_data/deps1.d @@ -0,0 +1,20 @@ +main.o: main.cpp /usr/include/stdc-predef.h /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/8/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps1.txt b/Tests/CMakeLib/testGccDepfileReader_data/deps1.txt new file mode 100644 index 0000000..fd2679f --- /dev/null +++ b/Tests/CMakeLib/testGccDepfileReader_data/deps1.txt @@ -0,0 +1,26 @@ +--RULES-- +main.o +--DEPENDENCIES-- +main.cpp +/usr/include/stdc-predef.h +/usr/include/stdio.h +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h +/usr/include/features.h +/usr/include/x86_64-linux-gnu/sys/cdefs.h +/usr/include/x86_64-linux-gnu/bits/wordsize.h +/usr/include/x86_64-linux-gnu/bits/long-double.h +/usr/include/x86_64-linux-gnu/gnu/stubs.h +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h +/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h +/usr/lib/gcc/x86_64-linux-gnu/8/include/stdarg.h +/usr/include/x86_64-linux-gnu/bits/types.h +/usr/include/x86_64-linux-gnu/bits/typesizes.h +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h +/usr/include/x86_64-linux-gnu/bits/types/FILE.h +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h +/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps2.d b/Tests/CMakeLib/testGccDepfileReader_data/deps2.d new file mode 100644 index 0000000..25f0d78 --- /dev/null +++ b/Tests/CMakeLib/testGccDepfileReader_data/deps2.d @@ -0,0 +1 @@ +foo.o bar.o: foobar.c diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps2.txt b/Tests/CMakeLib/testGccDepfileReader_data/deps2.txt new file mode 100644 index 0000000..afaf78e --- /dev/null +++ b/Tests/CMakeLib/testGccDepfileReader_data/deps2.txt @@ -0,0 +1,5 @@ +--RULES-- +foo.o +bar.o +--DEPENDENCIES-- +foobar.c diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps3.d b/Tests/CMakeLib/testGccDepfileReader_data/deps3.d new file mode 100644 index 0000000..d75ceed --- /dev/null +++ b/Tests/CMakeLib/testGccDepfileReader_data/deps3.d @@ -0,0 +1,2 @@ +main.o: main.cpp foo\#bar.h foo\\#bar.h foo\ bar.h \ + foo\\\ bar.h foo\\\\\ bar.h foo\\\\ foo$$bar.h diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps3.txt b/Tests/CMakeLib/testGccDepfileReader_data/deps3.txt new file mode 100644 index 0000000..448f69c --- /dev/null +++ b/Tests/CMakeLib/testGccDepfileReader_data/deps3.txt @@ -0,0 +1,11 @@ +--RULES-- +main.o +--DEPENDENCIES-- +main.cpp +foo#bar.h +foo\#bar.h +foo bar.h +foo\ bar.h +foo\\ bar.h +foo\\\\ +foo$bar.h diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleA.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleA.hpp index e1fdf0b..198ae98 100644 --- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleA.hpp +++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleA.hpp @@ -10,7 +10,7 @@ class StyleA : public QStylePlugin Q_OBJECT // Json file in source local directory Q_PLUGIN_METADATA(IID "org.styles.A" FILE "StyleA.json") - A_CUSTOM_MACRO(SomeArg, "StyleA_Custom.json", AnotherArg) + A_CUSTOM_MACRO(org.styles.A, "StyleA_Custom.json", AnotherArg) public: QStyle* create(const QString& key); }; diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleB.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleB.hpp index 7550d0c..8ce8d77 100644 --- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleB.hpp +++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleB.hpp @@ -10,7 +10,7 @@ class StyleB : public QStylePlugin Q_OBJECT // Json file in source local subdirectory Q_PLUGIN_METADATA(IID "org.styles.B" FILE "jsonIn/StyleB.json") - A_CUSTOM_MACRO(SomeArg, "jsonIn/StyleB_Custom.json", AnotherArg) + A_CUSTOM_MACRO(org.styles.B, "jsonIn/StyleB_Custom.json", AnotherArg) public: QStyle* create(const QString& key); }; diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleC.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleC.hpp index ec71bec..53171e3 100644 --- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleC.hpp +++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleC.hpp @@ -10,7 +10,7 @@ class StyleC : public QStylePlugin Q_OBJECT // Json file in global root directory Q_PLUGIN_METADATA(IID "org.styles.C" FILE "StyleC.json") - A_CUSTOM_MACRO(SomeArg, "StyleC_Custom.json", AnotherArg) + A_CUSTOM_MACRO(org.styles.C, "StyleC_Custom.json", AnotherArg) public: QStyle* create(const QString& key); }; diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleD.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleD.hpp index 3c093b9..29674f9 100644 --- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleD.hpp +++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleD.hpp @@ -10,7 +10,7 @@ class StyleD : public QStylePlugin Q_OBJECT // Json file in global sub director Q_PLUGIN_METADATA(IID "org.styles.D" FILE "sub/StyleD.json") - A_CUSTOM_MACRO(SomeArg, "sub/StyleD_Custom.json", AnotherArg) + A_CUSTOM_MACRO(org.styles.D, "sub/StyleD_Custom.json", AnotherArg) public: QStyle* create(const QString& key); }; diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleEInclude.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleEInclude.hpp index 5f10fb4..7318220 100644 --- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleEInclude.hpp +++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleEInclude.hpp @@ -10,7 +10,7 @@ class StyleE : public QStylePlugin Q_OBJECT // Json files in global root directory Q_PLUGIN_METADATA(IID "org.styles.E" FILE "StyleE.json") - A_CUSTOM_MACRO(SomeArg, "StyleE_Custom.json", AnotherArg) + A_CUSTOM_MACRO(org.styles.E, "StyleE_Custom.json", AnotherArg) public: QStyle* create(const QString& key); }; diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/UtilityMacros.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/UtilityMacros.hpp index 53a4284..2f558a8 100644 --- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/UtilityMacros.hpp +++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/UtilityMacros.hpp @@ -1,7 +1,7 @@ #ifndef UTILITYMACROS_HPP #define UTILITYMACROS_HPP -// Empty test macro definition -#define A_CUSTOM_MACRO(name, jsonFile, pluginRegistrations) +#define A_CUSTOM_MACRO(url, jsonFile, pluginRegistrations) \ + Q_PLUGIN_METADATA(IID #url FILE jsonFile) #endif diff --git a/Tests/RunCMake/CMP0037/RunCMakeTest.cmake b/Tests/RunCMake/CMP0037/RunCMakeTest.cmake index 98274f0..5952279 100644 --- a/Tests/RunCMake/CMP0037/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMP0037/RunCMakeTest.cmake @@ -1,5 +1,24 @@ include(RunCMake) +if(RunCMake_GENERATOR MATCHES "^Ninja") + # Detect ninja version so we know what tests can be supported. + execute_process( + COMMAND "${RunCMake_MAKE_PROGRAM}" --version + OUTPUT_VARIABLE ninja_out + ERROR_VARIABLE ninja_out + RESULT_VARIABLE ninja_res + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(ninja_res EQUAL 0 AND "x${ninja_out}" MATCHES "^x[0-9]+\\.[0-9]+") + set(ninja_version "${ninja_out}") + message(STATUS "ninja version: ${ninja_version}") + else() + message(FATAL_ERROR "'ninja --version' reported:\n${ninja_out}") + endif() +else() + set(ninja_version "") +endif() + run_cmake(CMP0037-OLD-space) run_cmake(CMP0037-NEW-space) run_cmake(CMP0037-WARN-space) @@ -9,8 +28,10 @@ if(NOT (WIN32 AND "${RunCMake_GENERATOR}" MATCHES "Make")) run_cmake(CMP0037-WARN-colon) endif() -run_cmake(CMP0037-WARN-reserved) -run_cmake(CMP0037-OLD-reserved) +if(NOT ninja_version VERSION_GREATER_EQUAL 1.10) + run_cmake(CMP0037-WARN-reserved) + run_cmake(CMP0037-OLD-reserved) +endif() run_cmake(CMP0037-NEW-reserved) run_cmake(NEW-cond) diff --git a/Tests/RunCMake/GNUInstallDirs/NoSystem-stderr.txt b/Tests/RunCMake/GNUInstallDirs/NoSystem-stderr.txt new file mode 100644 index 0000000..36f064c --- /dev/null +++ b/Tests/RunCMake/GNUInstallDirs/NoSystem-stderr.txt @@ -0,0 +1,8 @@ +^CMake Warning \(dev\) at .*/Modules/GNUInstallDirs.cmake:[0-9]+ \(message\): + Unable to determine default CMAKE_INSTALL_LIBDIR directory because no + target architecture is known. Please enable at least one language before + including GNUInstallDirs. +Call Stack \(most recent call first\): + NoSystem.cmake:[0-9]+ \(include\) + CMakeLists.txt:[0-9]+ \(include\) +This warning is for project developers. Use -Wno-dev to suppress it.$ diff --git a/Tests/RunCMake/GNUInstallDirs/NoSystem.cmake b/Tests/RunCMake/GNUInstallDirs/NoSystem.cmake new file mode 100644 index 0000000..19cf7be --- /dev/null +++ b/Tests/RunCMake/GNUInstallDirs/NoSystem.cmake @@ -0,0 +1,2 @@ +unset(CMAKE_SYSTEM_NAME) +include(GNUInstallDirs) diff --git a/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake b/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake index d671ee0..eb2c1a2 100644 --- a/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake +++ b/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake @@ -16,4 +16,7 @@ foreach(case ) set(RunCMake-stderr-file ${case}${variant}-stderr.txt) run_cmake(${case}) + unset(RunCMake-stderr-file) endforeach() + +run_cmake(NoSystem) diff --git a/Tests/RunCMake/Ninja/CustomCommandJobPool.cmake b/Tests/RunCMake/Ninja/CustomCommandJobPool.cmake index 1e36e65..a96802a 100644 --- a/Tests/RunCMake/Ninja/CustomCommandJobPool.cmake +++ b/Tests/RunCMake/Ninja/CustomCommandJobPool.cmake @@ -1,3 +1,4 @@ +set_property(GLOBAL PROPERTY JOB_POOLS custom_command_pool=2 custom_target_pool=2) add_custom_command( OUTPUT hello.copy.c COMMAND "${CMAKE_COMMAND}" -E copy diff --git a/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake b/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake index 6a80b1d..3a1c7f5 100644 --- a/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake @@ -11,8 +11,20 @@ target_link_libraries(exe PRIVATE Qt5::Core) include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake) generate_output_files(exe) +set(moc_writes_depfiles 0) +if(Qt5Core_VERSION VERSION_GREATER_EQUAL "5.15.0") + set(moc_writes_depfiles 1) +endif() + set(autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/mocs_compilation.cpp") +if(moc_writes_depfiles) + list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/deps") + list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/timestamp") +endif() foreach(c IN LISTS CMAKE_CONFIGURATION_TYPES) list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/include_${c}/moc_qt5.cpp") + if(moc_writes_depfiles) + list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/include_${c}/moc_qt5.cpp.d") + endif() endforeach() file(APPEND "${CMAKE_BINARY_DIR}/target_files.cmake" "set(AUTOGEN_FILES [==[${autogen_files}]==])\n") diff --git a/Tests/RunCMake/Swift/RunCMakeTest.cmake b/Tests/RunCMake/Swift/RunCMakeTest.cmake index 4817045..918df0b 100644 --- a/Tests/RunCMake/Swift/RunCMakeTest.cmake +++ b/Tests/RunCMake/Swift/RunCMakeTest.cmake @@ -7,6 +7,10 @@ if(RunCMake_GENERATOR STREQUAL Xcode) elseif(RunCMake_GENERATOR STREQUAL Ninja) if(CMAKE_Swift_COMPILER) run_cmake(Win32ExecutableDisallowed) + + set(RunCMake_TEST_OPTIONS -DCMAKE_SYSTEM_NAME=Darwin) + run_cmake(SwiftMultiArch) + unset(RunCMake_TEST_OPTIONS) endif() else() run_cmake(NotSupported) diff --git a/Tests/RunCMake/Swift/SwiftMultiArch-result.txt b/Tests/RunCMake/Swift/SwiftMultiArch-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Swift/SwiftMultiArch-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Swift/SwiftMultiArch-stderr.txt b/Tests/RunCMake/Swift/SwiftMultiArch-stderr.txt new file mode 100644 index 0000000..874bdc7 --- /dev/null +++ b/Tests/RunCMake/Swift/SwiftMultiArch-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at SwiftMultiArch.cmake:3 \(project\): + multiple values for CMAKE_OSX_ARCHITECTURES not supported with Swift +Call Stack \(most recent call first\): + CMakeLists.txt:3 diff --git a/Tests/RunCMake/Swift/SwiftMultiArch.cmake b/Tests/RunCMake/Swift/SwiftMultiArch.cmake new file mode 100644 index 0000000..5fdb688 --- /dev/null +++ b/Tests/RunCMake/Swift/SwiftMultiArch.cmake @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.15.1) +set(CMAKE_OSX_ARCHITECTURES "armv7;arm64;i386;x86_64") +project(SwiftMultiArch + LANGUAGES Swift) diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake index 6ecf3f2..f1dda54 100644 --- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake @@ -8,6 +8,16 @@ run_cmake(XcodeAttributeLocation) run_cmake(XcodeAttributeGenex) run_cmake(XcodeAttributeGenexError) run_cmake(XcodeGenerateTopLevelProjectOnly) + +function(XcodeGenerateTopLevelProjectOnlyWithObjectLibrary) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeGenerateTopLevelProjectOnlyWithObjectLibrary-build) + run_cmake(XcodeGenerateTopLevelProjectOnlyWithObjectLibrary) + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(XcodeGenerateTopLevelProjectOnlyWithObjectLibrary-build ${CMAKE_COMMAND} --build . --target shared_lib) +endfunction() + +XcodeGenerateTopLevelProjectOnlyWithObjectLibrary() + run_cmake(XcodeObjectNeedsEscape) run_cmake(XcodeObjectNeedsQuote) run_cmake(XcodeOptimizationFlags) diff --git a/Tests/RunCMake/XcodeProject/XcodeGenerateTopLevelProjectOnlyWithObjectLibrary.cmake b/Tests/RunCMake/XcodeProject/XcodeGenerateTopLevelProjectOnlyWithObjectLibrary.cmake new file mode 100644 index 0000000..67e4a00 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeGenerateTopLevelProjectOnlyWithObjectLibrary.cmake @@ -0,0 +1,3 @@ +set(CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY TRUE) +project(XcodeGenerateTopLevelProjectOnly NONE) +add_subdirectory(subproject_with_object_lib) diff --git a/Tests/RunCMake/XcodeProject/subproject_with_object_lib/CMakeLists.txt b/Tests/RunCMake/XcodeProject/subproject_with_object_lib/CMakeLists.txt new file mode 100644 index 0000000..ab400f4 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/subproject_with_object_lib/CMakeLists.txt @@ -0,0 +1,7 @@ +project(subproject_with_object_lib) + +add_library(object_lib_dependency OBJECT dummy.cpp) + +add_library(shared_lib SHARED dummy.cpp) +target_sources(shared_lib PRIVATE $<TARGET_OBJECTS:object_lib_dependency>) +set_target_properties(shared_lib PROPERTIES MACOSX_RPATH ON) diff --git a/Tests/RunCMake/XcodeProject/subproject_with_object_lib/dummy.cpp b/Tests/RunCMake/XcodeProject/subproject_with_object_lib/dummy.cpp new file mode 100644 index 0000000..bb4218a --- /dev/null +++ b/Tests/RunCMake/XcodeProject/subproject_with_object_lib/dummy.cpp @@ -0,0 +1,5 @@ +namespace { +void dummy() +{ +} +} diff --git a/Utilities/Scripts/regenerate-lexers.bash b/Utilities/Scripts/regenerate-lexers.bash index 1b61b70..186802a 100755 --- a/Utilities/Scripts/regenerate-lexers.bash +++ b/Utilities/Scripts/regenerate-lexers.bash @@ -14,7 +14,8 @@ for lexer in \ CTestResourceGroups \ DependsJava \ Expr \ - Fortran + Fortran \ + GccDepfile do cxx_file=cm${lexer}Lexer.cxx h_file=cm${lexer}Lexer.h diff --git a/Utilities/cmlibarchive/libarchive/archive_pack_dev.c b/Utilities/cmlibarchive/libarchive/archive_pack_dev.c index 53bddd7..f8286d8 100644 --- a/Utilities/cmlibarchive/libarchive/archive_pack_dev.c +++ b/Utilities/cmlibarchive/libarchive/archive_pack_dev.c @@ -57,8 +57,12 @@ __RCSID("$NetBSD$"); #ifdef HAVE_SYS_STAT_H #include <sys/stat.h> #endif -#ifdef HAVE_SYS_SYSMACROS_H +#if MAJOR_IN_MKDEV +#include <sys/mkdev.h> +#define HAVE_MAJOR +#elif MAJOR_IN_SYSMACROS #include <sys/sysmacros.h> +#define HAVE_MAJOR #endif #ifdef HAVE_UNISTD_H #include <unistd.h> diff --git a/Utilities/std/cm/memory b/Utilities/std/cm/memory index 8ebded2..dd0f822 100644 --- a/Utilities/std/cm/memory +++ b/Utilities/std/cm/memory @@ -8,6 +8,8 @@ #include <memory> // IWYU pragma: export #if !defined(CMake_HAVE_CXX_MAKE_UNIQUE) +# include <cstddef> +# include <type_traits> # include <utility> #endif @@ -19,12 +21,45 @@ using std::make_unique; #else +namespace internals { + +template <typename T> +struct make_unique_if +{ + using single = std::unique_ptr<T>; +}; + +template <typename T> +struct make_unique_if<T[]> +{ + using unbound_array = std::unique_ptr<T[]>; +}; + +template <typename T, std::size_t N> +struct make_unique_if<T[N]> +{ + using bound_array = void; +}; +} + template <typename T, typename... Args> -std::unique_ptr<T> make_unique(Args&&... args) +typename internals::make_unique_if<T>::single make_unique(Args&&... args) { return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); } +template <typename T> +typename internals::make_unique_if<T>::unbound_array make_unique(std::size_t n) +{ + using E = typename std::remove_extent<T>::type; + + return std::unique_ptr<T>(new E[n]()); +} + +template <typename T, typename... Args> +typename internals::make_unique_if<T>::bound_array make_unique(Args&&...) = + delete; + #endif } // namespace cm |