Browse Source

FindFLEX: Add policy CMP0098 to run flex in build tree

Jannick 6 years ago
parent
commit
c5fb36a4cb

+ 8 - 0
Help/manual/cmake-policies.7.rst

@@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
 to determine whether to report an error on use of deprecated macros or
 functions.
 
+Policies Introduced by CMake 3.17
+=================================
+
+.. toctree::
+   :maxdepth: 1
+
+   CMP0098: FindFLEX runs flex in CMAKE_CURRENT_BINARY_DIR when executing. </policy/CMP0098>
+
 Policies Introduced by CMake 3.16
 =================================
 

+ 30 - 0
Help/policy/CMP0098.rst

@@ -0,0 +1,30 @@
+CMP0098
+-------
+
+:module:`FindFLEX` runs ``flex`` in directory
+:variable:`CMAKE_CURRENT_BINARY_DIR` when executing.
+
+The module provides a ``FLEX_TARGET`` macro which generates FLEX output.
+In CMake 3.16 and below the macro would generate a custom command that runs
+``flex`` in the current source directory.  CMake 3.17 and later prefer to
+run it in the build directory and use :variable:`CMAKE_CURRENT_BINARY_DIR`
+as the ``WORKING_DIRECTORY`` of its :command:`add_custom_command` invocation.
+This ensures that any implicitly generated file is written relative to the
+build tree rather than the source tree, unless the generated file is
+provided as absolute path.
+
+This policy provides compatibility for projects that have not been updated
+to expect the new behavior.
+
+The ``OLD`` behavior for this policy is for ``FLEX_TARGET`` to use
+the current source directory for the ``WORKING_DIRECTORY`` and where
+to generate implicit files. The ``NEW`` behavior of this policy is to
+use the current binary directory for the ``WORKING_DIRECTORY`` relative to
+which implicit files are generated unless provided as absolute path.
+
+This policy was introduced in CMake version 3.17.  Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt

+ 6 - 0
Help/release/dev/FindFLEX-work-dir.rst

@@ -0,0 +1,6 @@
+FindFLEX-work-dir
+-----------------
+
+* The :module:`FindFLEX` module's ``FLEX_TARGET`` command now runs ``flex``
+  with :variable:`CMAKE_CURRENT_BINARY_DIR` as the working directory.
+  See policy :policy:`CMP0098`.

+ 54 - 19
Modules/FindFLEX.cmake

@@ -142,8 +142,6 @@ if(FLEX_EXECUTABLE)
   #============================================================
   #
   macro(FLEX_TARGET Name Input Output)
-    set(FLEX_TARGET_outputs "${Output}")
-    set(FLEX_EXECUTABLE_opts "")
 
     set(FLEX_TARGET_PARAM_OPTIONS)
     set(FLEX_TARGET_PARAM_ONE_VALUE_KEYWORDS
@@ -165,31 +163,68 @@ if(FLEX_EXECUTABLE)
     if(NOT "${FLEX_TARGET_ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
       message(SEND_ERROR ${FLEX_TARGET_usage})
     else()
+
+      cmake_policy(GET CMP0098 _flex_CMP0098
+          PARENT_SCOPE # undocumented, do not use outside of CMake
+        )
+      set(_flex_INPUT "${Input}")
+      if("x${_flex_CMP0098}x" STREQUAL "xNEWx")
+        set(_flex_WORKING_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+        if(NOT IS_ABSOLUTE "${_flex_INPUT}")
+          set(_flex_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/${_flex_INPUT}")
+        endif()
+      else()
+        set(_flex_WORKING_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+      endif()
+      unset(_flex_CMP0098)
+
+      set(_flex_OUTPUT "${Output}")
+      if(NOT IS_ABSOLUTE ${_flex_OUTPUT})
+        set(_flex_OUTPUT "${_flex_WORKING_DIR}/${_flex_OUTPUT}")
+      endif()
+      set(_flex_TARGET_OUTPUTS "${_flex_OUTPUT}")
+
+      set(_flex_EXE_OPTS "")
       if(NOT "${FLEX_TARGET_ARG_COMPILE_FLAGS}" STREQUAL "")
-        set(FLEX_EXECUTABLE_opts "${FLEX_TARGET_ARG_COMPILE_FLAGS}")
-        separate_arguments(FLEX_EXECUTABLE_opts)
+        set(_flex_EXE_OPTS "${FLEX_TARGET_ARG_COMPILE_FLAGS}")
+        separate_arguments(_flex_EXE_OPTS)
       endif()
+
+      set(_flex_OUTPUT_HEADER "")
       if(NOT "${FLEX_TARGET_ARG_DEFINES_FILE}" STREQUAL "")
-        list(APPEND FLEX_TARGET_outputs "${FLEX_TARGET_ARG_DEFINES_FILE}")
-        list(APPEND FLEX_EXECUTABLE_opts --header-file=${FLEX_TARGET_ARG_DEFINES_FILE})
+        set(_flex_OUTPUT_HEADER "${FLEX_TARGET_ARG_DEFINES_FILE}")
+        if(IS_ABSOLUTE "${_flex_OUTPUT_HEADER}")
+          set(_flex_OUTPUT_HEADER_ABS "${_flex_OUTPUT_HEADER}")
+        else()
+          set(_flex_OUTPUT_HEADER_ABS "${_flex_WORKING_DIR}/${_flex_OUTPUT_HEADER}")
+        endif()
+        list(APPEND _flex_TARGET_OUTPUTS "${_flex_OUTPUT_HEADER_ABS}")
+        list(APPEND _flex_EXE_OPTS --header-file=${_flex_OUTPUT_HEADER_ABS})
       endif()
 
-      add_custom_command(OUTPUT ${FLEX_TARGET_outputs}
-        COMMAND ${FLEX_EXECUTABLE} ${FLEX_EXECUTABLE_opts} -o${Output} ${Input}
+      get_filename_component(_flex_EXE_NAME_WE "${FLEX_EXECUTABLE}" NAME_WE)
+      add_custom_command(OUTPUT ${_flex_TARGET_OUTPUTS}
+        COMMAND ${FLEX_EXECUTABLE} ${_flex_EXE_OPTS} -o${_flex_OUTPUT} ${_flex_INPUT}
         VERBATIM
-        DEPENDS ${Input}
-        COMMENT "[FLEX][${Name}] Building scanner with flex ${FLEX_VERSION}"
-        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+        DEPENDS ${_flex_INPUT}
+        COMMENT "[FLEX][${Name}] Building scanner with ${_flex_EXE_NAME_WE} ${FLEX_VERSION}"
+        WORKING_DIRECTORY ${_flex_WORKING_DIR})
 
       set(FLEX_${Name}_DEFINED TRUE)
-      set(FLEX_${Name}_OUTPUTS ${Output})
-      set(FLEX_${Name}_INPUT ${Input})
-      set(FLEX_${Name}_COMPILE_FLAGS ${FLEX_EXECUTABLE_opts})
-      if("${FLEX_TARGET_ARG_DEFINES_FILE}" STREQUAL "")
-        set(FLEX_${Name}_OUTPUT_HEADER "")
-      else()
-        set(FLEX_${Name}_OUTPUT_HEADER ${FLEX_TARGET_ARG_DEFINES_FILE})
-      endif()
+      set(FLEX_${Name}_OUTPUTS ${_flex_TARGET_OUTPUTS})
+      set(FLEX_${Name}_INPUT ${_flex_INPUT})
+      set(FLEX_${Name}_COMPILE_FLAGS ${_flex_EXE_OPTS})
+      set(FLEX_${Name}_OUTPUT_HEADER ${_flex_OUTPUT_HEADER})
+
+      unset(_flex_EXE_NAME_WE)
+      unset(_flex_EXE_OPTS)
+      unset(_flex_INPUT)
+      unset(_flex_OUTPUT)
+      unset(_flex_OUTPUT_HEADER)
+      unset(_flex_OUTPUT_HEADER_ABS)
+      unset(_flex_TARGET_OUTPUTS)
+      unset(_flex_WORKING_DIR)
+
     endif()
   endmacro()
   #============================================================

+ 4 - 1
Source/cmPolicies.h

@@ -290,7 +290,10 @@ class cmMakefile;
   SELECT(POLICY, CMP0097,                                                     \
          "ExternalProject_Add with GIT_SUBMODULES \"\" initializes no "       \
          "submodules.",                                                       \
-         3, 16, 0, cmPolicies::WARN)
+         3, 16, 0, cmPolicies::WARN)                                          \
+  SELECT(POLICY, CMP0098,                                                     \
+         "FindFLEX runs flex in CMAKE_CURRENT_BINARY_DIR when executing.", 3, \
+         17, 0, cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \