1# Copyright 2006-2008 The FLWOR Foundation.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15# This script will either generate a source file from a spec XML file
16# (if Zorba is available to process it), or copy a pre-generated
17# version from svn.
18
19# Arguments - all are required:
20#  query: Full path to .xq to execute for generation
21#  extvars: List of external variables to bind (-e args to zorba)
22#  files: List of files to bind to $files in query
23#  gen_file: Full path to generated file (in binary dir)
24#  ZORBA_EXE: Full path of ZORBA_EXE
25#  binary_dir: Full path of CMAKE_BINARY_DIR
26#  source_dir: Full path of CMAKE_SOURCE_DIR
27
28# Optional arguments:
29#  test_only: If true, we are testing the generation. Generate to a
30#  temp location and fail if the generated file is different than the
31#  pre-generated form. Note: gen_file must be provided as normal!
32
33
34# Check if zorbacmd exists and works. We need the ZORBA_EXE and the
35# file API for the generation of the runtime and codegen. Zorba will
36# fail running the test query if the file API dll is not found in the
37# correct location.
38SET (ZORBA_WORKS)
39IF (EXISTS ${ZORBA_EXE})
40  EXECUTE_PROCESS (
41    COMMAND
42      ${ZORBA_EXE}
43      -q "import module namespace file = 'http://expath.org/ns/file'; file:exists( 'a non existant file' )"
44    RESULT_VARIABLE ZORBA_WORKS_RES
45    OUTPUT_VARIABLE ZORBA_WORKS_OUTPUT
46  )
47  IF (NOT ZORBA_WORKS_RES EQUAL 0)
48    SET (ZORBA_WORKS FALSE)
49    MESSAGE (STATUS "[WARNING] Zorba Command Line Utility at \"${ZORBA_EXE}\ "
50      "does not work properly and cannot generate the runtime source files. "
51      "This will cause the repository version of these files to be used. "
52      "(Output from Zorba test command: ${ZORBA_WORKS_OUTPUT}")
53  ELSE (NOT ZORBA_WORKS_RES EQUAL 0)
54    SET (ZORBA_WORKS TRUE)
55  ENDIF (NOT ZORBA_WORKS_RES EQUAL 0)
56ELSE (EXISTS ${ZORBA_EXE})
57  SET (ZORBA_WORKS FALSE)
58ENDIF (EXISTS ${ZORBA_EXE})
59
60# Compute the relative path to the generated file
61FILE(RELATIVE_PATH gen_relfile "${binary_dir}" "${gen_file}")
62GET_FILENAME_COMPONENT(gen_relfiledir "${gen_relfile}" PATH)
63GET_FILENAME_COMPONENT(gen_relfilename "${gen_relfile}" NAME)
64
65# Compute path to pre-generated file.
66SET(pregen_file "${source_dir}/${gen_relfiledir}/pregenerated/${gen_relfilename}")
67
68# If we are testing the generation, overwrite gen_file with a dummy location.
69IF(test_only)
70  STRING(REGEX REPLACE "[/\\]" "_" gen_file "${gen_relfilename}")
71  SET(gen_file "${binary_dir}/gen_test.tmp.${gen_file}")
72  MESSAGE("  dobbbling: ${gen_file}")
73ENDIF(test_only)
74
75
76IF(ZORBA_WORKS)
77  MESSAGE(STATUS "Generating: ${gen_file}")
78  SET(extvarargs)
79  FOREACH(extvar ${extvars})
80    LIST(APPEND extvarargs "-e" "${extvar}")
81  ENDFOREACH(extvar)
82  IF(files)
83    # Because semicolons in CMake arguments end up being lists, we
84    # change the delimiter to a comma before passing to Zorba.
85    STRING(REPLACE ";" "," files "${files}")
86    LIST(APPEND extvarargs "-e" "files:=${files}")
87  ENDIF(files)
88  GET_FILENAME_COMPONENT(gen_file_dir "${gen_file}" PATH)
89  FILE(MAKE_DIRECTORY "${gen_file_dir}")
90  EXECUTE_PROCESS(COMMAND "${ZORBA_EXE}"
91    -q "${query}"
92    -f
93    -o "${gen_file}"
94    ${extvarargs}
95    --serialize-text
96    WORKING_DIRECTORY "${source_dir}/src/runtime/spec"
97    RESULT_VARIABLE RESULT)
98  IF(RESULT)
99    # Zorba may have created an empty file first, which will mess up dependency checking
100    FILE(REMOVE "${gen_file}")
101    MESSAGE(FATAL_ERROR "Error during generation!")
102  ENDIF(RESULT)
103
104  IF(test_only)
105    # Compare the resulting file with the existing pre-generated file.
106    # This SHOULD be the same, because either:
107
108    # A. Zorba existed before this bulid, in which case the
109    # pre-generated files would have been generated and overwritten if
110    # there were any spec file changes.
111
112    # B. Zorba did not exist before thie build, in which case the
113    # pre-generated files should match the results of generating now
114    # as they should be in sync in svn with the spec files.
115
116    # If they DON'T match, either somebody checked in a spec file that
117    # is no longer in sync with the pre-generated source; or somebody
118    # checked in something that affected the generation process
119    # without performing a re-generation. In either case, we want this
120    # test to fail!
121    EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" "-E" "compare_files"
122      "${pregen_file}" "${gen_file}" RESULT_VARIABLE COMPARE_RES)
123    IF(COMPARE_RES)
124      MESSAGE(FATAL_ERROR "Runtime generation produced different file! "
125        "Result was: ${COMPARE_RES} for ${pregen_file}")
126    ENDIF(COMPARE_RES)
127  ELSE(test_only)
128    # Overwrite the pregenerated file, so svn will pick it up.  Use
129    # copy_if_different so we don't mess with the timestamps if there
130    # was no difference.
131    EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" "-E" "copy_if_different"
132      "${gen_file}" "${pregen_file}")
133  ENDIF(test_only)
134
135ELSE(ZORBA_WORKS)
136
137  IF(test_only)
138    MESSAGE(FATAL_ERROR "Attempt to test runtime generation with "
139      "non-functional or missing Zorba executable ${ZORBA_EXE}!")
140  ELSE(test_only)
141    MESSAGE(STATUS "Copying pregenerated file for ${gen_file}")
142    EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" "-E" "copy"
143      "${pregen_file}" "${gen_file}")
144  ENDIF(test_only)
145
146ENDIF(ZORBA_WORKS)
147
148# Clean up testing file if we got this far
149IF(test_only)
150  FILE(REMOVE "${gen_file}")
151ENDIF(test_only)
152