# - Precompilation of Vala/Genie source files into C sources # Makes use of the parallel build ability introduced in Vala 0.11. # Filenames must be unique within a single compilation unit and that's fine. # Props to other Vala module writers, I had to reengineer it to understand it. # # 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. #============================================================================= cmake_minimum_required (VERSION 2.8.0) 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 () function (_vala_make_fast file) _vala_parse_source_path () # See `cmake --help-policy CMP0058` for a rather nice explanation set (_stamp "${output_vapi}") set (_byproducts) if (NOT "${CMAKE_VERSION}" VERSION_LESS "3.0.2") set (_stamp "${output_vapi}.stamp") set (_byproducts BYPRODUCTS "${output_vapi}") set (stamp_target ${stamp_target} "${_stamp}" PARENT_SCOPE) endif () add_custom_command (OUTPUT "${_stamp}" ${_byproducts} COMMAND ${VALA_COMPILER} "${file}" "--fast-vapi=${output_vapi}" COMMAND ${CMAKE_COMMAND} -E touch "${_stamp}" 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} ${stamp_target} WORKING_DIRECTORY "${directory}" COMMENT "Precompiling ${basename}" VERBATIM) set (c_outputs ${c_outputs} "${output_c}" PARENT_SCOPE) endfunction () set (_vala_counter 0) function (vala_precompile) # So that the user doesn't need to name any targets, we can do it ourselves math (EXPR counter "${_vala_counter} + 1") set (_vala_counter "${counter}" PARENT_SCOPE) 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) set (stamp_target) foreach (_source ${sources}) _vala_make_fast ("${_source}") endforeach () # The target is actually required, or else it may trigger CMP0058 if (stamp_target) add_custom_target ("vala_fast_vapis_${counter}" DEPENDS ${stamp_target}) set (stamp_target "vala_fast_vapis_${counter}") endif () 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) if (arg_VAPI) if (NOT IS_ABSOLUTE "${arg_VAPI}") set (arg_VAPI "${directory}/${arg_VAPI}") endif () list (APPEND extra_outputs "${arg_VAPI}") list (APPEND compiler_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 compiler_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 compiler_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} ${fast_vapi_args} DEPENDS ${fast_vapi_deps} ${vapis} COMMENT "Generating vapi/headers/symbols" VERBATIM) endif () endfunction ()