Back to home page

EIC code displayed by LXR

 
 

    


Warning, /DD4hep/cmake/PANDOC.cmake is written in an unsupported language. File is not indexed.

0001 ################################################################################
0002 ##
0003 ##  Provide Pandoc compilation support for the CMake build system
0004 ##
0005 ##  Version: 0.0.1
0006 ##  Author: Jeet Sukumatan (jeetsukumaran@gmail.com)
0007 ##
0008 ##  Copyright 2015 Jeet Sukumaran.
0009 ##
0010 ##  This software is released under the BSD 3-Clause License.
0011 ##
0012 ##  Redistribution and use in source and binary forms, with or without
0013 ##  modification, are permitted provided that the following conditions are
0014 ##  met:
0015 ##
0016 ##  1. Redistributions of source code must retain the above copyright notice,
0017 ##  this list of conditions and the following disclaimer.
0018 ##
0019 ##  2. Redistributions in binary form must reproduce the above copyright
0020 ##  notice, this list of conditions and the following disclaimer in the
0021 ##  documentation and/or other materials provided with the distribution.
0022 ##
0023 ##  3. Neither the name of the copyright holder nor the names of its
0024 ##  contributors may be used to endorse or promote products derived from this
0025 ##  software without specific prior written permission.
0026 ##
0027 ##  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
0028 ##  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
0029 ##  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0030 ##  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
0031 ##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0032 ##  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0033 ##  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0034 ##  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0035 ##  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
0036 ##  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0037 ##  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0038 ##
0039 ################################################################################
0040 
0041 include(CMakeParseArguments)
0042 
0043 if(NOT EXISTS ${PANDOC_EXECUTABLE})
0044     # find_program(PANDOC_EXECUTABLE NAMES pandoc)
0045     find_program(PANDOC_EXECUTABLE pandoc)
0046     mark_as_advanced(PANDOC_EXECUTABLE)
0047     if(NOT EXISTS ${PANDOC_EXECUTABLE})
0048         unset(PANDOC_EXECUTABLE)
0049         return()
0050     endif()
0051 endif()
0052 
0053 ###############################################################################
0054 # Based on code from UseLATEX
0055 # Author: Kenneth Moreland <kmorel@sandia.gov>
0056 # Copyright 2004 Sandia Corporation.
0057 # Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
0058 # license for use of this work by or on behalf of the
0059 # U.S. Government. Redistribution and use in source and binary forms, with
0060 # or without modification, are permitted provided that this Notice and any
0061 # statement of authorship are reproduced on all copies.
0062 
0063 # Adds command to copy file from the source directory to the destination
0064 # directory: used to move source files from source directory into build
0065 # directory before main build
0066 function(pandocology_add_input_file source_path dest_dir dest_filelist_var)
0067     set(dest_filelist)
0068     file(GLOB globbed_source_paths "${source_path}")
0069     foreach(globbed_source_path ${globbed_source_paths})
0070         # MESSAGE(FATAL_ERROR "${globbed_source_path}")
0071         if(NOT IS_ABSOLUTE ${globbed_source_path})
0072             get_filename_component(filename ${globbed_source_path} NAME)
0073             get_filename_component(absolute_dest_path ${dest_dir}/${filename} ABSOLUTE)
0074             file(RELATIVE_PATH relative_dest_path ${CMAKE_CURRENT_BINARY_DIR} ${absolute_dest_path})
0075             list(APPEND dest_filelist ${absolute_dest_path})
0076         
0077             add_custom_command(
0078                 OUTPUT ${relative_dest_path}
0079                 COMMAND ${CMAKE_COMMAND} -E copy ${globbed_source_path} ${dest_dir}/${filename}
0080                 DEPENDS ${globbed_source_path}
0081                 )
0082         else()
0083             list(APPEND dest_filelist ${globbed_source_path})
0084         endif()
0085         set(${dest_filelist_var} ${${dest_filelist_var}} ${dest_filelist} PARENT_SCOPE)
0086     endforeach()
0087 endfunction()
0088 
0089 # A version of GET_FILENAME_COMPONENT that treats extensions after the last
0090 # period rather than the first.
0091 function(pandocology_get_file_stemname varname filename)
0092     SET(result)
0093     GET_FILENAME_COMPONENT(name ${filename} NAME)
0094     STRING(REGEX REPLACE "\\.[^.]*\$" "" result "${name}")
0095     SET(${varname} "${result}" PARENT_SCOPE)
0096 endfunction()
0097 
0098 function(pandocology_get_file_extension varname filename)
0099     SET(result)
0100     GET_FILENAME_COMPONENT(name ${filename} NAME)
0101     STRING(REGEX MATCH "\\.[^.]*\$" result "${name}")
0102     SET(${varname} "${result}" PARENT_SCOPE)
0103 endfunction()
0104 ###############################################################################
0105 
0106 function(pandocology_add_input_dir source_dir dest_parent_dir dir_dest_filelist_var)
0107     set(dir_dest_filelist)
0108     get_filename_component(dir_name ${source_dir} NAME)
0109     get_filename_component(absolute_dest_dir ${dest_parent_dir}/${dir_name} ABSOLUTE)
0110     file(RELATIVE_PATH relative_dest_dir ${CMAKE_CURRENT_BINARY_DIR} ${absolute_dest_dir})
0111     add_custom_command(
0112         OUTPUT ${relative_dest_dir}
0113         COMMAND ${CMAKE_COMMAND} -E make_directory ${absolute_dest_dir}
0114         DEPENDS ${source_dir}
0115         )
0116     file(GLOB source_files "${source_dir}/*")
0117     foreach(source_file ${source_files})
0118         # get_filename_component(absolute_source_path ${CMAKE_CURRENT_SOURCE_DIR}/${source_file} ABSOLUTE)
0119         pandocology_add_input_file(${source_file} ${absolute_dest_dir} dir_dest_filelist)
0120     endforeach()
0121     set(${dir_dest_filelist_var} ${${dir_dest_filelist_var}} ${dir_dest_filelist} PARENT_SCOPE)
0122 endfunction()
0123 
0124 function(add_to_make_clean filepath)
0125     get_directory_property(make_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
0126     set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${make_clean_files};${filepath}")
0127 endfunction()
0128 
0129 function(disable_insource_build)
0130     IF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE )
0131         MESSAGE(FATAL_ERROR "The build directory must be different from the main project source "
0132 "directory. Please create a directory such as '${CMAKE_SOURCE_DIR}/build', "
0133 "and run CMake from there, passing the path to this source directory as "
0134 "the path argument. E.g.:
0135     $ cd ${CMAKE_SOURCE_DIR}
0136     $ mkdir build
0137     $ cd build
0138     $ cmake .. && make && sudo make install
0139 This process created the file `CMakeCache.txt' and the directory `CMakeFiles'.
0140 Please delete them:
0141     $ rm -r CMakeFiles/ CmakeCache.txt
0142 ")
0143     ENDIF()
0144 endfunction()
0145 
0146 # This builds a document
0147 #
0148 # Usage:
0149 #
0150 #
0151 #     INCLUDE(pandocology)
0152 #
0153 #     add_document(
0154 #         figures.tex
0155 #         SOURCES              figures.md
0156 #         RESOURCE_DIRS        figs
0157 #         PANDOC_DIRECTIVES    -t latex
0158 #         NO_EXPORT_PRODUCT
0159 #         )
0160 #
0161 #     add_document(
0162 #         opus.pdf
0163 #         SOURCES              opus.md
0164 #         RESOURCE_FILES       opus.bib systbiol.template.latex systematic-biology.csl
0165 #         RESOURCE_DIRS        figs
0166 #         PANDOC_DIRECTIVES    -t             latex
0167 #                             --smart
0168 #                             --template     systbiol.template.latex
0169 #                             --filter       pandoc-citeproc
0170 #                             --csl          systematic-biology.csl
0171 #                             --bibliography opus.bib
0172 #                             --include-after-body=figures.tex
0173 #         DEPENDS             figures.tex
0174 #         EXPORT_ARCHIVE
0175 #         )
0176 #
0177 function(add_document target_name)
0178     set(options          EXPORT_ARCHIVE NO_EXPORT_PRODUCT EXPORT_PDF DIRECT_TEX_TO_PDF VERBOSE)
0179     set(oneValueArgs     PRODUCT_DIRECTORY)
0180     set(multiValueArgs   SOURCES RESOURCE_FILES RESOURCE_DIRS PANDOC_DIRECTIVES DEPENDS)
0181     cmake_parse_arguments(ADD_DOCUMENT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
0182 
0183     # this is because `make clean` will dangerously clean up source files
0184     disable_insource_build()
0185 
0186     # get the stem of the target name
0187     pandocology_get_file_stemname(target_stemname ${target_name})
0188     pandocology_get_file_extension(target_extension ${target_name})
0189     if (${ADD_DOCUMENT_EXPORT_PDF})
0190         if (NOT "${target_extension}" STREQUAL ".tex" AND NOT "${target_extension}" STREQUAL ".latex")
0191         # if (NOT "${target_extension}" STREQUAL ".tex")
0192             MESSAGE(FATAL_ERROR "Target '${target_name}': Cannot use 'EXPORT_PDF' for target of type '${target_extension}': target type must be '.tex' or '.latex'")
0193         endif()
0194     endif()
0195     if (${ADD_DOCUMENT_DIRECT_TEX_TO_PDF})
0196         list(LENGTH ${ADD_DOCUMENT_SOURCES} SOURCE_LEN)
0197         if (SOURCE_LEN GREATER 1)
0198             MESSAGE(FATAL_ERROR "Target '${target_name}': Only one source can be specified when using the 'DIRECT_TEX_TO_PDF' option")
0199         endif()
0200         # set(ADD_DOCUMENT_SOURCES, list(GET ${ADD_DOCUMENT_SOURCES} 1))
0201         pandocology_get_file_stemname(source_stemname ${ADD_DOCUMENT_SOURCES})
0202         pandocology_get_file_extension(source_extension ${ADD_DOCUMENT_SOURCES})
0203         if (NOT "${source_extension}" STREQUAL ".tex" AND NOT "${source_extension}" STREQUAL ".latex")
0204             MESSAGE(FATAL_ERROR "Target '${target_name}': Cannot use 'DIRECT_TEX_TO_PDF' for source of type '${source_extension}': source type must be '.tex' or '.latex'")
0205         endif()
0206         SET(check_target ${source_stemname}.pdf)
0207         IF (NOT ${check_target} STREQUAL ${target_name})
0208             MESSAGE(FATAL_ERROR "Target '${target_name}': Must use target name of '${check_target}' if using 'DIRECT_TEX_TO_PDF'")
0209         endif()
0210     endif()
0211 
0212     ## set up output directory
0213     if ("${ADD_DOCUMENT_PRODUCT_DIRECTORY}" STREQUAL "")
0214         set(ADD_DOCUMENT_PRODUCT_DIRECTORY "product")
0215     endif()
0216     get_filename_component(product_directory ${CMAKE_BINARY_DIR}/${ADD_DOCUMENT_PRODUCT_DIRECTORY} ABSOLUTE)
0217     # get_filename_component(absolute_product_path ${product_directory}/${target_name} ABSOLUTE)
0218     
0219     ## get primary source
0220     set(build_sources)
0221     foreach(input_file ${ADD_DOCUMENT_SOURCES} )
0222         if(NOT IS_ABSOLUTE ${input_file})
0223             set(input_file ${CMAKE_CURRENT_SOURCE_DIR}/${input_file})
0224         endif()
0225         pandocology_add_input_file(${input_file} ${CMAKE_CURRENT_BINARY_DIR} build_sources)
0226     endforeach()
0227 
0228     ## get resource files
0229     set(build_resources)
0230     foreach(resource_file ${ADD_DOCUMENT_RESOURCE_FILES})
0231         if(NOT IS_ABSOLUTE ${resource_file})
0232             set(resource_file ${CMAKE_CURRENT_SOURCE_DIR}/${resource_file})
0233         endif()
0234         pandocology_add_input_file(${resource_file} ${CMAKE_CURRENT_BINARY_DIR} build_resources)
0235     endforeach()
0236 
0237     ## get resource dirs
0238     set(exported_resources)
0239     foreach(resource_dir ${ADD_DOCUMENT_RESOURCE_DIRS})
0240         if(NOT IS_ABSOLUTE ${resource_file})
0241             set(resource_dir ${CMAKE_CURRENT_SOURCE_DIR}/${resource_dir})
0242         endif()
0243         pandocology_add_input_dir(${resource_dir} ${CMAKE_CURRENT_BINARY_DIR} build_resources)
0244         if (${ADD_DOCUMENT_EXPORT_ARCHIVE})
0245             pandocology_add_input_dir(${resource_dir} ${product_directory} exported_resources)
0246         endif()
0247     endforeach()
0248     
0249     ## primary command
0250     if (${ADD_DOCUMENT_DIRECT_TEX_TO_PDF})
0251         if (${ADD_DOCUMENT_VERBOSE})
0252             add_custom_command(
0253                 OUTPUT  ${target_name} # note that this is in the build directory
0254                 DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0255                 # WORKING_DIRECTORY ${working_directory}
0256                 COMMAND ${CMAKE_COMMAND} -E make_directory ${product_directory}
0257                 # we produce the target in the source directory, in case other build targets require it as a source
0258                 COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${build_sources}
0259                 )
0260         else()
0261             add_custom_command(
0262                 OUTPUT  ${target_name} # note that this is in the build directory
0263                 DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0264                 # WORKING_DIRECTORY ${working_directory}
0265                 COMMAND ${CMAKE_COMMAND} -E make_directory ${product_directory}
0266                 # we produce the target in the source directory, in case other build targets require it as a source
0267                 COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${build_sources} 2>/dev/null >/dev/null || (grep --no-messages -A8 ".*:[0-9]*:.*" ${target_stemname}.log && false)
0268                 )
0269         endif()
0270         add_to_make_clean(${target_name})
0271     else()
0272         add_custom_command(
0273             OUTPUT  ${target_name} # note that this is in the build directory
0274             DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0275             # WORKING_DIRECTORY ${working_directory}
0276             COMMAND ${CMAKE_COMMAND} -E make_directory ${product_directory}
0277             # we produce the target in the source directory, in case other build targets require it as a source
0278             COMMAND ${PANDOC_EXECUTABLE} ${build_sources} ${ADD_DOCUMENT_PANDOC_DIRECTIVES} -o ${target_name}
0279             )
0280         add_to_make_clean(${target_name})
0281     endif()
0282     
0283     ## figure out what all is going to be produced by this build set, and set
0284     ## those as dependencies of the primary target
0285     set(primary_target_dependencies)
0286     set(primary_target_dependencies ${primary_target_dependencies} ${target_name})
0287     if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT})
0288         set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_name})
0289     endif()
0290     if (${ADD_DOCUMENT_EXPORT_PDF})
0291         set(primary_target_dependencies ${primary_target_dependencies} ${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf)
0292         set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_stemname}.pdf)
0293     endif()
0294     if (${ADD_DOCUMENT_EXPORT_ARCHIVE})
0295         set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_stemname}.tbz)
0296     endif()
0297     
0298     # run post-pdf
0299     if (${ADD_DOCUMENT_EXPORT_PDF})
0300         # get_filename_component(target_stemname ${target_name} NAME_WE)
0301         add_custom_command(
0302             OUTPUT ${product_directory}/${target_stemname}.pdf ${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf
0303             DEPENDS ${target_name} ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0304 
0305             # Does not work: custom template used to generate tex is ignored
0306             # COMMAND ${PANDOC_EXECUTABLE} ${target_name} -f latex -o ${target_stemname}.pdf
0307 
0308             # (1)   Apparently, both nonstopmode and batchmode produce an output file
0309             #       even if there was an error. This tricks latexmk into believing
0310             #       the file is actually up-to-date.
0311             #       So we use `-halt-on-error` or `-interaction=errorstopmode`
0312             #       instead.
0313             # (2)   `grep` returns a non-zero error code if the pattern is not
0314             #       found. So, in our scheme below to filter the output of
0315             #       `pdflatex`, it is precisely when there is NO error that
0316             #       grep returns a non-zero code, which fools CMake into thinking
0317             #       tex'ing failed.
0318             #       Hence the need for `| grep ...| cat` or `| grep  || true`.
0319             #       But we can go better:
0320             #           latexmk .. || (grep .. && false)
0321             #       So we can have our cake and eat it too: here we want to
0322             #       re-raise the error after a successful grep if there was an
0323             #       error in `latexmk`.
0324             # COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${target_name} 2>&1 | grep -A8 ".*:[0-9]*:.*" || true
0325             COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${target_name} 2>/dev/null >/dev/null || (grep --no-messages -A8 ".*:[0-9]*:.*" ${target_stemname}.log && false)
0326 
0327             COMMAND ${CMAKE_COMMAND} -E copy ${target_stemname}.pdf ${product_directory}
0328             )
0329         add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf)
0330         add_to_make_clean(${product_directory}/${target_stemname}.pdf)
0331     endif()
0332     
0333     ## copy products
0334     if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT})
0335         add_custom_command(
0336             OUTPUT ${product_directory}/${target_name}
0337             DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0338             COMMAND ${CMAKE_COMMAND} -E copy ${target_name} ${product_directory}
0339             )
0340         add_to_make_clean(${product_directory}/${target_name})
0341     endif()
0342     
0343     ## copy resources
0344     if (${ADD_DOCUMENT_EXPORT_ARCHIVE})
0345         # get_filename_component(target_stemname ${target_name} NAME_WE)
0346         # add_custom_command(
0347         #     TARGET ${target_name} POST_BUILD
0348         #     DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0349         #     # COMMAND cp ${build_resources} ${ADD_DOCUMENT_DEPENDS} ${product_directory}
0350         #     COMMAND ${CMAKE_COMMAND} -E tar cjf ${product_directory}/${target_stemname}.tbz ${target_name} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0351         #     )
0352         add_custom_command(
0353             OUTPUT ${product_directory}/${target_stemname}.tbz
0354             DEPENDS ${target_name}
0355             # COMMAND cp ${build_resources} ${ADD_DOCUMENT_DEPENDS} ${product_directory}
0356             COMMAND ${CMAKE_COMMAND} -E tar cjf ${product_directory}/${target_stemname}.tbz ${target_name} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0357             )
0358         add_to_make_clean(${product_directory}/${target_stemname}.tbz)
0359         # add_custom_target(
0360         #     ${target_stemname}.ARCHIVE
0361         #     ALL
0362         #     DEPENDS ${product_directory}/${target_stemname}.tbz
0363         #     )
0364     endif()
0365 
0366 endfunction(add_document)
0367 
0368 function(add_pandoc_document)
0369     add_document(${ARGV})
0370 endfunction()