kopia lustrzana https://github.com/stlink-org/stlink
374 wiersze
18 KiB
CMake
374 wiersze
18 KiB
CMake
################################################################################
|
|
##
|
|
## Provide Pandoc compilation support for the CMake build system
|
|
##
|
|
## Version: 0.0.1-dirty
|
|
## Author: Jeet Sukumatan (jeetsukumaran@gmail.com)
|
|
## Jerry Jacobs (jerry.jacobs@xor-gate.org)
|
|
##
|
|
## Copyright 2015 Jeet Sukumaran.
|
|
## Copyright 2016 Jerry Jacobs
|
|
##
|
|
## This software is released under the BSD 3-Clause License.
|
|
##
|
|
## Redistribution and use in source and binary forms, with or without
|
|
## modification, are permitted provided that the following conditions are
|
|
## met:
|
|
##
|
|
## 1. Redistributions of source code must retain the above copyright notice,
|
|
## this list of conditions and the following disclaimer.
|
|
##
|
|
## 2. Redistributions in binary form must reproduce the above copyright
|
|
## notice, this list of conditions and the following disclaimer in the
|
|
## documentation and/or other materials provided with the distribution.
|
|
##
|
|
## 3. Neither the name of the copyright holder nor the names of its
|
|
## contributors may be used to endorse or promote products derived from this
|
|
## software without specific prior written permission.
|
|
##
|
|
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
|
## IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
## LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
## NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
## SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
##
|
|
################################################################################
|
|
|
|
include(CMakeParseArguments)
|
|
|
|
if (NOT EXISTS ${PANDOC_EXECUTABLE})
|
|
find_program(PANDOC_EXECUTABLE pandoc)
|
|
mark_as_advanced(PANDOC_EXECUTABLE)
|
|
endif ()
|
|
|
|
###############################################################################
|
|
# Based on code from UseLATEX
|
|
# Author: Kenneth Moreland <kmorel@sandia.gov>
|
|
# Copyright 2004 Sandia Corporation.
|
|
# Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
|
# license for use of this work by or on behalf of the
|
|
# U.S. Government. Redistribution and use in source and binary forms, with
|
|
# or without modification, are permitted provided that this Notice and any
|
|
# statement of authorship are reproduced on all copies.
|
|
|
|
# Adds command to copy file from the source directory to the destination
|
|
# directory: used to move source files from source directory into build
|
|
# directory before main build
|
|
function(pandocology_add_input_file source_path dest_dir dest_filelist_var)
|
|
set(dest_filelist)
|
|
file(GLOB globbed_source_paths "${source_path}")
|
|
foreach(globbed_source_path ${globbed_source_paths})
|
|
# MESSAGE(FATAL_ERROR "${globbed_source_path}")
|
|
get_filename_component(filename ${globbed_source_path} NAME)
|
|
get_filename_component(absolute_dest_path ${dest_dir}/${filename} ABSOLUTE)
|
|
file(RELATIVE_PATH relative_dest_path ${CMAKE_CURRENT_BINARY_DIR} ${absolute_dest_path})
|
|
list(APPEND dest_filelist ${absolute_dest_path})
|
|
ADD_CUSTOM_COMMAND(
|
|
OUTPUT ${relative_dest_path}
|
|
COMMAND ${CMAKE_COMMAND} -E copy ${globbed_source_path} ${dest_dir}/${filename}
|
|
DEPENDS ${globbed_source_path}
|
|
)
|
|
set(${dest_filelist_var} ${${dest_filelist_var}} ${dest_filelist} PARENT_SCOPE)
|
|
endforeach()
|
|
endfunction()
|
|
|
|
# A version of GET_FILENAME_COMPONENT that treats extensions after the last
|
|
# period rather than the first.
|
|
function(pandocology_get_file_stemname varname filename)
|
|
SET(result)
|
|
GET_FILENAME_COMPONENT(name ${filename} NAME)
|
|
STRING(REGEX REPLACE "\\.[^.]*\$" "" result "${name}")
|
|
SET(${varname} "${result}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
function(pandocology_get_file_extension varname filename)
|
|
SET(result)
|
|
GET_FILENAME_COMPONENT(name ${filename} NAME)
|
|
STRING(REGEX MATCH "\\.[^.]*\$" result "${name}")
|
|
SET(${varname} "${result}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
###############################################################################
|
|
|
|
function(pandocology_add_input_dir source_dir dest_parent_dir dir_dest_filelist_var)
|
|
set(dir_dest_filelist)
|
|
get_filename_component(dir_name ${source_dir} NAME)
|
|
get_filename_component(absolute_dest_dir ${dest_parent_dir}/${dir_name} ABSOLUTE)
|
|
file(RELATIVE_PATH relative_dest_dir ${CMAKE_CURRENT_BINARY_DIR} ${absolute_dest_dir})
|
|
add_custom_command(
|
|
OUTPUT ${relative_dest_dir}
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${absolute_dest_dir}
|
|
DEPENDS ${source_dir}
|
|
)
|
|
file(GLOB source_files "${source_dir}/*")
|
|
foreach(source_file ${source_files})
|
|
# get_filename_component(absolute_source_path ${CMAKE_CURRENT_SOURCE_DIR}/${source_file} ABSOLUTE)
|
|
pandocology_add_input_file(${source_file} ${absolute_dest_dir} dir_dest_filelist)
|
|
endforeach()
|
|
set(${dir_dest_filelist_var} ${${dir_dest_filelist_var}} ${dir_dest_filelist} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
function(add_to_make_clean filepath)
|
|
get_directory_property(make_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
|
|
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${make_clean_files};${filepath}")
|
|
endfunction()
|
|
|
|
function(disable_insource_build)
|
|
IF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE )
|
|
MESSAGE(FATAL_ERROR "The build directory must be different from the main project source "
|
|
"directory. Please create a directory such as '${CMAKE_SOURCE_DIR}/build', "
|
|
"and run CMake from there, passing the path to this source directory as "
|
|
"the path argument. E.g.:
|
|
$ cd ${CMAKE_SOURCE_DIR}
|
|
$ mkdir build
|
|
$ cd build
|
|
$ cmake .. && make && sudo make install
|
|
This process created the file `CMakeCache.txt' and the directory `CMakeFiles'.
|
|
Please delete them:
|
|
$ rm -r CMakeFiles/ CmakeCache.txt
|
|
")
|
|
ENDif ()
|
|
endfunction()
|
|
|
|
# This builds a document
|
|
#
|
|
# Usage:
|
|
#
|
|
#
|
|
# INCLUDE(pandocology)
|
|
#
|
|
# add_document(
|
|
# figures.tex
|
|
# SOURCES figures.md
|
|
# RESOURCE_DIRS figs
|
|
# PANDOC_DIRECTIVES -t latex
|
|
# NO_EXPORT_PRODUCT
|
|
# )
|
|
#
|
|
# add_document(
|
|
# opus.pdf
|
|
# SOURCES opus.md
|
|
# RESOURCE_FILES opus.bib systbiol.template.latex systematic-biology.csl
|
|
# RESOURCE_DIRS figs
|
|
# PANDOC_DIRECTIVES -t latex
|
|
# --smart
|
|
# --template systbiol.template.latex
|
|
# --filter pandoc-citeproc
|
|
# --csl systematic-biology.csl
|
|
# --bibliography opus.bib
|
|
# --include-after-body=figures.tex
|
|
# DEPENDS figures.tex
|
|
# EXPORT_ARCHIVE
|
|
# )
|
|
#
|
|
function(add_document target_name)
|
|
if (NOT PANDOC_EXECUTABLE)
|
|
message(WARNING "Pandoc not found. Install Pandoc (http://johnmacfarlane.net/pandoc/) or set cache variable PANDOC_EXECUTABLE.")
|
|
return()
|
|
endif ()
|
|
|
|
set(options EXPORT_ARCHIVE NO_EXPORT_PRODUCT EXPORT_PDF DIRECT_TEX_TO_PDF VERBOSE)
|
|
set(oneValueArgs PRODUCT_DIRECTORY)
|
|
set(multiValueArgs SOURCES RESOURCE_FILES RESOURCE_DIRS PANDOC_DIRECTIVES DEPENDS)
|
|
cmake_parse_arguments(ADD_DOCUMENT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
|
|
|
|
# this is because `make clean` will dangerously clean up source files
|
|
disable_insource_build()
|
|
|
|
# get the stem of the target name
|
|
pandocology_get_file_stemname(target_stemname ${target_name})
|
|
pandocology_get_file_extension(target_extension ${target_name})
|
|
if (${ADD_DOCUMENT_EXPORT_PDF})
|
|
if (NOT "${target_extension}" STREQUAL ".tex" AND NOT "${target_extension}" STREQUAL ".latex")
|
|
# if (NOT "${target_extension}" STREQUAL ".tex")
|
|
MESSAGE(FATAL_ERROR "Target '${target_name}': Cannot use 'EXPORT_PDF' for target of type '${target_extension}': target type must be '.tex' or '.latex'")
|
|
endif ()
|
|
endif ()
|
|
if (${ADD_DOCUMENT_DIRECT_TEX_TO_PDF})
|
|
list(LENGTH ${ADD_DOCUMENT_SOURCES} SOURCE_LEN)
|
|
if (SOURCE_LEN GREATER 1)
|
|
MESSAGE(FATAL_ERROR "Target '${target_name}': Only one source can be specified when using the 'DIRECT_TEX_TO_PDF' option")
|
|
endif ()
|
|
# set(ADD_DOCUMENT_SOURCES, list(GET ${ADD_DOCUMENT_SOURCES} 1))
|
|
pandocology_get_file_stemname(source_stemname ${ADD_DOCUMENT_SOURCES})
|
|
pandocology_get_file_extension(source_extension ${ADD_DOCUMENT_SOURCES})
|
|
if (NOT "${source_extension}" STREQUAL ".tex" AND NOT "${source_extension}" STREQUAL ".latex")
|
|
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'")
|
|
endif ()
|
|
SET(check_target ${source_stemname}.pdf)
|
|
IF (NOT ${check_target} STREQUAL ${target_name})
|
|
MESSAGE(FATAL_ERROR "Target '${target_name}': Must use target name of '${check_target}' if using 'DIRECT_TEX_TO_PDF'")
|
|
endif ()
|
|
endif ()
|
|
|
|
## set up output directory
|
|
if ("${ADD_DOCUMENT_PRODUCT_DIRECTORY}" STREQUAL "")
|
|
set(ADD_DOCUMENT_PRODUCT_DIRECTORY "product")
|
|
endif ()
|
|
get_filename_component(product_directory ${CMAKE_BINARY_DIR}/${ADD_DOCUMENT_PRODUCT_DIRECTORY} ABSOLUTE)
|
|
# get_filename_component(absolute_product_path ${product_directory}/${target_name} ABSOLUTE)
|
|
|
|
## get primary source
|
|
set(build_sources)
|
|
foreach(input_file ${ADD_DOCUMENT_SOURCES} )
|
|
pandocology_add_input_file(${CMAKE_CURRENT_SOURCE_DIR}/${input_file} ${CMAKE_CURRENT_BINARY_DIR} build_sources)
|
|
endforeach()
|
|
|
|
## get resource files
|
|
set(build_resources)
|
|
foreach(resource_file ${ADD_DOCUMENT_RESOURCE_FILES})
|
|
pandocology_add_input_file(${CMAKE_CURRENT_SOURCE_DIR}/${resource_file} ${CMAKE_CURRENT_BINARY_DIR} build_resources)
|
|
endforeach()
|
|
|
|
## get resource dirs
|
|
set(exported_resources)
|
|
foreach(resource_dir ${ADD_DOCUMENT_RESOURCE_DIRS})
|
|
pandocology_add_input_dir(${CMAKE_CURRENT_SOURCE_DIR}/${resource_dir} ${CMAKE_CURRENT_BINARY_DIR} build_resources)
|
|
if (${ADD_DOCUMENT_EXPORT_ARCHIVE})
|
|
pandocology_add_input_dir(${CMAKE_CURRENT_SOURCE_DIR}/${resource_dir} ${product_directory} exported_resources)
|
|
endif ()
|
|
endforeach()
|
|
|
|
## primary command
|
|
if (${ADD_DOCUMENT_DIRECT_TEX_TO_PDF})
|
|
if (${ADD_DOCUMENT_VERBOSE})
|
|
add_custom_command(
|
|
OUTPUT ${target_name} # note that this is in the build directory
|
|
DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
|
|
# WORKING_DIRECTORY ${working_directory}
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${product_directory}
|
|
# we produce the target in the source directory, in case other build targets require it as a source
|
|
COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${build_sources}
|
|
)
|
|
else()
|
|
add_custom_command(
|
|
OUTPUT ${target_name} # note that this is in the build directory
|
|
DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
|
|
# WORKING_DIRECTORY ${working_directory}
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${product_directory}
|
|
# we produce the target in the source directory, in case other build targets require it as a source
|
|
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)
|
|
)
|
|
endif ()
|
|
add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_name})
|
|
else()
|
|
add_custom_command(
|
|
OUTPUT ${target_name} # note that this is in the build directory
|
|
DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
|
|
# WORKING_DIRECTORY ${working_directory}
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${product_directory}
|
|
# we produce the target in the source directory, in case other build targets require it as a source
|
|
COMMAND ${PANDOC_EXECUTABLE} ${build_sources} ${ADD_DOCUMENT_PANDOC_DIRECTIVES} -o ${target_name}
|
|
)
|
|
add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_name})
|
|
endif ()
|
|
|
|
## figure out what all is going to be produced by this build set, and set
|
|
## those as dependencies of the primary target
|
|
set(primary_target_dependencies)
|
|
set(primary_target_dependencies ${primary_target_dependencies} ${CMAKE_CURRENT_BINARY_DIR}/${target_name})
|
|
if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT})
|
|
set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_name})
|
|
endif ()
|
|
if (${ADD_DOCUMENT_EXPORT_PDF})
|
|
set(primary_target_dependencies ${primary_target_dependencies} ${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf)
|
|
set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_stemname}.pdf)
|
|
endif ()
|
|
if (${ADD_DOCUMENT_EXPORT_ARCHIVE})
|
|
set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_stemname}.tbz)
|
|
endif ()
|
|
|
|
## primary target
|
|
# # target cannot have same (absolute name) as dependencies:
|
|
# # http://www.cmake.org/pipermail/cmake/2011-March/043378.html
|
|
add_custom_target(
|
|
${target_name}
|
|
ALL
|
|
DEPENDS ${primary_target_dependencies} ${ADD_DOCUMENT_DEPENDS}
|
|
)
|
|
|
|
# run post-pdf
|
|
if (${ADD_DOCUMENT_EXPORT_PDF})
|
|
# get_filename_component(target_stemname ${target_name} NAME_WE)
|
|
add_custom_command(
|
|
OUTPUT ${product_directory}/${target_stemname}.pdf ${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf
|
|
DEPENDS ${target_name} ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
|
|
|
|
# Does not work: custom template used to generate tex is ignored
|
|
# COMMAND ${PANDOC_EXECUTABLE} ${target_name} -f latex -o ${target_stemname}.pdf
|
|
|
|
# (1) Apparently, both nonstopmode and batchmode produce an output file
|
|
# even if there was an error. This tricks latexmk into believing
|
|
# the file is actually up-to-date.
|
|
# So we use `-halt-on-error` or `-interaction=errorstopmode`
|
|
# instead.
|
|
# (2) `grep` returns a non-zero error code if the pattern is not
|
|
# found. So, in our scheme below to filter the output of
|
|
# `pdflatex`, it is precisely when there is NO error that
|
|
# grep returns a non-zero code, which fools CMake into thinking
|
|
# tex'ing failed.
|
|
# Hence the need for `| grep ...| cat` or `| grep || true`.
|
|
# But we can go better:
|
|
# latexmk .. || (grep .. && false)
|
|
# So we can have our cake and eat it too: here we want to
|
|
# re-raise the error after a successful grep if there was an
|
|
# error in `latexmk`.
|
|
# COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${target_name} 2>&1 | grep -A8 ".*:[0-9]*:.*" || true
|
|
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)
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E copy ${target_stemname}.pdf ${product_directory}
|
|
)
|
|
add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf)
|
|
add_to_make_clean(${product_directory}/${target_stemname}.pdf)
|
|
endif ()
|
|
|
|
## copy products
|
|
if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT})
|
|
add_custom_command(
|
|
OUTPUT ${product_directory}/${target_name}
|
|
DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
|
|
COMMAND ${CMAKE_COMMAND} -E copy ${target_name} ${product_directory}
|
|
)
|
|
add_to_make_clean(${product_directory}/${target_name})
|
|
endif ()
|
|
|
|
## copy resources
|
|
if (${ADD_DOCUMENT_EXPORT_ARCHIVE})
|
|
# get_filename_component(target_stemname ${target_name} NAME_WE)
|
|
# add_custom_command(
|
|
# TARGET ${target_name} POST_BUILD
|
|
# DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
|
|
# # COMMAND cp ${build_resources} ${ADD_DOCUMENT_DEPENDS} ${product_directory}
|
|
# COMMAND ${CMAKE_COMMAND} -E tar cjf ${product_directory}/${target_stemname}.tbz ${target_name} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
|
|
# )
|
|
add_custom_command(
|
|
OUTPUT ${product_directory}/${target_stemname}.tbz
|
|
DEPENDS ${target_name}
|
|
# COMMAND cp ${build_resources} ${ADD_DOCUMENT_DEPENDS} ${product_directory}
|
|
COMMAND ${CMAKE_COMMAND} -E tar cjf ${product_directory}/${target_stemname}.tbz ${target_name} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
|
|
)
|
|
add_to_make_clean(${product_directory}/${target_stemname}.tbz)
|
|
# add_custom_target(
|
|
# ${target_stemname}.ARCHIVE
|
|
# ALL
|
|
# DEPENDS ${product_directory}/${target_stemname}.tbz
|
|
# )
|
|
endif ()
|
|
|
|
endfunction(add_document)
|
|
|
|
function(add_tex_document)
|
|
add_document(${ARGV} DIRECT_TEX_TO_PDF)
|
|
endfunction()
|
|
|
|
# LEGACY SUPPORT
|
|
function(add_pandoc_document)
|
|
add_document(${ARGV})
|
|
endfunction()
|