Initial commit

This commit is contained in:
BHBN
2020-03-06 21:16:51 +01:00
committed by GitHub
parent 67e9c29a01
commit db75874e87
26 changed files with 5314 additions and 0 deletions

617
cmake/modules/CMakeRC.cmake Normal file
View File

@@ -0,0 +1,617 @@
# This block is executed when generating an intermediate resource file, not when
# running in CMake configure mode
if(_CMRC_GENERATE_MODE)
# Read in the digits
file(READ "${INPUT_FILE}" bytes HEX)
# Format each pair into a character literal. Heuristics seem to favor doing
# the conversion in groups of five for fastest conversion
string(REGEX REPLACE "(..)(..)(..)(..)(..)" "'\\\\x\\1','\\\\x\\2','\\\\x\\3','\\\\x\\4','\\\\x\\5'," chars "${bytes}")
# Since we did this in groups, we have some leftovers to clean up
string(LENGTH "${bytes}" n_bytes2)
math(EXPR n_bytes "${n_bytes2} / 2")
math(EXPR remainder "${n_bytes} % 5") # <-- '5' is the grouping count from above
set(cleanup_re "$")
set(cleanup_sub )
while(remainder)
set(cleanup_re "(..)${cleanup_re}")
set(cleanup_sub "'\\\\x\\${remainder}',${cleanup_sub}")
math(EXPR remainder "${remainder} - 1")
endwhile()
if(NOT cleanup_re STREQUAL "$")
string(REGEX REPLACE "${cleanup_re}" "${cleanup_sub}" chars "${chars}")
endif()
string(CONFIGURE [[
namespace { const char file_array[] = { @chars@ 0 }; }
namespace cmrc { namespace @NAMESPACE@ { namespace res_chars {
extern const char* const @SYMBOL@_begin = file_array;
extern const char* const @SYMBOL@_end = file_array + @n_bytes@;
}}}
]] code)
file(WRITE "${OUTPUT_FILE}" "${code}")
# Exit from the script. Nothing else needs to be processed
return()
endif()
set(_version 2.0.0)
cmake_minimum_required(VERSION 3.3)
include(CMakeParseArguments)
if(COMMAND cmrc_add_resource_library)
if(NOT DEFINED _CMRC_VERSION OR NOT (_version STREQUAL _CMRC_VERSION))
message(WARNING "More than one CMakeRC version has been included in this project.")
endif()
# CMakeRC has already been included! Don't do anything
return()
endif()
set(_CMRC_VERSION "${_version}" CACHE INTERNAL "CMakeRC version. Used for checking for conflicts")
set(_CMRC_SCRIPT "${CMAKE_CURRENT_LIST_FILE}" CACHE INTERNAL "Path to CMakeRC script")
function(_cmrc_normalize_path var)
set(path "${${var}}")
file(TO_CMAKE_PATH "${path}" path)
while(path MATCHES "//")
string(REPLACE "//" "/" path "${path}")
endwhile()
string(REGEX REPLACE "/+$" "" path "${path}")
set("${var}" "${path}" PARENT_SCOPE)
endfunction()
get_filename_component(_inc_dir "${CMAKE_BINARY_DIR}/_cmrc/include" ABSOLUTE)
set(CMRC_INCLUDE_DIR "${_inc_dir}" CACHE INTERNAL "Directory for CMakeRC include files")
# Let's generate the primary include file
file(MAKE_DIRECTORY "${CMRC_INCLUDE_DIR}/cmrc")
set(hpp_content [==[
#ifndef CMRC_CMRC_HPP_INCLUDED
#define CMRC_CMRC_HPP_INCLUDED
#include <cassert>
#include <functional>
#include <iterator>
#include <list>
#include <map>
#include <mutex>
#include <string>
#include <system_error>
#include <type_traits>
namespace cmrc { namespace detail { struct dummy; } }
#define CMRC_DECLARE(libid) \
namespace cmrc { namespace detail { \
struct dummy; \
static_assert(std::is_same<dummy, ::cmrc::detail::dummy>::value, "CMRC_DECLARE() must only appear at the global namespace"); \
} } \
namespace cmrc { namespace libid { \
cmrc::embedded_filesystem get_filesystem(); \
} } static_assert(true, "")
namespace cmrc {
class file {
const char* _begin = nullptr;
const char* _end = nullptr;
public:
using iterator = const char*;
using const_iterator = iterator;
iterator begin() const noexcept { return _begin; }
iterator cbegin() const noexcept { return _begin; }
iterator end() const noexcept { return _end; }
iterator cend() const noexcept { return _end; }
std::size_t size() const { return std::distance(begin(), end()); }
file() = default;
file(iterator beg, iterator end) noexcept : _begin(beg), _end(end) {}
};
class directory_entry;
namespace detail {
class directory;
class file_data;
class file_or_directory {
union _data_t {
class file_data* file_data;
class directory* directory;
} _data;
bool _is_file = true;
public:
explicit file_or_directory(file_data& f) {
_data.file_data = &f;
}
explicit file_or_directory(directory& d) {
_data.directory = &d;
_is_file = false;
}
bool is_file() const noexcept {
return _is_file;
}
bool is_directory() const noexcept {
return !is_file();
}
const directory& as_directory() const noexcept {
assert(!is_file());
return *_data.directory;
}
const file_data& as_file() const noexcept {
assert(is_file());
return *_data.file_data;
}
};
class file_data {
public:
const char* begin_ptr;
const char* end_ptr;
file_data(const file_data&) = delete;
file_data(const char* b, const char* e) : begin_ptr(b), end_ptr(e) {}
};
inline std::pair<std::string, std::string> split_path(const std::string& path) {
auto first_sep = path.find("/");
if (first_sep == path.npos) {
return std::make_pair(path, "");
} else {
return std::make_pair(path.substr(0, first_sep), path.substr(first_sep + 1));
}
}
struct created_subdirectory {
class directory& directory;
class file_or_directory& index_entry;
};
class directory {
std::list<file_data> _files;
std::list<directory> _dirs;
std::map<std::string, file_or_directory> _index;
using base_iterator = std::map<std::string, file_or_directory>::const_iterator;
public:
directory() = default;
directory(const directory&) = delete;
created_subdirectory add_subdir(std::string name) & {
_dirs.emplace_back();
auto& back = _dirs.back();
auto& fod = _index.emplace(name, file_or_directory{back}).first->second;
return created_subdirectory{back, fod};
}
file_or_directory* add_file(std::string name, const char* begin, const char* end) & {
assert(_index.find(name) == _index.end());
_files.emplace_back(begin, end);
return &_index.emplace(name, file_or_directory{_files.back()}).first->second;
}
const file_or_directory* get(const std::string& path) const {
auto pair = split_path(path);
auto child = _index.find(pair.first);
if (child == _index.end()) {
return nullptr;
}
auto& entry = child->second;
if (pair.second.empty()) {
// We're at the end of the path
return &entry;
}
if (entry.is_file()) {
// We can't traverse into a file. Stop.
return nullptr;
}
// Keep going down
return entry.as_directory().get(pair.second);
}
class iterator {
base_iterator _base_iter;
base_iterator _end_iter;
public:
using value_type = directory_entry;
using difference_type = std::ptrdiff_t;
using pointer = const value_type*;
using reference = const value_type&;
using iterator_category = std::input_iterator_tag;
iterator() = default;
explicit iterator(base_iterator iter, base_iterator end) : _base_iter(iter), _end_iter(end) {}
iterator begin() const noexcept {
return *this;
}
iterator end() const noexcept {
return iterator(_end_iter, _end_iter);
}
inline value_type operator*() const noexcept;
bool operator==(const iterator& rhs) const noexcept {
return _base_iter == rhs._base_iter;
}
bool operator!=(const iterator& rhs) const noexcept {
return !(*this == rhs);
}
iterator operator++() noexcept {
auto cp = *this;
++_base_iter;
return cp;
}
iterator& operator++(int) noexcept {
++_base_iter;
return *this;
}
};
using const_iterator = iterator;
iterator begin() const noexcept {
return iterator(_index.begin(), _index.end());
}
iterator end() const noexcept {
return iterator();
}
};
inline std::string normalize_path(std::string path) {
while (path.find("/") == 0) {
path.erase(path.begin());
}
while (!path.empty() && (path.rfind("/") == path.size() - 1)) {
path.pop_back();
}
auto off = path.npos;
while ((off = path.find("//")) != path.npos) {
path.erase(path.begin() + off);
}
return path;
}
using index_type = std::map<std::string, const cmrc::detail::file_or_directory*>;
} // detail
class directory_entry {
std::string _fname;
const detail::file_or_directory* _item;
public:
directory_entry() = delete;
explicit directory_entry(std::string filename, const detail::file_or_directory& item)
: _fname(filename)
, _item(&item)
{}
const std::string& filename() const & {
return _fname;
}
std::string filename() const && {
return std::move(_fname);
}
bool is_file() const {
return _item->is_file();
}
bool is_directory() const {
return _item->is_directory();
}
};
directory_entry detail::directory::iterator::operator*() const noexcept {
assert(begin() != end());
return directory_entry(_base_iter->first, _base_iter->second);
}
using directory_iterator = detail::directory::iterator;
class embedded_filesystem {
// Never-null:
const cmrc::detail::index_type* _index;
const detail::file_or_directory* _get(std::string path) const {
path = detail::normalize_path(path);
auto found = _index->find(path);
if (found == _index->end()) {
return nullptr;
} else {
return found->second;
}
}
public:
explicit embedded_filesystem(const detail::index_type& index)
: _index(&index)
{}
file open(const std::string& path) const {
auto entry_ptr = _get(path);
if (!entry_ptr || !entry_ptr->is_file()) {
throw std::system_error(make_error_code(std::errc::no_such_file_or_directory), path);
}
auto& dat = entry_ptr->as_file();
return file{dat.begin_ptr, dat.end_ptr};
}
bool is_file(const std::string& path) const noexcept {
auto entry_ptr = _get(path);
return entry_ptr && entry_ptr->is_file();
}
bool is_directory(const std::string& path) const noexcept {
auto entry_ptr = _get(path);
return entry_ptr && entry_ptr->is_directory();
}
bool exists(const std::string& path) const noexcept {
return !!_get(path);
}
directory_iterator iterate_directory(const std::string& path) const {
auto entry_ptr = _get(path);
if (!entry_ptr) {
throw std::system_error(make_error_code(std::errc::no_such_file_or_directory), path);
}
if (!entry_ptr->is_directory()) {
throw std::system_error(make_error_code(std::errc::not_a_directory), path);
}
return entry_ptr->as_directory().begin();
}
};
}
#endif // CMRC_CMRC_HPP_INCLUDED
]==])
set(cmrc_hpp "${CMRC_INCLUDE_DIR}/cmrc/cmrc.hpp" CACHE INTERNAL "")
set(_generate 1)
if(EXISTS "${cmrc_hpp}")
file(READ "${cmrc_hpp}" _current)
if(_current STREQUAL hpp_content)
set(_generate 0)
endif()
endif()
file(GENERATE OUTPUT "${cmrc_hpp}" CONTENT "${hpp_content}" CONDITION ${_generate})
add_library(cmrc-base INTERFACE)
target_include_directories(cmrc-base INTERFACE "${CMRC_INCLUDE_DIR}")
# Signal a basic C++11 feature to require C++11.
target_compile_features(cmrc-base INTERFACE cxx_nullptr)
set_property(TARGET cmrc-base PROPERTY INTERFACE_CXX_EXTENSIONS OFF)
add_library(cmrc::base ALIAS cmrc-base)
function(cmrc_add_resource_library name)
set(args ALIAS NAMESPACE)
cmake_parse_arguments(ARG "" "${args}" "" "${ARGN}")
# Generate the identifier for the resource library's namespace
set(ns_re "[a-zA-Z_][a-zA-Z0-9_]*")
if(NOT DEFINED ARG_NAMESPACE)
# Check that the library name is also a valid namespace
if(NOT name MATCHES "${ns_re}")
message(SEND_ERROR "Library name is not a valid namespace. Specify the NAMESPACE argument")
endif()
set(ARG_NAMESPACE "${name}")
else()
if(NOT ARG_NAMESPACE MATCHES "${ns_re}")
message(SEND_ERROR "NAMESPACE for ${name} is not a valid C++ namespace identifier (${ARG_NAMESPACE})")
endif()
endif()
set(libname "${name}")
# Generate a library with the compiled in character arrays.
string(CONFIGURE [=[
#include <cmrc/cmrc.hpp>
#include <map>
#include <utility>
namespace cmrc {
namespace @ARG_NAMESPACE@ {
namespace res_chars {
// These are the files which are available in this resource library
$<JOIN:$<TARGET_PROPERTY:@libname@,CMRC_EXTERN_DECLS>,
>
}
namespace {
const cmrc::detail::index_type&
get_root_index() {
static cmrc::detail::directory root_directory_;
static cmrc::detail::file_or_directory root_directory_fod{root_directory_};
static cmrc::detail::index_type root_index;
root_index.emplace("", &root_directory_fod);
struct dir_inl {
class cmrc::detail::directory& directory;
};
dir_inl root_directory_dir{root_directory_};
(void)root_directory_dir;
$<JOIN:$<TARGET_PROPERTY:@libname@,CMRC_MAKE_DIRS>,
>
$<JOIN:$<TARGET_PROPERTY:@libname@,CMRC_MAKE_FILES>,
>
return root_index;
}
}
cmrc::embedded_filesystem get_filesystem() {
static auto& index = get_root_index();
return cmrc::embedded_filesystem{index};
}
} // @ARG_NAMESPACE@
} // cmrc
]=] cpp_content @ONLY)
get_filename_component(libdir "${CMAKE_CURRENT_BINARY_DIR}/__cmrc_${name}" ABSOLUTE)
get_filename_component(lib_tmp_cpp "${libdir}/lib_.cpp" ABSOLUTE)
string(REPLACE "\n " "\n" cpp_content "${cpp_content}")
file(GENERATE OUTPUT "${lib_tmp_cpp}" CONTENT "${cpp_content}")
get_filename_component(libcpp "${libdir}/lib.cpp" ABSOLUTE)
add_custom_command(OUTPUT "${libcpp}"
DEPENDS "${lib_tmp_cpp}" "${cmrc_hpp}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${lib_tmp_cpp}" "${libcpp}"
COMMENT "Generating ${name} resource loader"
)
# Generate the actual static library. Each source file is just a single file
# with a character array compiled in containing the contents of the
# corresponding resource file.
add_library(${name} STATIC ${libcpp})
set_property(TARGET ${name} PROPERTY CMRC_LIBDIR "${libdir}")
set_property(TARGET ${name} PROPERTY CMRC_NAMESPACE "${ARG_NAMESPACE}")
target_link_libraries(${name} PUBLIC cmrc::base)
set_property(TARGET ${name} PROPERTY CMRC_IS_RESOURCE_LIBRARY TRUE)
if(ARG_ALIAS)
add_library("${ARG_ALIAS}" ALIAS ${name})
endif()
cmrc_add_resources(${name} ${ARG_UNPARSED_ARGUMENTS})
endfunction()
function(_cmrc_register_dirs name dirpath)
if(dirpath STREQUAL "")
return()
endif()
# Skip this dir if we have already registered it
get_target_property(registered "${name}" _CMRC_REGISTERED_DIRS)
if(dirpath IN_LIST registered)
return()
endif()
# Register the parent directory first
get_filename_component(parent "${dirpath}" DIRECTORY)
if(NOT parent STREQUAL "")
_cmrc_register_dirs("${name}" "${parent}")
endif()
# Now generate the registration
set_property(TARGET "${name}" APPEND PROPERTY _CMRC_REGISTERED_DIRS "${dirpath}")
_cm_encode_fpath(sym "${dirpath}")
if(parent STREQUAL "")
set(parent_sym root_directory)
else()
_cm_encode_fpath(parent_sym "${parent}")
endif()
get_filename_component(leaf "${dirpath}" NAME)
set_property(
TARGET "${name}"
APPEND PROPERTY CMRC_MAKE_DIRS
"static auto ${sym}_dir = ${parent_sym}_dir.directory.add_subdir(\"${leaf}\")\;"
"root_index.emplace(\"${dirpath}\", &${sym}_dir.index_entry)\;"
)
endfunction()
function(cmrc_add_resources name)
get_target_property(is_reslib ${name} CMRC_IS_RESOURCE_LIBRARY)
if(NOT TARGET ${name} OR NOT is_reslib)
message(SEND_ERROR "cmrc_add_resources called on target '${name}' which is not an existing resource library")
return()
endif()
set(options)
set(args WHENCE PREFIX)
set(list_args)
cmake_parse_arguments(ARG "${options}" "${args}" "${list_args}" "${ARGN}")
if(NOT ARG_WHENCE)
set(ARG_WHENCE ${CMAKE_CURRENT_SOURCE_DIR})
endif()
_cmrc_normalize_path(ARG_WHENCE)
get_filename_component(ARG_WHENCE "${ARG_WHENCE}" ABSOLUTE)
# Generate the identifier for the resource library's namespace
get_target_property(lib_ns "${name}" CMRC_NAMESPACE)
get_target_property(libdir ${name} CMRC_LIBDIR)
get_target_property(target_dir ${name} SOURCE_DIR)
file(RELATIVE_PATH reldir "${target_dir}" "${CMAKE_CURRENT_SOURCE_DIR}")
if(reldir MATCHES "^\\.\\.")
message(SEND_ERROR "Cannot call cmrc_add_resources in a parent directory from the resource library target")
return()
endif()
foreach(input IN LISTS ARG_UNPARSED_ARGUMENTS)
_cmrc_normalize_path(input)
get_filename_component(abs_in "${input}" ABSOLUTE)
# Generate a filename based on the input filename that we can put in
# the intermediate directory.
file(RELATIVE_PATH relpath "${ARG_WHENCE}" "${abs_in}")
if(relpath MATCHES "^\\.\\.")
# For now we just error on files that exist outside of the soure dir.
message(SEND_ERROR "Cannot add file '${input}': File must be in a subdirectory of ${ARG_WHENCE}")
continue()
endif()
if(DEFINED ARG_PREFIX)
_cmrc_normalize_path(ARG_PREFIX)
endif()
if(ARG_PREFIX AND NOT ARG_PREFIX MATCHES "/$")
set(ARG_PREFIX "${ARG_PREFIX}/")
endif()
get_filename_component(dirpath "${ARG_PREFIX}${relpath}" DIRECTORY)
_cmrc_register_dirs("${name}" "${dirpath}")
get_filename_component(abs_out "${libdir}/intermediate/${relpath}.cpp" ABSOLUTE)
# Generate a symbol name relpath the file's character array
_cm_encode_fpath(sym "${relpath}")
# Get the symbol name for the parent directory
if(dirpath STREQUAL "")
set(parent_sym root_directory)
else()
_cm_encode_fpath(parent_sym "${dirpath}")
endif()
# Generate the rule for the intermediate source file
_cmrc_generate_intermediate_cpp(${lib_ns} ${sym} "${abs_out}" "${abs_in}")
target_sources(${name} PRIVATE "${abs_out}")
set_property(TARGET ${name} APPEND PROPERTY CMRC_EXTERN_DECLS
"// Pointers to ${input}"
"extern const char* const ${sym}_begin\;"
"extern const char* const ${sym}_end\;"
)
get_filename_component(leaf "${relpath}" NAME)
set_property(
TARGET ${name}
APPEND PROPERTY CMRC_MAKE_FILES
"root_index.emplace("
" \"${ARG_PREFIX}${relpath}\","
" ${parent_sym}_dir.directory.add_file("
" \"${leaf}\","
" res_chars::${sym}_begin,"
" res_chars::${sym}_end"
" )"
")\;"
)
endforeach()
endfunction()
function(_cmrc_generate_intermediate_cpp lib_ns symbol outfile infile)
add_custom_command(
# This is the file we will generate
OUTPUT "${outfile}"
# These are the primary files that affect the output
DEPENDS "${infile}" "${_CMRC_SCRIPT}"
COMMAND
"${CMAKE_COMMAND}"
-D_CMRC_GENERATE_MODE=TRUE
-DNAMESPACE=${lib_ns}
-DSYMBOL=${symbol}
"-DINPUT_FILE=${infile}"
"-DOUTPUT_FILE=${outfile}"
-P "${_CMRC_SCRIPT}"
COMMENT "Generating intermediate file for ${infile}"
)
endfunction()
function(_cm_encode_fpath var fpath)
string(MAKE_C_IDENTIFIER "${fpath}" ident)
string(MD5 hash "${fpath}")
string(SUBSTRING "${hash}" 0 4 hash)
set(${var} f_${hash}_${ident} PARENT_SCOPE)
endfunction()

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 vector-of-bool <vectorofbool@gmail.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.

View File

@@ -0,0 +1,22 @@
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 copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.

View File

@@ -0,0 +1,64 @@
# - Try to find the GLIB2 libraries
# Once done this will define
#
# GLIB2_FOUND - system has glib2
# GLIB2_INCLUDE_DIR - the glib2 include directory
# GLIB2_LIBRARIES - glib2 library
# Copyright (c) 2008 Laurent Montel, <montel@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
if(GLIB2_INCLUDE_DIR AND GLIB2_LIBRARIES)
# Already in cache, be silent
set(GLIB2_FIND_QUIETLY TRUE)
endif(GLIB2_INCLUDE_DIR AND GLIB2_LIBRARIES)
if (NOT WIN32)
find_package(PkgConfig REQUIRED)
pkg_check_modules(PKG_GLIB REQUIRED glib-2.0)
endif(NOT WIN32)
find_path(GLIB2_MAIN_INCLUDE_DIR glib.h
PATH_SUFFIXES glib-2.0
HINTS ${PKG_GLIB_INCLUDE_DIRS} ${PKG_GLIB_INCLUDEDIR})
# search the glibconfig.h include dir under the same root where the library is found
find_library(GLIB2_LIBRARIES
NAMES glib-2.0
HINTS ${PKG_GLIB_LIBRARY_DIRS} ${PKG_GLIB_LIBDIR})
find_path(GLIB2_INTERNAL_INCLUDE_DIR glibconfig.h
PATH_SUFFIXES glib-2.0/include ../lib/glib-2.0/include
HINTS ${PKG_GLIB_INCLUDE_DIRS} ${PKG_GLIB_LIBRARIES} ${CMAKE_SYSTEM_LIBRARY_PATH})
set(GLIB2_INCLUDE_DIR ${GLIB2_MAIN_INCLUDE_DIR})
# not sure if this include dir is optional or required
# for now it is optional
if(GLIB2_INTERNAL_INCLUDE_DIR)
set(GLIB2_INCLUDE_DIR ${GLIB2_INCLUDE_DIR} ${GLIB2_INTERNAL_INCLUDE_DIR})
endif(GLIB2_INTERNAL_INCLUDE_DIR)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GLIB2 DEFAULT_MSG GLIB2_LIBRARIES GLIB2_MAIN_INCLUDE_DIR)
mark_as_advanced(GLIB2_INCLUDE_DIR GLIB2_LIBRARIES)
find_program(GLIB2_GENMARSHAL_UTIL glib-genmarshal)
macro(glib2_genmarshal output_name)
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/genmarshal_tmp)
foreach(_declaration ${ARGN})
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/genmarshal_tmp "${_declaration}\n")
endforeach()
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${output_name}.h ${CMAKE_CURRENT_BINARY_DIR}/${output_name}.c
COMMAND ${GLIB2_GENMARSHAL_UTIL} --header genmarshal_tmp > ${output_name}.h
COMMAND ${GLIB2_GENMARSHAL_UTIL} --body genmarshal_tmp > ${output_name}.c
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
endmacro()

View File

@@ -0,0 +1,63 @@
# - Try to find GObject
# Once done this will define
#
# GOBJECT_FOUND - system has GObject
# GOBJECT_INCLUDE_DIR - the GObject include directory
# GOBJECT_LIBRARIES - the libraries needed to use GObject
# GOBJECT_DEFINITIONS - Compiler switches required for using GObject
# Copyright (c) 2006, Tim Beaulen <tbscope@gmail.com>
# Copyright (c) 2008 Helio Chissini de Castro, <helio@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
IF (GOBJECT_INCLUDE_DIR AND GOBJECT_LIBRARIES)
# in cache already
SET(GObject_FIND_QUIETLY TRUE)
ELSE (GOBJECT_INCLUDE_DIR AND GOBJECT_LIBRARIES)
SET(GObject_FIND_QUIETLY FALSE)
ENDIF (GOBJECT_INCLUDE_DIR AND GOBJECT_LIBRARIES)
IF (NOT WIN32)
FIND_PACKAGE(PkgConfig REQUIRED)
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
PKG_CHECK_MODULES(PKG_GOBJECT2 REQUIRED gobject-2.0)
SET(GOBJECT_DEFINITIONS ${PKG_GOBJECT2_CFLAGS})
ENDIF (NOT WIN32)
FIND_PATH(GOBJECT_INCLUDE_DIR gobject/gobject.h
HINTS ${PKG_GOBJECT2_INCLUDE_DIRS} ${PKG_GOBJECT2_INCLUDEDIR}
PATHS /usr/include/glib-2.0/
PATH_SUFFIXES glib-2.0
)
FIND_LIBRARY(_GObjectLibs NAMES gobject-2.0
HINTS
${PKG_GOBJECT2_LIBRARY_DIRS}
${PKG_GOBJECT2_LIBDIR}
)
FIND_LIBRARY(_GModuleLibs NAMES gmodule-2.0
HINTS
${PKG_GOBJECT2_LIBRARY_DIRS}
${PKG_GOBJECT2_LIBDIR}
)
FIND_LIBRARY(_GThreadLibs NAMES gthread-2.0
HINTS
${PKG_GOBJECT2_LIBRARY_DIRS}
${PKG_GOBJECT2_LIBDIR}
)
FIND_LIBRARY(_GLibs NAMES glib-2.0
HINTS
${PKG_GOBJECT2_LIBRARY_DIRS}
${PKG_GOBJECT2_LIBDIR}
)
SET (GOBJECT_LIBRARIES ${_GObjectLibs} ${_GModuleLibs} ${_GThreadLibs} ${_GLibs})
MARK_AS_ADVANCED(GOBJECT_INCLUDE_DIR GOBJECT_LIBRARIES)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GObject DEFAULT_MSG GOBJECT_INCLUDE_DIR GOBJECT_LIBRARIES)

View File

@@ -0,0 +1,132 @@
# - Try to find GStreamer
# Once done this will define
#
# GSTREAMER_FOUND - system has GStreamer
# GSTREAMER_INCLUDE_DIR - the GStreamer include directory
# GSTREAMER_LIBRARY - the main GStreamer library
# GSTREAMER_PLUGIN_DIR - the GStreamer plugin directory
#
# And for all the plugin libraries specified in the COMPONENTS
# of find_package, this module will define:
#
# GSTREAMER_<plugin_lib>_LIBRARY_FOUND - system has <plugin_lib>
# GSTREAMER_<plugin_lib>_LIBRARY - the <plugin_lib> library
# GSTREAMER_<plugin_lib>_INCLUDE_DIR - the <plugin_lib> include directory
#
# Copyright (c) 2010, Collabora Ltd.
# @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
if (GSTREAMER_INCLUDE_DIR AND GSTREAMER_LIBRARY)
set(GStreamer_FIND_QUIETLY TRUE)
else()
set(GStreamer_FIND_QUIETLY FALSE)
endif()
set(GSTREAMER_ABI_VERSION "1.0")
# Find the main library
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PKG_GSTREAMER gstreamer-${GSTREAMER_ABI_VERSION})
exec_program(${PKG_CONFIG_EXECUTABLE}
ARGS --variable pluginsdir gstreamer-${GSTREAMER_ABI_VERSION}
OUTPUT_VARIABLE PKG_GSTREAMER_PLUGIN_DIR)
endif()
find_library(GSTREAMER_LIBRARY
NAMES gstreamer-${GSTREAMER_ABI_VERSION}
HINTS ${PKG_GSTREAMER_LIBRARY_DIRS} ${PKG_GSTREAMER_LIBDIR})
find_path(GSTREAMER_INCLUDE_DIR
gst/gst.h
HINTS ${PKG_GSTREAMER_INCLUDE_DIRS} ${PKG_GSTREAMER_INCLUDEDIR}
PATH_SUFFIXES gstreamer-${GSTREAMER_ABI_VERSION})
if (PKG_GSTREAMER_PLUGIN_DIR)
set(_GSTREAMER_PLUGIN_DIR ${PKG_GSTREAMER_PLUGIN_DIR})
else()
get_filename_component(_GSTREAMER_LIB_DIR ${GSTREAMER_LIBRARY} PATH)
set(_GSTREAMER_PLUGIN_DIR ${_GSTREAMER_LIB_DIR}/gstreamer-${GSTREAMER_ABI_VERSION})
endif()
set(GSTREAMER_PLUGIN_DIR ${_GSTREAMER_PLUGIN_DIR}
CACHE PATH "The path to the gstreamer plugins installation directory")
mark_as_advanced(GSTREAMER_LIBRARY GSTREAMER_INCLUDE_DIR GSTREAMER_PLUGIN_DIR)
# Find additional libraries
include(MacroFindGStreamerLibrary)
macro(_find_gst_component _name _header)
find_gstreamer_library(${_name} ${_header} ${GSTREAMER_ABI_VERSION})
set(_GSTREAMER_EXTRA_VARIABLES ${_GSTREAMER_EXTRA_VARIABLES}
GSTREAMER_${_name}_LIBRARY GSTREAMER_${_name}_INCLUDE_DIR)
endmacro()
foreach(_component ${GStreamer_FIND_COMPONENTS})
if (${_component} STREQUAL "base")
_find_gst_component(BASE gstbasesink.h)
elseif (${_component} STREQUAL "check")
_find_gst_component(CHECK gstcheck.h)
elseif (${_component} STREQUAL "controller")
_find_gst_component(CONTROLLER gstargbcontrolbinding.h)
elseif (${_component} STREQUAL "net")
_find_gst_component(NET gstnet.h)
else()
message (AUTHOR_WARNING "FindGStreamerPluginsBase.cmake: Invalid component \"${_component}\" was specified")
endif()
endforeach()
# Version check
if (GStreamer_FIND_VERSION)
if (PKG_GSTREAMER_FOUND)
if("${PKG_GSTREAMER_VERSION}" VERSION_LESS "${GStreamer_FIND_VERSION}")
message(STATUS "Found GStreamer version ${PKG_GSTREAMER_VERSION}, but at least version ${GStreamer_FIND_VERSION} is required")
set(GSTREAMER_VERSION_COMPATIBLE FALSE)
else()
set(GSTREAMER_VERSION_COMPATIBLE TRUE)
endif()
elseif(GSTREAMER_INCLUDE_DIR)
include(CheckCXXSourceCompiles)
set(CMAKE_REQUIRED_INCLUDES ${GSTREAMER_INCLUDE_DIR})
string(REPLACE "." "," _comma_version ${GStreamer_FIND_VERSION})
# Hack to invalidate the cached value
set(GSTREAMER_VERSION_COMPATIBLE GSTREAMER_VERSION_COMPATIBLE)
check_cxx_source_compiles("
#define G_BEGIN_DECLS
#define G_END_DECLS
#include <gst/gstversion.h>
#if GST_CHECK_VERSION(${_comma_version})
int main() { return 0; }
#else
# error \"GStreamer version incompatible\"
#endif
" GSTREAMER_VERSION_COMPATIBLE)
if (NOT GSTREAMER_VERSION_COMPATIBLE)
message(STATUS "GStreamer ${GStreamer_FIND_VERSION} is required, but the version found is older")
endif()
else()
# We didn't find gstreamer at all
set(GSTREAMER_VERSION_COMPATIBLE FALSE)
endif()
else()
# No version constrain was specified, thus we consider the version compatible
set(GSTREAMER_VERSION_COMPATIBLE TRUE)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GStreamer DEFAULT_MSG
GSTREAMER_LIBRARY GSTREAMER_INCLUDE_DIR
GSTREAMER_VERSION_COMPATIBLE ${_GSTREAMER_EXTRA_VARIABLES})

View File

@@ -0,0 +1,90 @@
# - Try to find gst-plugins-base
# Once done this will define
#
# GSTREAMER_PLUGINS_BASE_FOUND - system has gst-plugins-base
#
# And for all the plugin libraries specified in the COMPONENTS
# of find_package, this module will define:
#
# GSTREAMER_<plugin_lib>_LIBRARY_FOUND - system has <plugin_lib>
# GSTREAMER_<plugin_lib>_LIBRARY - the <plugin_lib> library
# GSTREAMER_<plugin_lib>_INCLUDE_DIR - the <plugin_lib> include directory
#
# Copyright (c) 2010, Collabora Ltd.
# @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
set(GSTREAMER_ABI_VERSION "1.0")
# Find the pkg-config file for doing the version check
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PKG_GSTREAMER_PLUGINS_BASE gstreamer-plugins-base-${GSTREAMER_ABI_VERSION})
endif()
# Find the plugin libraries
include(MacroFindGStreamerLibrary)
macro(_find_gst_plugins_base_component _name _header)
find_gstreamer_library(${_name} ${_header} ${GSTREAMER_ABI_VERSION})
set(_GSTREAMER_PLUGINS_BASE_EXTRA_VARIABLES ${_GSTREAMER_PLUGINS_BASE_EXTRA_VARIABLES}
GSTREAMER_${_name}_LIBRARY GSTREAMER_${_name}_INCLUDE_DIR)
endmacro()
foreach(_component ${GStreamerPluginsBase_FIND_COMPONENTS})
if (${_component} STREQUAL "app")
_find_gst_plugins_base_component(APP gstappsrc.h)
elseif (${_component} STREQUAL "audio")
_find_gst_plugins_base_component(AUDIO audio.h)
elseif (${_component} STREQUAL "fft")
_find_gst_plugins_base_component(FFT gstfft.h)
elseif (${_component} STREQUAL "riff")
_find_gst_plugins_base_component(RIFF riff-ids.h)
elseif (${_component} STREQUAL "rtp")
_find_gst_plugins_base_component(RTP gstrtpbuffer.h)
elseif (${_component} STREQUAL "rtsp")
_find_gst_plugins_base_component(RTSP gstrtspdefs.h)
elseif (${_component} STREQUAL "sdp")
_find_gst_plugins_base_component(SDP gstsdp.h)
elseif (${_component} STREQUAL "tag")
_find_gst_plugins_base_component(TAG tag.h)
elseif (${_component} STREQUAL "pbutils")
_find_gst_plugins_base_component(PBUTILS pbutils.h)
elseif (${_component} STREQUAL "video")
_find_gst_plugins_base_component(VIDEO video.h)
elseif (${_component} STREQUAL "gl")
_find_gst_plugins_base_component(GL gstglconfig.h)
else()
message (AUTHOR_WARNING "FindGStreamer.cmake: Invalid component \"${_component}\" was specified")
endif()
endforeach()
# Version check
if (GStreamerPluginsBase_FIND_VERSION)
if (PKG_GSTREAMER_PLUGINS_BASE_FOUND)
if("${PKG_GSTREAMER_PLUGINS_BASE_VERSION}" VERSION_LESS "${GStreamerPluginsBase_FIND_VERSION}")
message(STATUS "Found gst-plugins-base version ${PKG_GSTREAMER_PLUGINS_BASE_VERSION}, but at least version ${GStreamerPluginsBase_FIND_VERSION} is required")
set(GSTREAMER_PLUGINS_BASE_VERSION_COMPATIBLE FALSE)
else()
set(GSTREAMER_PLUGINS_BASE_VERSION_COMPATIBLE TRUE)
endif()
else()
# We can't make any version checks without pkg-config, just assume version is compatible and hope...
set(GSTREAMER_PLUGINS_BASE_VERSION_COMPATIBLE TRUE)
endif()
else()
# No version constrain was specified, thus we consider the version compatible
set(GSTREAMER_PLUGINS_BASE_VERSION_COMPATIBLE TRUE)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GStreamerPluginsBase DEFAULT_MSG
GSTREAMER_PLUGINS_BASE_VERSION_COMPATIBLE
${_GSTREAMER_PLUGINS_BASE_EXTRA_VARIABLES})

View File

@@ -0,0 +1,57 @@
# - macro find_gstreamer_library
#
# Copyright (c) 2010, Collabora Ltd.
# @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
macro(find_gstreamer_library _name _header _abi_version)
string(TOLOWER ${_name} _lower_name)
string(TOUPPER ${_name} _upper_name)
if (GSTREAMER_${_upper_name}_LIBRARY AND GSTREAMER_${_upper_name}_INCLUDE_DIR)
set(_GSTREAMER_${_upper_name}_QUIET TRUE)
else()
set(_GSTREAMER_${_upper_name}_QUIET FALSE)
endif()
if (PKG_CONFIG_FOUND)
pkg_check_modules(PKG_GSTREAMER_${_upper_name} gstreamer-${_lower_name}-${_abi_version})
endif()
find_library(GSTREAMER_${_upper_name}_LIBRARY
NAMES gst${_lower_name}-${_abi_version}
HINTS ${PKG_GSTREAMER_${_upper_name}_LIBRARY_DIRS}
${PKG_GSTREAMER_${_upper_name}_LIBDIR}
)
find_path(GSTREAMER_${_upper_name}_INCLUDE_DIR
gst/${_lower_name}/${_header}
HINTS ${PKG_GSTREAMER_${_upper_name}_INCLUDE_DIRS}
${PKG_GSTREAMER_${_upper_name}_INCLUDEDIR}
PATH_SUFFIXES gstreamer-${_abi_version}
)
if (GSTREAMER_${_upper_name}_LIBRARY AND GSTREAMER_${_upper_name}_INCLUDE_DIR)
set(GSTREAMER_${_upper_name}_LIBRARY_FOUND TRUE)
else()
set(GSTREAMER_${_upper_name}_LIBRARY_FOUND FALSE)
endif()
if (NOT _GSTREAMER_${_upper_name}_QUIET)
if (GSTREAMER_${_upper_name}_LIBRARY)
message(STATUS "Found GSTREAMER_${_upper_name}_LIBRARY: ${GSTREAMER_${_upper_name}_LIBRARY}")
else()
message(STATUS "Could NOT find GSTREAMER_${_upper_name}_LIBRARY")
endif()
if (GSTREAMER_${_upper_name}_INCLUDE_DIR)
message(STATUS "Found GSTREAMER_${_upper_name}_INCLUDE_DIR: ${GSTREAMER_${_upper_name}_INCLUDE_DIR}")
else()
message(STATUS "Could NOT find GSTREAMER_${_upper_name}_INCLUDE_DIR")
endif()
endif()
mark_as_advanced(GSTREAMER_${_upper_name}_LIBRARY GSTREAMER_${_upper_name}_INCLUDE_DIR)
endmacro()

View File

@@ -0,0 +1,146 @@
# This file defines the Feature Logging macros.
#
# MACRO_LOG_FEATURE(VAR FEATURE DESCRIPTION URL [REQUIRED [MIN_VERSION [COMMENTS]]])
# Logs the information so that it can be displayed at the end
# of the configure run
# VAR : TRUE or FALSE, indicating whether the feature is supported
# FEATURE: name of the feature, e.g. "libjpeg"
# DESCRIPTION: description what this feature provides
# URL: home page
# REQUIRED: TRUE or FALSE, indicating whether the featue is required
# MIN_VERSION: minimum version number. empty string if unneeded
# COMMENTS: More info you may want to provide. empty string if unnecessary
#
# MACRO_DISPLAY_FEATURE_LOG()
# Call this to display the collected results.
# Exits CMake with a FATAL error message if a required feature is missing
#
# Example:
#
# INCLUDE(MacroLogFeature)
#
# FIND_PACKAGE(JPEG)
# MACRO_LOG_FEATURE(JPEG_FOUND "libjpeg" "Support JPEG images" "http://www.ijg.org" TRUE "3.2a" "")
# ...
# MACRO_DISPLAY_FEATURE_LOG()
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
# Copyright (c) 2006, Allen Winter, <winter@kde.org>
# Copyright (c) 2009, Sebastian Trueg, <trueg@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
IF (NOT _macroLogFeatureAlreadyIncluded)
SET(_file ${CMAKE_BINARY_DIR}/MissingRequirements.txt)
IF (EXISTS ${_file})
FILE(REMOVE ${_file})
ENDIF (EXISTS ${_file})
SET(_file ${CMAKE_BINARY_DIR}/EnabledFeatures.txt)
IF (EXISTS ${_file})
FILE(REMOVE ${_file})
ENDIF (EXISTS ${_file})
SET(_file ${CMAKE_BINARY_DIR}/DisabledFeatures.txt)
IF (EXISTS ${_file})
FILE(REMOVE ${_file})
ENDIF (EXISTS ${_file})
SET(_macroLogFeatureAlreadyIncluded TRUE)
ENDIF (NOT _macroLogFeatureAlreadyIncluded)
MACRO(MACRO_LOG_FEATURE _var _package _description _url ) # _required _minvers _comments)
STRING(TOUPPER "${ARGV4}" _required)
SET(_minvers "${ARGV5}")
SET(_comments "${ARGV6}")
IF (${_var})
SET(_LOGFILENAME ${CMAKE_BINARY_DIR}/EnabledFeatures.txt)
ELSE (${_var})
IF ("${_required}" STREQUAL "TRUE")
SET(_LOGFILENAME ${CMAKE_BINARY_DIR}/MissingRequirements.txt)
ELSE ("${_required}" STREQUAL "TRUE")
SET(_LOGFILENAME ${CMAKE_BINARY_DIR}/DisabledFeatures.txt)
ENDIF ("${_required}" STREQUAL "TRUE")
ENDIF (${_var})
SET(_logtext " * ${_package}")
IF (NOT ${_var})
IF (${_minvers} MATCHES ".*")
SET(_logtext "${_logtext} (${_minvers} or higher)")
ENDIF (${_minvers} MATCHES ".*")
SET(_logtext "${_logtext} <${_url}>\n ")
ELSE (NOT ${_var})
SET(_logtext "${_logtext} - ")
ENDIF (NOT ${_var})
SET(_logtext "${_logtext}${_description}")
IF (NOT ${_var})
IF (${_comments} MATCHES ".*")
SET(_logtext "${_logtext}\n ${_comments}")
ENDIF (${_comments} MATCHES ".*")
# SET(_logtext "${_logtext}\n") #double-space missing features?
ENDIF (NOT ${_var})
FILE(APPEND "${_LOGFILENAME}" "${_logtext}\n")
ENDMACRO(MACRO_LOG_FEATURE)
MACRO(MACRO_DISPLAY_FEATURE_LOG)
SET(_missingFile ${CMAKE_BINARY_DIR}/MissingRequirements.txt)
SET(_enabledFile ${CMAKE_BINARY_DIR}/EnabledFeatures.txt)
SET(_disabledFile ${CMAKE_BINARY_DIR}/DisabledFeatures.txt)
IF (EXISTS ${_missingFile} OR EXISTS ${_enabledFile} OR EXISTS ${_disabledFile})
SET(_printSummary TRUE)
ENDIF (EXISTS ${_missingFile} OR EXISTS ${_enabledFile} OR EXISTS ${_disabledFile})
IF(_printSummary)
SET(_missingDeps 0)
IF (EXISTS ${_enabledFile})
FILE(READ ${_enabledFile} _enabled)
FILE(REMOVE ${_enabledFile})
SET(_summary "${_summary}\n-----------------------------------------------------------------------------\n-- The following external packages were located on your system.\n-- This installation will have the extra features provided by these packages.\n-----------------------------------------------------------------------------\n${_enabled}")
ENDIF (EXISTS ${_enabledFile})
IF (EXISTS ${_disabledFile})
SET(_missingDeps 1)
FILE(READ ${_disabledFile} _disabled)
FILE(REMOVE ${_disabledFile})
SET(_summary "${_summary}\n-----------------------------------------------------------------------------\n-- The following OPTIONAL packages could NOT be located on your system.\n-- Consider installing them to enable more features from this software.\n-----------------------------------------------------------------------------\n${_disabled}")
ENDIF (EXISTS ${_disabledFile})
IF (EXISTS ${_missingFile})
SET(_missingDeps 1)
FILE(READ ${_missingFile} _requirements)
SET(_summary "${_summary}\n-----------------------------------------------------------------------------\n-- The following REQUIRED packages could NOT be located on your system.\n-- You must install these packages before continuing.\n-----------------------------------------------------------------------------\n${_requirements}")
FILE(REMOVE ${_missingFile})
SET(_haveMissingReq 1)
ENDIF (EXISTS ${_missingFile})
IF (NOT ${_missingDeps})
SET(_summary "${_summary}\n-----------------------------------------------------------------------------\n-- Congratulations! All external packages have been found.")
ENDIF (NOT ${_missingDeps})
MESSAGE(${_summary})
MESSAGE("-----------------------------------------------------------------------------\n")
IF(_haveMissingReq)
MESSAGE(FATAL_ERROR "Exiting: Missing Requirements")
ENDIF(_haveMissingReq)
ENDIF(_printSummary)
ENDMACRO(MACRO_DISPLAY_FEATURE_LOG)