Browse Source

Define add_flex_target CMake macro.

Sam Edwards 12 years ago
parent
commit
84aad872ec
2 changed files with 74 additions and 0 deletions
  1. 1 0
      CMakeLists.txt
  2. 73 0
      cmake/macros/AddFlexTarget.cmake

+ 1 - 0
CMakeLists.txt

@@ -12,6 +12,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/macros/")
 # Include global modules
 include(AutoInclude)        # Implements automatic include_directories finding
 include(AddBisonTarget)     # Defines add_bison_target function
+include(AddFlexTarget)      # Defines add_flex_target function
 include(CompositeSources)   # Defines composite_sources function
 include(PackageConfig)      # Defines package_option AND target_use_packages
 include(Interrogate)        # Defines target_interrogate AND add_python_module

+ 73 - 0
cmake/macros/AddFlexTarget.cmake

@@ -0,0 +1,73 @@
+# Filename: AddFlexTarget.cmake
+# Description: This file defines the function add_flex_target which instructs
+#   cmake to use flex on an input .lxx file.  If flex is not available on
+#   the system, add_flex_target tries to use .prebuilt .cxx files instead.
+#
+# Usage:
+#   add_flex_target(output_cxx input_lxx [DEFINES output_h] [PREFIX prefix])
+#
+
+# Define add_flex_target()
+function(add_flex_target output_cxx input_lxx)
+  set(arguments "")
+  set(outputs "${output_cxx}")
+  set(keyword "")
+
+  # Parse the extra arguments to the function.
+  foreach(arg ${ARGN})
+    if(arg STREQUAL "DEFINES")
+      set(keyword "DEFINES")
+    elseif(arg STREQUAL "PREFIX")
+      set(keyword "PREFIX")
+
+    elseif(keyword STREQUAL "PREFIX")
+      set(arguments ${arguments} -P "${arg}")
+    elseif(keyword STREQUAL "DEFINES")
+      set(arguments ${arguments} --header-file="${arg}")
+      list(APPEND outputs "${arg}")
+
+    else()
+      message(SEND_ERROR "Unexpected argument ${arg} to add_flex_target")
+    endif()
+  endforeach()
+
+  if(keyword STREQUAL arg AND NOT keyword STREQUAL "")
+    message(SEND_ERROR "Expected argument after ${keyword}")
+  endif()
+
+  if(HAVE_FLEX)
+    get_source_file_property(input_lxx "${input_lxx}" LOCATION)
+
+    # If we have flex, we can of course just run it.
+    add_custom_command(
+      OUTPUT ${outputs}
+      COMMAND ${FLEX_EXECUTABLE}
+        -o "${output_cxx}" ${arguments}
+        "${input_lxx}"
+      MAIN_DEPENDENCY "${input_lxx}"
+    )
+
+  else()
+    # Look for prebuilt versions of the outputs.
+    set(commands "")
+    set(depends "")
+
+    foreach(output ${outputs})
+      set(prebuilt_file "${output}.prebuilt")
+      get_filename_component(prebuilt_file "${prebuilt_file}" ABSOLUTE)
+
+      if(NOT EXISTS "${prebuilt_file}")
+        message(SEND_ERROR "Flex was not found and ${prebuilt_file} does not exist!")
+      endif()
+
+      list(APPEND depends "${prebuilt_file}")
+      set(commands ${commands} COMMAND ${CMAKE_COMMAND} -E copy ${prebuilt_file} ${output})
+    endforeach()
+
+    add_custom_command(
+      OUTPUT ${outputs}
+      ${commands}
+      DEPENDS ${depends}
+    )
+  endif()
+endfunction(add_flex_target)