# - Precompilation of Vala/Genie source files into C sources # Makes use of the parallel build ability introduced in Vala 0.11. # Might be a bit oversimplified and inefficient but at least it's short. # Filenames must be unique within a single compilation unit and that's fine. # # vala_precompile (source... - .vala, .gs, .vapi # [DIRECTORY dir] - Output directory (binary dir by default) # [PACKAGES package...] - Package dependencies # [OPTIONS option...] - Extra valac options # [OUTPUTS outputs_var] - Output C sources # [HEADER id.h - Generate id.h and id_internal.h # [VAPI id.vapi] - Generate a vapi file # [SYMBOLS id.def]]) - Generate a list of public symbols # #============================================================================= # Copyright (c) 2011, 2016, Přemysl Janouch # All rights reserved. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY # SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #============================================================================= find_package (Vala 0.11 REQUIRED) include (CMakeParseArguments) macro (_vala_parse_source_path) get_filename_component (basename "${file}" NAME) get_filename_component (without_extension "${file}" NAME_WE) set (output_vapi "${directory}/${without_extension}.vapi") set (output_c "${directory}/${without_extension}.c") endmacro () # XXX: it would be best to have it working without touching the vapi (which # forces rebuilds even if the API doesn't change) but it appears this cannot # be done in CMake (at least with make, with ninja it seems to be possible # via stamps and BYPRODUCTS) # TODO: check ${CMAKE_GENERATOR} and try to do better -> OUTPUT and "touch" # a stamp, use BYPRODUCTS instead, ... maybe make a target for all stamps, # then DEPEND on that target when precompiling. This should be enough. function (_vala_make_fast file) _vala_parse_source_path () add_custom_command (OUTPUT "${output_vapi}" COMMAND ${VALA_COMPILER} "${file}" "--fast-vapi=${output_vapi}" COMMAND ${CMAKE_COMMAND} -E touch "${output_vapi}" DEPENDS "${file}" COMMENT "Generating a fast vapi for ${basename}" VERBATIM) set (fast_vapi_deps ${fast_vapi_deps} "${output_vapi}" PARENT_SCOPE) set (fast_vapi_args ${fast_vapi_args} "--use-fast-vapi=${output_vapi}" PARENT_SCOPE) endfunction () function (_vala_make_c file) _vala_parse_source_path () # We need to filter the current file back out or else it creates conflicts set (fast_vapis ${fast_vapi_args}) list (REMOVE_ITEM fast_vapis "--use-fast-vapi=${output_vapi}") add_custom_command (OUTPUT "${output_c}" COMMAND ${VALA_COMPILER} "${file}" -C ${compiler_args} ${fast_vapis} COMMAND ${CMAKE_COMMAND} -E touch "${output_c}" DEPENDS "${file}" ${fast_vapi_deps} ${vapis} WORKING_DIRECTORY "${directory}" COMMENT "Precompiling ${basename}" VERBATIM) set (c_outputs ${c_outputs} "${output_c}" PARENT_SCOPE) endfunction () function (vala_precompile) set (_single_value DIRECTORY OUTPUTS HEADER VAPI SYMBOLS) set (_multi_value PACKAGES OPTIONS) cmake_parse_arguments (arg "" "${_single_value}" "${_multi_value}" ${ARGN}) set (directory ${CMAKE_CURRENT_BINARY_DIR}) if (arg_DIRECTORY) set (directory ${arg_DIRECTORY}) if (NOT IS_DIRECTORY ${directory}) file (MAKE_DIRECTORY ${directory}) endif (NOT IS_DIRECTORY ${directory}) endif () set (sources) set (vapis) foreach (_source ${arg_UNPARSED_ARGUMENTS}) if (NOT IS_ABSOLUTE "${_source}") set (_source "${CMAKE_CURRENT_SOURCE_DIR}/${_source}") endif () if (${_source} MATCHES "\\.vapi$") list (APPEND vapis "${_source}") else () list (APPEND sources "${_source}") endif () endforeach () # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - set (fast_vapi_deps) set (fast_vapi_args) foreach (_source ${sources}) _vala_make_fast ("${_source}") endforeach () set (compiler_args) foreach (_pkg ${arg_PACKAGES}) list (APPEND compiler_args "--pkg=${_pkg}") endforeach () list (APPEND compiler_args ${arg_OPTIONS} ${vapis}) set (c_outputs) foreach (_source ${sources}) _vala_make_c ("${_source}") endforeach () if (arg_OUTPUTS) set (${arg_OUTPUTS} ${c_outputs} PARENT_SCOPE) endif (arg_OUTPUTS) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - set (extra_outputs) set (export_args) if (arg_VAPI) if (NOT IS_ABSOLUTE "${arg_VAPI}") set (arg_VAPI "${directory}/${arg_VAPI}") endif () list (APPEND extra_outputs "${arg_VAPI}") list (APPEND export_args "--internal-vapi=${arg_VAPI}") if (NOT arg_HEADER) message (FATAL_ERROR "HEADER generation required for vapi") endif () endif () if (arg_SYMBOLS) if (NOT IS_ABSOLUTE "${arg_SYMBOLS}") set (arg_SYMBOLS "${directory}/${arg_SYMBOLS}") endif () list (APPEND extra_outputs "${arg_SYMBOLS}") list (APPEND export_args "--symbols=${arg_SYMBOLS}") if (NOT arg_HEADER) message (FATAL_ERROR "HEADER generation required for symbols") endif () endif () if (arg_HEADER) if (NOT IS_ABSOLUTE "${arg_HEADER}") set (arg_HEADER "${directory}/${arg_HEADER}") endif () get_filename_component (header_path "${arg_HEADER}" PATH) get_filename_component (header_name "${arg_HEADER}" NAME_WE) set (header_base "${header_path}/${header_name}") get_filename_component (header_ext "${arg_HEADER}" EXT) list (APPEND extra_outputs "${header_base}${header_ext}" "${header_base}_internal${header_ext}") list (APPEND export_args "--header=${header_base}${header_ext}" "--internal-header=${header_base}_internal${header_ext}") endif () if (extra_outputs) add_custom_command (OUTPUT ${extra_outputs} COMMAND ${VALA_COMPILER} -C ${compiler_args} ${export_args} ${fast_vapi_args} DEPENDS ${fast_vapi_deps} ${vapis} COMMENT "Generating vapi/headers/symbols" VERBATIM) endif () endfunction ()