--- /dev/null
+# FindVala.cmake
+# <https://github.com/nemequ/gnome-cmake>
+#
+# This file contains functions which can be used to integrate Vala
+# compilation with CMake. It is intended as a replacement for Jakob
+# Westhoff's FindVala.cmake and UseVala.cmake. It uses fast-vapis for
+# faster parallel compilation, and per-target directories for
+# generated sources to allow reusing source files across, even with
+# different options.
+#
+# License:
+#
+# Copyright (c) 2016 Evan Nemerson <evan@nemerson.com>
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use, copy,
+# modify, merge, publish, distribute, sublicense, and/or sell copies
+# of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+set(VALAC_NAMES valac)
+
+set(_FIND_VALA_CURRENT_VERSION 98)
+while(_FIND_VALA_CURRENT_VERSION GREATER 0)
+ list(APPEND VALAC_NAME "valac-1.${_FIND_VALA_CURRENT_VERSION}")
+ math(EXPR _FIND_VALA_CURRENT_VERSION "${_FIND_VALA_CURRENT_VERSION} - 2")
+endwhile()
+set(_FIND_VALA_CURRENT_VERSION 98)
+while(_FIND_VALA_CURRENT_VERSION GREATER 0)
+ list(APPEND VALAC_NAME "valac-1.${_FIND_VALA_CURRENT_VERSION}")
+ math(EXPR _FIND_VALA_CURRENT_VERSION "${_FIND_VALA_CURRENT_VERSION} - 2")
+endwhile()
+unset(_FIND_VALA_CURRENT_VERSION)
+
+find_program(VALA_EXECUTABLE
+ NAMES ${VALAC_NAMES})
+mark_as_advanced(VALA_EXECUTABLE)
+
+unset(VALAC_NAMES)
+
+if(VALA_EXECUTABLE)
+ # Determine valac version
+ execute_process(COMMAND ${VALA_EXECUTABLE} "--version"
+ OUTPUT_VARIABLE VALA_VERSION)
+ string(REGEX REPLACE "^.*Vala ([0-9]+\\.[0-9]+\\.[0-9]+(\\.[0-9]+(\\-[0-9a-f]+)?)?).*$" "\\1" VALA_VERSION "${VALA_VERSION}")
+
+ add_executable(valac IMPORTED)
+ set_property(TARGET valac PROPERTY IMPORTED_LOCATION "${VALA_EXECUTABLE}")
+endif(VALA_EXECUTABLE)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Vala
+ REQUIRED_VARS VALA_EXECUTABLE
+ VERSION_VAR VALA_VERSION)
+
+function(_vala_mkdir_for_file file)
+ get_filename_component(dir "${file}" DIRECTORY)
+ file(MAKE_DIRECTORY "${dir}")
+endfunction()
+
+macro(_vala_parse_source_file_path source)
+ set (options)
+ set (oneValueArgs SOURCE TYPE OUTPUT_PATH OUTPUT_DIR GENERATED_SOURCE FAST_VAPI)
+ set (multiValueArgs)
+ cmake_parse_arguments(VALAPATH "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+ unset (options)
+ unset (oneValueArgs)
+ unset (multiValueArgs)
+
+ if(VALAPATH_SOURCE)
+ get_filename_component("${VALAPATH_SOURCE}" "${source}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+ endif()
+
+ if(VALAPATH_TYPE)
+ string(REGEX MATCH "[^\\.]+$" "${VALAPATH_TYPE}" "${source}")
+ string(TOLOWER "${${VALAPATH_TYPE}}" "${VALAPATH_TYPE}")
+ endif()
+
+ if(VALAPATH_OUTPUT_PATH OR VALAPATH_GENERATED_SOURCE OR VALAPATH_OUTPUT_DIR OR VALAPATH_FAST_VAPI)
+ get_filename_component(srcfile "${source}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+
+ string(LENGTH "${CMAKE_BINARY_DIR}" dirlen)
+ string(SUBSTRING "${srcfile}" 0 ${dirlen} tmp)
+ if("${CMAKE_BINARY_DIR}" STREQUAL "${tmp}")
+ string(SUBSTRING "${srcfile}" ${dirlen} -1 tmp)
+ set(outpath "build${tmp}")
+ else()
+ string(LENGTH "${CMAKE_SOURCE_DIR}" dirlen)
+ string(SUBSTRING "${srcfile}" 0 ${dirlen} tmp)
+ if("${CMAKE_SOURCE_DIR}" STREQUAL "${tmp}")
+ string(SUBSTRING "${srcfile}" ${dirlen} -1 tmp)
+ set(outpath "source${tmp}")
+ else ()
+ # TODO: this probably doesn't work correctly on Windows…
+ set(outpath "root${tmp}")
+ endif()
+ endif()
+
+ unset(tmp)
+ unset(dirlen)
+ unset(srcfile)
+ endif()
+
+ if(VALAPATH_OUTPUT_PATH)
+ set("${VALAPATH_OUTPUT_PATH}" "${outpath}")
+ endif()
+
+ if(VALAPATH_GENERATED_SOURCE)
+ string(REGEX REPLACE "\\.(vala|gs)$" ".c" "${VALAPATH_GENERATED_SOURCE}" "${outpath}")
+ endif()
+
+ if(VALAPATH_FAST_VAPI)
+ string(REGEX REPLACE "\\.(vala|gs)$" ".vapi" "${VALAPATH_FAST_VAPI}" "${outpath}")
+ endif()
+
+ if(VALAPATH_OUTPUT_DIR)
+ get_filename_component("${VALAPATH_OUTPUT_DIR}" "${outpath}" DIRECTORY)
+ endif()
+
+ unset(outpath)
+endmacro()
+
+# vala_precompile_target(
+# TARGET
+# GENERATED_SOURCES
+# SOURCES…
+# [VAPI vapi-name.vapi]
+# [GIR name-version.gir]
+# [HEADER name.h]
+# [FLAGS …]
+# [PACKAGES …]
+# [DEPENDS …])
+#
+# This function will use valac to generate C code.
+#
+# This function uses fast VAPIs to help improve parallelization and
+# incremental build times. The problem with this is that CMake
+# doesn't allow file-level dependencies across directories; if you're
+# generating code in one directory (for example, a library) and would
+# like to use it in another directory and are building in parallel,
+# the build can fail. To prevent this, this function will create a
+# ${TARGET}-vala top-level target (which *is* usable from other
+# directories).
+#
+# Options:
+#
+# TARGET
+# Target to create; it's generally best to make this similar to
+# your executable or library target name (e.g., for a "foo"
+# executable, "foo-vala" might be a good name), but not
+# technically required.
+# GENERATED_SOURCES
+# Variable in which to store the list of generated sources (which
+# you should pass to add_executable or add_library).
+# SOURCES
+# Vala sources to generate C from. You should include *.vala,
+# *.gs, and uninstalled *.vapi files here; you may also include
+# C/C++ sources (they will simply be passed directly through to
+# the GENERATED_SOURCES variable).
+# VAPI name.vapi
+# If you would like to have valac generate a VAPI (basically, if
+# you are generating a library not an executable), pass the file
+# name here.
+# GIR name-version.gir
+# If you would like to have valac generate a GIR, pass the file
+# name here.
+# HEADER name.h
+# If you would like to have valac generate a C header, pass the
+# file name here.
+# FLAGS …
+# List of flags you wish to pass to valac. They will be added to
+# the flags in VALA_COMPILER_FLAGS and VALA_COMPILER_FLAGS_DEBUG
+# (for Debug builds) or VALA_COMPILER_FLAGS_RELEASE (for Release
+# builds).
+# PACKAGES
+# List of dependencies to pass to valac.
+# DEPENDS
+# Any additional dependencies you would like.
+macro(vala_precompile_target TARGET GENERATED_SOURCES)
+ set (options)
+ set (oneValueArgs VAPI GIR HEADER)
+ set (multiValueArgs FLAGS PACKAGES DEPENDS)
+ cmake_parse_arguments(VALAC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+ unset (options)
+ unset (oneValueArgs)
+ unset (multiValueArgs)
+
+ set(VALA_SOURCES)
+ set(VALA_VAPIS)
+ set(VALA_OUTPUT_SOURCES)
+
+ if(VALAC_VAPI)
+ list(APPEND non_source_out_files "${VALAC_VAPI}")
+ list(APPEND non_source_valac_args "--vapi" "${VALAC_VAPI}")
+ endif()
+
+ if(VALAC_GIR)
+ list(APPEND non_source_out_files "${VALAC_GIR}")
+ list(APPEND non_source_valac_args
+ "--gir" "${VALAC_GIR}"
+ "--library" "${TARGET}"
+ "--shared-library" "${CMAKE_SHARED_LIBRARY_PREFIX}${TARGET}${CMAKE_SHARED_LIBRARY_SUFFIX}")
+ endif()
+
+ if(VALAC_HEADER)
+ list(APPEND non_source_out_files "${VALAC_HEADER}")
+ list(APPEND non_source_valac_args --header "${VALAC_HEADER}")
+ endif()
+
+ # Split up the input files into three lists; one containing vala and
+ # genie sources, one containing VAPIs, and one containing C files
+ # (which may seem a bit silly, but it does open up the possibility
+ # of declaring your source file list once instead of having separate
+ # lists for Vala and C).
+ foreach(source ${VALAC_UNPARSED_ARGUMENTS})
+ _vala_parse_source_file_path("${source}"
+ SOURCE source_full
+ TYPE type)
+
+ if("vala" STREQUAL "${type}" OR "gs" STREQUAL "${type}")
+ list(APPEND VALA_SOURCES "${source_full}")
+ elseif("vapi" STREQUAL "${type}")
+ list(APPEND VALA_VAPIS "${source_full}")
+ elseif(
+ "c" STREQUAL "${type}" OR
+ "h" STREQUAL "${type}" OR
+ "cpp" STREQUAL "${type}" OR
+ "cxx" STREQUAL "${type}" OR
+ "hpp" STREQUAL "${type}")
+ list(APPEND VALA_OUTPUT_SOURCES "${source_full}")
+ endif()
+
+ unset(type)
+ unset(source_full)
+ endforeach()
+
+ # Set the common flags to pass to every valac invocation.
+ set(VALAFLAGS ${VALAC_FLAGS} ${VALA_VAPIS})
+ foreach(pkg ${VALAC_PACKAGES})
+ list(APPEND VALAFLAGS "--pkg" "${pkg}")
+ endforeach()
+ list(APPEND VALAFLAGS ${VALA_COMPILER_FLAGS})
+ if (CMAKE_BUILD_TYPE MATCHES "Debug")
+ list(APPEND VALAFLAGS ${VALA_COMPILER_FLAGS_DEBUG})
+ elseif(CMAKE_BUILD_TYPE MATCHES "Release")
+ list(APPEND VALAFLAGS ${VALA_COMPILER_FLAGS_RELEASE})
+ endif()
+
+ # Where to put the output
+ set(TARGET_DIR "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}")
+
+ set(FAST_VAPI_STAMPS)
+
+ # Create fast VAPI targets for each vala source
+ foreach(source ${VALA_SOURCES})
+ _vala_parse_source_file_path("${source}"
+ FAST_VAPI fast_vapi_path)
+
+ # We need somewhere to put the output…
+ _vala_mkdir_for_file("${TARGET_DIR}/${fast_vapi_path}")
+
+ # Create the target
+ add_custom_command(
+ OUTPUT "${TARGET_DIR}/${fast_vapi_path}.stamp"
+ BYPRODUCTS "${TARGET_DIR}/${fast_vapi_path}"
+ DEPENDS
+ "${source}"
+ ${VALA_VAPIS}
+ ${VALAC_DEPENDS}
+ COMMAND "${VALA_EXECUTABLE}"
+ ARGS
+ "${source}"
+ --fast-vapi "${TARGET_DIR}/${fast_vapi_path}"
+ ${VALAFLAGS}
+ COMMAND "${CMAKE_COMMAND}" ARGS -E touch "${TARGET_DIR}/${fast_vapi_path}.stamp"
+ COMMENT "Generating fast VAPI ${TARGET_DIR}/${fast_vapi_path}")
+
+ list(APPEND FAST_VAPI_STAMPS "${TARGET_DIR}/${fast_vapi_path}.stamp")
+
+ unset(fast_vapi_path)
+ endforeach()
+
+ # Create a ${TARGET_DIR}-fast-vapis target which depens on all the fast
+ # vapi stamps. We can use this as a dependency to make sure all
+ # fast-vapis are up to date.
+ add_custom_command(
+ OUTPUT "${TARGET_DIR}/fast-vapis.stamp"
+ COMMAND "${CMAKE_COMMAND}" ARGS -E touch "${TARGET_DIR}/fast-vapis.stamp"
+ DEPENDS
+ ${FAST_VAPI_STAMPS}
+ ${VALAC_DEPENDS}
+ COMMENT "Generating fast VAPIs for ${TARGET}")
+
+ add_custom_target("${TARGET}-fast-vapis"
+ DEPENDS "${TARGET_DIR}/fast-vapis.stamp")
+
+ set(VALA_GENERATED_SOURCE_STAMPS)
+
+ # Add targets to generate C sources
+ foreach(source ${VALA_SOURCES})
+ _vala_parse_source_file_path("${source}"
+ OUTPUT_PATH output_path
+ OUTPUT_DIR output_dir
+ GENERATED_SOURCE generated_source)
+
+ set(use_fast_vapi_flags)
+ foreach(src ${VALA_SOURCES})
+ if(NOT "${src}" STREQUAL "${source}")
+ _vala_parse_source_file_path("${src}"
+ FAST_VAPI src_fast_vapi_path)
+
+ list(APPEND use_fast_vapi_flags --use-fast-vapi "${TARGET_DIR}/${src_fast_vapi_path}")
+
+ unset(src_fast_vapi_path)
+ endif()
+ endforeach()
+
+ add_custom_command(
+ OUTPUT "${TARGET_DIR}/${generated_source}.stamp"
+ BYPRODUCTS "${TARGET_DIR}/${generated_source}"
+ COMMAND "${VALA_EXECUTABLE}"
+ ARGS
+ -d "${TARGET_DIR}/${output_dir}"
+ -C
+ "${source}"
+ ${VALAFLAGS}
+ ${use_fast_vapi_flags}
+ COMMAND "${CMAKE_COMMAND}" ARGS -E touch "${TARGET_DIR}/${generated_source}.stamp"
+ DEPENDS
+ "${TARGET}-fast-vapis"
+ "${source}"
+ ${VALA_VAPIS}
+ COMMENT "Generating ${TARGET_DIR}/${generated_source}")
+ unset(use_fast_vapi_flags)
+
+ list(APPEND VALA_OUTPUT_SOURCES "${TARGET_DIR}/${generated_source}")
+ list(APPEND VALA_GENERATED_SOURCE_STAMPS "${TARGET_DIR}/${generated_source}.stamp")
+
+ unset(fast_vapi_path)
+ unset(output_dir)
+ unset(generated_source)
+ endforeach()
+
+ add_custom_command(
+ OUTPUT "${TARGET_DIR}/stamp"
+ COMMAND "${CMAKE_COMMAND}" ARGS -E touch "${TARGET_DIR}/stamp"
+ DEPENDS ${VALA_GENERATED_SOURCE_STAMPS}
+ COMMENT "Generating sources from Vala for ${TARGET}")
+
+ set("${GENERATED_SOURCES}" ${VALA_OUTPUT_SOURCES})
+
+ if(non_source_out_files)
+ set(use_fast_vapi_flags)
+ foreach(source ${VALA_SOURCES})
+ _vala_parse_source_file_path("${source}"
+ FAST_VAPI fast_vapi_path)
+
+ list(APPEND use_fast_vapi_flags --use-fast-vapi "${TARGET_DIR}/${fast_vapi_path}")
+
+ unset(fast_vapi_path)
+ endforeach()
+
+ add_custom_command(OUTPUT ${non_source_out_files}
+ COMMAND ${VALA_EXECUTABLE}
+ ARGS
+ -C
+ ${non_source_valac_args}
+ ${VALAFLAGS}
+ ${use_fast_vapi_flags}
+ DEPENDS
+ "${TARGET}-fast-vapis"
+ ${VALA_VAPIS})
+ unset(use_fast_vapi_flags)
+ endif()
+
+ # CMake doesn't allow file-level dependencies across directories, so
+ # we provide a target we can depend on from other directories.
+ add_custom_target("${TARGET}"
+ DEPENDS
+ "${TARGET_DIR}/stamp"
+ ${non_source_out_files}
+ ${VALAC_DEPENDS}
+ ${VALA_GENERATED_SOURCE_STAMPS})
+
+ unset(non_source_out_files)
+ unset(non_source_valac_args)
+
+ unset(VALA_GENERATED_SOURCE_STAMPS)
+ unset(FAST_VAPI_STAMPS)
+ unset(TARGET_DIR)
+ unset(VALAFLAGS)
+ unset(VALA_SOURCES)
+ unset(VALA_VAPIS)
+ unset(VALA_OUTPUT_SOURCES)
+endmacro()
\ No newline at end of file