summaryrefslogtreecommitdiffstats
path: root/cmake/macros
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cmake/macros/BuildTargetScript.cmake57
-rw-r--r--cmake/macros/CompileGResources.cmake231
-rw-r--r--cmake/macros/GenerateGXML.cmake124
-rw-r--r--cmake/macros/GlibCompileResourcesSupport.cmake11
-rw-r--r--cmake/macros/TargetArch.cmake169
5 files changed, 592 insertions, 0 deletions
diff --git a/cmake/macros/BuildTargetScript.cmake b/cmake/macros/BuildTargetScript.cmake
new file mode 100644
index 0000000..7243449
--- /dev/null
+++ b/cmake/macros/BuildTargetScript.cmake
@@ -0,0 +1,57 @@
+# This file is used to be invoked at build time. It generates the needed
+# resource XML file.
+
+# Input variables that need to provided when invoking this script:
+# GXML_OUTPUT The output file path where to save the XML file.
+# GXML_COMPRESS_ALL Sets all COMPRESS flags in all resources in resource
+# list.
+# GXML_NO_COMPRESS_ALL Removes all COMPRESS flags in all resources in
+# resource list.
+# GXML_STRIPBLANKS_ALL Sets all STRIPBLANKS flags in all resources in
+# resource list.
+# GXML_NO_STRIPBLANKS_ALL Removes all STRIPBLANKS flags in all resources in
+# resource list.
+# GXML_TOPIXDATA_ALL Sets all TOPIXDATA flags i nall resources in resource
+# list.
+# GXML_NO_TOPIXDATA_ALL Removes all TOPIXDATA flags in all resources in
+# resource list.
+# GXML_PREFIX Overrides the resource prefix that is prepended to
+# each relative name in registered resources.
+# GXML_RESOURCES The list of resource files. Whether absolute or
+# relative path is equal.
+
+# Include the GENERATE_GXML() function.
+include(${CMAKE_CURRENT_LIST_DIR}/GenerateGXML.cmake)
+
+# Set flags to actual invocation flags.
+if(GXML_COMPRESS_ALL)
+ set(GXML_COMPRESS_ALL COMPRESS_ALL)
+endif()
+if(GXML_NO_COMPRESS_ALL)
+ set(GXML_NO_COMPRESS_ALL NO_COMPRESS_ALL)
+endif()
+if(GXML_STRIPBLANKS_ALL)
+ set(GXML_STRIPBLANKS_ALL STRIPBLANKS_ALL)
+endif()
+if(GXML_NO_STRIPBLANKS_ALL)
+ set(GXML_NO_STRIPBLANKS_ALL NO_STRIPBLANKS_ALL)
+endif()
+if(GXML_TOPIXDATA_ALL)
+ set(GXML_TOPIXDATA_ALL TOPIXDATA_ALL)
+endif()
+if(GXML_NO_TOPIXDATA_ALL)
+ set(GXML_NO_TOPIXDATA_ALL NO_TOPIXDATA_ALL)
+endif()
+
+# Replace " " with ";" to import the list over the command line. Otherwise
+# CMake would interprete the passed resources as a whole string.
+string(REPLACE " " ";" GXML_RESOURCES ${GXML_RESOURCES})
+
+# Invoke the gresource XML generation function.
+generate_gxml(${GXML_OUTPUT}
+ ${GXML_COMPRESS_ALL} ${GXML_NO_COMPRESS_ALL}
+ ${GXML_STRIPBLANKS_ALL} ${GXML_NO_STRIPBLANKS_ALL}
+ ${GXML_TOPIXDATA_ALL} ${GXML_NO_TOPIXDATA_ALL}
+ PREFIX ${GXML_PREFIX}
+ RESOURCES ${GXML_RESOURCES})
+
diff --git a/cmake/macros/CompileGResources.cmake b/cmake/macros/CompileGResources.cmake
new file mode 100644
index 0000000..fd7c6b3
--- /dev/null
+++ b/cmake/macros/CompileGResources.cmake
@@ -0,0 +1,231 @@
+include(CMakeParseArguments)
+
+# Path to this file.
+set(GCR_CMAKE_MACRO_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+# Compiles a gresource resource file from given resource files. Automatically
+# creates the XML controlling file.
+# The type of resource to generate (header, c-file or bundle) is automatically
+# determined from TARGET file ending, if no TYPE is explicitly specified.
+# The output file is stored in the provided variable "output".
+# "xml_out" contains the variable where to output the XML path. Can be used to
+# create custom targets or doing postprocessing.
+# If you want to use preprocessing, you need to manually check the existence
+# of the tools you use. This function doesn't check this for you, it just
+# generates the XML file. glib-compile-resources will then throw a
+# warning/error.
+function(COMPILE_GRESOURCES output xml_out)
+ # Available options:
+ # COMPRESS_ALL, NO_COMPRESS_ALL Overrides the COMPRESS flag in all
+ # registered resources.
+ # STRIPBLANKS_ALL, NO_STRIPBLANKS_ALL Overrides the STRIPBLANKS flag in all
+ # registered resources.
+ # TOPIXDATA_ALL, NO_TOPIXDATA_ALL Overrides the TOPIXDATA flag in all
+ # registered resources.
+ set(CG_OPTIONS COMPRESS_ALL NO_COMPRESS_ALL
+ STRIPBLANKS_ALL NO_STRIPBLANKS_ALL
+ TOPIXDATA_ALL NO_TOPIXDATA_ALL)
+
+ # Available one value options:
+ # TYPE Type of resource to create. Valid options are:
+ # EMBED_C: A C-file that can be compiled with your project.
+ # EMBED_H: A header that can be included into your project.
+ # BUNDLE: Generates a resource bundle file that can be loaded
+ # at runtime.
+ # AUTO: Determine from target file ending. Need to specify
+ # target argument.
+ # PREFIX Overrides the resource prefix that is prepended to each
+ # relative file name in registered resources.
+ # SOURCE_DIR Overrides the resources base directory to search for resources.
+ # Normally this is set to the source directory with that CMake
+ # was invoked (CMAKE_CURRENT_SOURCE_DIR).
+ # TARGET Overrides the name of the output file/-s. Normally the output
+ # names from glib-compile-resources tool is taken.
+ set(CG_ONEVALUEARGS TYPE PREFIX SOURCE_DIR TARGET)
+
+ # Available multi-value options:
+ # RESOURCES The list of resource files. Whether absolute or relative path is
+ # equal, absolute paths are stripped down to relative ones. If the
+ # absolute path is not inside the given base directory SOURCE_DIR
+ # or CMAKE_CURRENT_SOURCE_DIR (if SOURCE_DIR is not overriden),
+ # this function aborts.
+ # OPTIONS Extra command line options passed to glib-compile-resources.
+ set(CG_MULTIVALUEARGS RESOURCES OPTIONS)
+
+ # Parse the arguments.
+ cmake_parse_arguments(CG_ARG
+ "${CG_OPTIONS}"
+ "${CG_ONEVALUEARGS}"
+ "${CG_MULTIVALUEARGS}"
+ "${ARGN}")
+
+ # Variable to store the double-quote (") string. Since escaping
+ # double-quotes in strings is not possible we need a helper variable that
+ # does this job for us.
+ set(Q \")
+
+ # Check invocation validity with the <prefix>_UNPARSED_ARGUMENTS variable.
+ # If other not recognized parameters were passed, throw error.
+ if (CG_ARG_UNPARSED_ARGUMENTS)
+ set(CG_WARNMSG "Invocation of COMPILE_GRESOURCES with unrecognized")
+ set(CG_WARNMSG "${CG_WARNMSG} parameters. Parameters are:")
+ set(CG_WARNMSG "${CG_WARNMSG} ${CG_ARG_UNPARSED_ARGUMENTS}.")
+ message(WARNING ${CG_WARNMSG})
+ endif()
+
+ # Check invocation validity depending on generation mode (EMBED_C, EMBED_H
+ # or BUNDLE).
+ if ("${CG_ARG_TYPE}" STREQUAL "EMBED_C")
+ # EMBED_C mode, output compilable C-file.
+ set(CG_GENERATE_COMMAND_LINE "--generate-source")
+ set(CG_TARGET_FILE_ENDING "c")
+ elseif ("${CG_ARG_TYPE}" STREQUAL "EMBED_H")
+ # EMBED_H mode, output includable header file.
+ set(CG_GENERATE_COMMAND_LINE "--generate-header")
+ set(CG_TARGET_FILE_ENDING "h")
+ elseif ("${CG_ARG_TYPE}" STREQUAL "BUNDLE")
+ # BUNDLE mode, output resource bundle. Don't do anything since
+ # glib-compile-resources outputs a bundle when not specifying
+ # something else.
+ set(CG_TARGET_FILE_ENDING "gresource")
+ else()
+ # Everything else is AUTO mode, determine from target file ending.
+ if (CG_ARG_TARGET)
+ set(CG_GENERATE_COMMAND_LINE "--generate")
+ else()
+ set(CG_ERRMSG "AUTO mode given, but no target specified. Can't")
+ set(CG_ERRMSG "${CG_ERRMSG} determine output type. In function")
+ set(CG_ERRMSG "${CG_ERRMSG} COMPILE_GRESOURCES.")
+ message(FATAL_ERROR ${CG_ERRMSG})
+ endif()
+ endif()
+
+ # Check flag validity.
+ if (CG_ARG_COMPRESS_ALL AND CG_ARG_NO_COMPRESS_ALL)
+ set(CG_ERRMSG "COMPRESS_ALL and NO_COMPRESS_ALL simultaneously set. In")
+ set(CG_ERRMSG "${CG_ERRMSG} function COMPILE_GRESOURCES.")
+ message(FATAL_ERROR ${CG_ERRMSG})
+ endif()
+ if (CG_ARG_STRIPBLANKS_ALL AND CG_ARG_NO_STRIPBLANKS_ALL)
+ set(CG_ERRMSG "STRIPBLANKS_ALL and NO_STRIPBLANKS_ALL simultaneously")
+ set(CG_ERRMSG "${CG_ERRMSG} set. In function COMPILE_GRESOURCES.")
+ message(FATAL_ERROR ${CG_ERRMSG})
+ endif()
+ if (CG_ARG_TOPIXDATA_ALL AND CG_ARG_NO_TOPIXDATA_ALL)
+ set(CG_ERRMSG "TOPIXDATA_ALL and NO_TOPIXDATA_ALL simultaneously set.")
+ set(CG_ERRMSG "${CG_ERRMSG} In function COMPILE_GRESOURCES.")
+ message(FATAL_ERROR ${CG_ERRMSG})
+ endif()
+
+ # Check if there are any resources.
+ if (NOT CG_ARG_RESOURCES)
+ set(CG_ERRMSG "No resource files to process. In function")
+ set(CG_ERRMSG "${CG_ERRMSG} COMPILE_GRESOURCES.")
+ message(FATAL_ERROR ${CG_ERRMSG})
+ endif()
+
+ # Extract all dependencies for targets from resource list.
+ foreach(res ${CG_ARG_RESOURCES})
+ if (NOT(("${res}" STREQUAL "COMPRESS") OR
+ ("${res}" STREQUAL "STRIPBLANKS") OR
+ ("${res}" STREQUAL "TOPIXDATA")))
+
+ list(APPEND CG_RESOURCES_DEPENDENCIES "${res}")
+ endif()
+ endforeach()
+
+
+ # Create source directory automatically if not set.
+ if (NOT CG_ARG_SOURCE_DIR)
+ set(CG_ARG_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+ endif()
+
+ # Replace paths
+ foreach(res ${CG_ARG_RESOURCES})
+ if (NOT(("${res}" STREQUAL "COMPRESS") OR
+ ("${res}" STREQUAL "STRIPBLANKS") OR
+ ("${res}" STREQUAL "TOPIXDATA")))
+
+ string(REPLACE "${CG_ARG_SOURCE_DIR}/" "" RES_FILTERED "${res}")
+ list(APPEND CG_RESOURCES_FILTERED "${RES_FILTERED}")
+ else()
+ list(APPEND CG_RESOURCES_FILTERED "${res}")
+ endif()
+ endforeach()
+
+ # Construct .gresource.xml path.
+ set(CG_XML_FILE_PATH "${CMAKE_CURRENT_BINARY_DIR}/.gresource.xml")
+
+ # Generate gresources XML target.
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "-D")
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "GXML_OUTPUT=${Q}${CG_XML_FILE_PATH}${Q}")
+ if(CG_ARG_COMPRESS_ALL)
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "-D")
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "GXML_COMPRESS_ALL")
+ endif()
+ if(CG_ARG_NO_COMPRESS_ALL)
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "-D")
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "GXML_NO_COMPRESS_ALL")
+ endif()
+ if(CG_ARG_STRPIBLANKS_ALL)
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "-D")
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "GXML_STRIPBLANKS_ALL")
+ endif()
+ if(CG_ARG_NO_STRIPBLANKS_ALL)
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "-D")
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "GXML_NO_STRIPBLANKS_ALL")
+ endif()
+ if(CG_ARG_TOPIXDATA_ALL)
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "-D")
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "GXML_TOPIXDATA_ALL")
+ endif()
+ if(CG_ARG_NO_TOPIXDATA_ALL)
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "-D")
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "GXML_NO_TOPIXDATA_ALL")
+ endif()
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "-D")
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "GXML_PREFIX=${Q}${CG_ARG_PREFIX}${Q}")
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "-D")
+ list(APPEND CG_CMAKE_SCRIPT_ARGS
+ "GXML_RESOURCES=${Q}${CG_RESOURCES_FILTERED}${Q}")
+ list(APPEND CG_CMAKE_SCRIPT_ARGS "-P")
+ list(APPEND CG_CMAKE_SCRIPT_ARGS
+ "${Q}${GCR_CMAKE_MACRO_DIR}/BuildTargetScript.cmake${Q}")
+
+ get_filename_component(CG_XML_FILE_PATH_ONLY_NAME
+ "${CG_XML_FILE_PATH}" NAME)
+ set(CG_XML_CUSTOM_COMMAND_COMMENT
+ "Creating gresources XML file (${CG_XML_FILE_PATH_ONLY_NAME})")
+ add_custom_command(OUTPUT ${CG_XML_FILE_PATH}
+ COMMAND ${CMAKE_COMMAND}
+ ARGS ${CG_CMAKE_SCRIPT_ARGS}
+ DEPENDS ${CG_RESOURCES_DEPENDENCIES}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT ${CG_XML_CUSTOM_COMMAND_COMMENT})
+
+ # Create target manually if not set (to make sure glib-compile-resources
+ # doesn't change behaviour with it's naming standards).
+ if (NOT CG_ARG_TARGET)
+ set(CG_ARG_TARGET "${CMAKE_CURRENT_BINARY_DIR}/resources")
+ set(CG_ARG_TARGET "${CG_ARG_TARGET}.${CG_TARGET_FILE_ENDING}")
+ endif()
+
+
+ # Add compilation target for resources.
+ add_custom_command(OUTPUT ${CG_ARG_TARGET}
+ COMMAND ${GLIB_COMPILE_RESOURCES_EXECUTABLE}
+ ARGS
+ ${OPTIONS}
+ "--target=${Q}${CG_ARG_TARGET}${Q}"
+ "--sourcedir=${Q}${CG_ARG_SOURCE_DIR}${Q}"
+ ${CG_GENERATE_COMMAND_LINE}
+ ${CG_XML_FILE_PATH}
+ MAIN_DEPENDENCY ${CG_XML_FILE_PATH}
+ DEPENDS ${CG_RESOURCES_DEPENDENCIES}
+ WORKING_DIRECTORY ${CMAKE_BUILD_DIR})
+
+ # Set output and XML_OUT to parent scope.
+ set(${xml_out} ${CG_XML_FILE_PATH} PARENT_SCOPE)
+ set(${output} ${CG_ARG_TARGET} PARENT_SCOPE)
+
+endfunction()
diff --git a/cmake/macros/GenerateGXML.cmake b/cmake/macros/GenerateGXML.cmake
new file mode 100644
index 0000000..b3f1a30
--- /dev/null
+++ b/cmake/macros/GenerateGXML.cmake
@@ -0,0 +1,124 @@
+include(CMakeParseArguments)
+
+# Generates the resource XML controlling file from resource list (and saves it
+# to xml_path). It's not recommended to use this function directly, since it
+# doesn't handle invalid arguments. It is used by the function
+# COMPILE_GRESOURCES() to create a custom command, so that this function is
+# invoked at build-time in script mode from CMake.
+function(GENERATE_GXML xml_path)
+ # Available options:
+ # COMPRESS_ALL, NO_COMPRESS_ALL Overrides the COMPRESS flag in all
+ # registered resources.
+ # STRIPBLANKS_ALL, NO_STRIPBLANKS_ALL Overrides the STRIPBLANKS flag in all
+ # registered resources.
+ # TOPIXDATA_ALL, NO_TOPIXDATA_ALL Overrides the TOPIXDATA flag in all
+ # registered resources.
+ set(GXML_OPTIONS COMPRESS_ALL NO_COMPRESS_ALL
+ STRIPBLANKS_ALL NO_STRIPBLANKS_ALL
+ TOPIXDATA_ALL NO_TOPIXDATA_ALL)
+
+ # Available one value options:
+ # PREFIX Overrides the resource prefix that is prepended to each
+ # relative file name in registered resources.
+ set(GXML_ONEVALUEARGS PREFIX)
+
+ # Available multi-value options:
+ # RESOURCES The list of resource files. Whether absolute or relative path is
+ # equal, absolute paths are stripped down to relative ones. If the
+ # absolute path is not inside the given base directory SOURCE_DIR
+ # or CMAKE_CURRENT_SOURCE_DIR (if SOURCE_DIR is not overriden),
+ # this function aborts.
+ set(GXML_MULTIVALUEARGS RESOURCES)
+
+ # Parse the arguments.
+ cmake_parse_arguments(GXML_ARG
+ "${GXML_OPTIONS}"
+ "${GXML_ONEVALUEARGS}"
+ "${GXML_MULTIVALUEARGS}"
+ "${ARGN}")
+
+ # Variable to store the double-quote (") string. Since escaping
+ # double-quotes in strings is not possible we need a helper variable that
+ # does this job for us.
+ set(Q \")
+
+ # Process resources and generate XML file.
+ # Begin with the XML header and header nodes.
+ set(GXML_XML_FILE "<?xml version=${Q}1.0${Q} encoding=${Q}UTF-8${Q}?>")
+ set(GXML_XML_FILE "${GXML_XML_FILE}<gresources><gresource prefix=${Q}")
+
+ # Set the prefix for the resources. Depending on the user-override we choose
+ # the standard prefix "/" or the override.
+ if (GXML_ARG_PREFIX)
+ set(GXML_XML_FILE "${GXML_XML_FILE}${GXML_ARG_PREFIX}")
+ else()
+ set(GXML_XML_FILE "${GXML_XML_FILE}/")
+ endif()
+
+ set(GXML_XML_FILE "${GXML_XML_FILE}${Q}>")
+
+ # Process each resource.
+ foreach(res ${GXML_ARG_RESOURCES})
+ if ("${res}" STREQUAL "COMPRESS")
+ set(GXML_COMPRESSION_FLAG ON)
+ elseif ("${res}" STREQUAL "STRIPBLANKS")
+ set(GXML_STRIPBLANKS_FLAG ON)
+ elseif ("${res}" STREQUAL "TOPIXDATA")
+ set(GXML_TOPIXDATA_FLAG ON)
+ else()
+ # The file name.
+ set(GXML_RESOURCE_PATH "${res}")
+
+ # Append to real resource file dependency list.
+ list(APPEND GXML_RESOURCES_DEPENDENCIES ${GXML_RESOURCE_PATH})
+
+ # Assemble <file> node.
+ set(GXML_RES_LINE "<file")
+ if ((GXML_ARG_COMPRESS_ALL OR GXML_COMPRESSION_FLAG) AND NOT
+ GXML_ARG_NO_COMPRESS_ALL)
+ set(GXML_RES_LINE "${GXML_RES_LINE} compressed=${Q}true${Q}")
+ endif()
+
+ # Check preprocess flag validity.
+ if ((GXML_ARG_STRIPBLANKS_ALL OR GXML_STRIPBLANKS_FLAG) AND
+ (GXML_ARG_TOPIXDATA_ALL OR GXML_TOPIXDATA_FLAG))
+ set(GXML_ERRMSG "Resource preprocessing option conflict. Tried")
+ set(GXML_ERRMSG "${GXML_ERRMSG} to specify both, STRIPBLANKS")
+ set(GXML_ERRMSG "${GXML_ERRMSG} and TOPIXDATA. In resource")
+ set(GXML_ERRMSG "${GXML_ERRMSG} ${GXML_RESOURCE_PATH} in")
+ set(GXML_ERRMSG "${GXML_ERRMSG} function COMPILE_GRESOURCES.")
+ message(FATAL_ERROR ${GXML_ERRMSG})
+ endif()
+
+ if ((GXML_ARG_STRIPBLANKS_ALL OR GXML_STRIPBLANKS_FLAG) AND NOT
+ GXML_ARG_NO_STRIPBLANKS_ALL)
+ set(GXML_RES_LINE "${GXML_RES_LINE} preprocess=")
+ set(GXML_RES_LINE "${GXML_RES_LINE}${Q}xml-stripblanks${Q}")
+ elseif((GXML_ARG_TOPIXDATA_ALL OR GXML_TOPIXDATA_FLAG) AND NOT
+ GXML_ARG_NO_TOPIXDATA_ALL)
+ set(GXML_RES_LINE "${GXML_RES_LINE} preprocess=")
+ set(GXML_RES_LINE "${GXML_RES_LINE}${Q}to-pixdata${Q}")
+ endif()
+
+ set(GXML_RES_LINE "${GXML_RES_LINE}>${GXML_RESOURCE_PATH}</file>")
+
+ # Append to file string.
+ set(GXML_XML_FILE "${GXML_XML_FILE}${GXML_RES_LINE}")
+
+ # Unset variables.
+ unset(GXML_COMPRESSION_FLAG)
+ unset(GXML_STRIPBLANKS_FLAG)
+ unset(GXML_TOPIXDATA_FLAG)
+ endif()
+
+ endforeach()
+
+ # Append closing nodes.
+ set(GXML_XML_FILE "${GXML_XML_FILE}</gresource></gresources>")
+
+ # Use "file" function to generate XML controlling file.
+ get_filename_component(xml_path_only_name "${xml_path}" NAME)
+ file(WRITE ${xml_path} ${GXML_XML_FILE})
+
+endfunction()
+
diff --git a/cmake/macros/GlibCompileResourcesSupport.cmake b/cmake/macros/GlibCompileResourcesSupport.cmake
new file mode 100644
index 0000000..2950af3
--- /dev/null
+++ b/cmake/macros/GlibCompileResourcesSupport.cmake
@@ -0,0 +1,11 @@
+# Path to this file.
+set(GCR_CMAKE_MACRO_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+# Finds the glib-compile-resources executable.
+find_program(GLIB_COMPILE_RESOURCES_EXECUTABLE glib-compile-resources)
+mark_as_advanced(GLIB_COMPILE_RESOURCES_EXECUTABLE)
+
+# Include the cmake files containing the functions.
+include(${GCR_CMAKE_MACRO_DIR}/CompileGResources.cmake)
+include(${GCR_CMAKE_MACRO_DIR}/GenerateGXML.cmake)
+
diff --git a/cmake/macros/TargetArch.cmake b/cmake/macros/TargetArch.cmake
new file mode 100644
index 0000000..ee144bc
--- /dev/null
+++ b/cmake/macros/TargetArch.cmake
@@ -0,0 +1,169 @@
+# Copyright (c) 2014 PCSX2 Dev Team
+# Copyright (c) 2012 Petroules Corporation. All rights reserved.
+#
+# 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.
+#
+# 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 OWNER 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.
+#
+# https://github.com/petroules/solar-cmake/blob/master/TargetArch.cmake
+#
+# Based on the Qt 5 processor detection code, so should be very accurate
+# https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h
+# Currently handles arm (v5, v6, v7), x86 (32/64), ia64, and ppc (32/64)
+
+# Regarding POWER/PowerPC, just as is noted in the Qt source,
+# "There are many more known variants/revisions that we do not handle/detect."
+
+set(archdetect_c_code "
+#if defined(__arm__) || defined(__TARGET_ARCH_ARM)
+ #if defined(__ARM_ARCH_7__) \\
+ || defined(__ARM_ARCH_7A__) \\
+ || defined(__ARM_ARCH_7R__) \\
+ || defined(__ARM_ARCH_7M__) \\
+ || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7)
+ #error cmake_ARCH armv7
+ #elif defined(__ARM_ARCH_6__) \\
+ || defined(__ARM_ARCH_6J__) \\
+ || defined(__ARM_ARCH_6T2__) \\
+ || defined(__ARM_ARCH_6Z__) \\
+ || defined(__ARM_ARCH_6K__) \\
+ || defined(__ARM_ARCH_6ZK__) \\
+ || defined(__ARM_ARCH_6M__) \\
+ || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6)
+ #error cmake_ARCH armv6
+ #elif defined(__ARM_ARCH_5TEJ__) \\
+ || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5)
+ #error cmake_ARCH armv5
+ #else
+ #error cmake_ARCH arm
+ #endif
+#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
+ #error cmake_ARCH i386
+#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
+ #error cmake_ARCH x86_64
+#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
+ #error cmake_ARCH ia64
+#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\
+ || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\
+ || defined(_M_MPPC) || defined(_M_PPC)
+ #if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
+ #error cmake_ARCH ppc64
+ #else
+ #error cmake_ARCH ppc
+ #endif
+#endif
+
+#error cmake_ARCH unknown
+")
+
+# Set ppc_support to TRUE before including this file or ppc and ppc64
+# will be treated as invalid architectures since they are no longer supported by Apple
+
+function(target_architecture output_var)
+ if(APPLE AND CMAKE_OSX_ARCHITECTURES)
+ # On OS X we use CMAKE_OSX_ARCHITECTURES *if* it was set
+ # First let's normalize the order of the values
+
+ # Note that it's not possible to compile PowerPC applications if you are using
+ # the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we
+ # disable it by default
+ # See this page for more information:
+ # http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4
+
+ # Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime.
+ # On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise.
+
+ LIST(LENGTH CMAKE_OSX_ARCHITECTURES osx_arch_num)
+ if(NOT (osx_arch_num EQUAL 1))
+ message(FATAL_ERROR "Currently ${CMAKE_PROJECT_NAME} does not support multiple architectures in CMAKE_OSX_ARCHITECTURES")
+ endif()
+
+ foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
+ if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
+ set(osx_arch_ppc TRUE)
+ elseif("${osx_arch}" STREQUAL "i386")
+ set(osx_arch_i386 TRUE)
+ elseif("${osx_arch}" STREQUAL "x86_64")
+ set(osx_arch_x86_64 TRUE)
+ elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
+ set(osx_arch_ppc64 TRUE)
+ else()
+ message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
+ endif()
+ endforeach()
+
+ # Now add all the architectures in our normalized order
+ if(osx_arch_ppc)
+ list(APPEND ARCH ppc)
+ endif()
+
+ if(osx_arch_i386)
+ list(APPEND ARCH i386)
+ endif()
+
+ if(osx_arch_x86_64)
+ list(APPEND ARCH x86_64)
+ endif()
+
+ if(osx_arch_ppc64)
+ list(APPEND ARCH ppc64)
+ endif()
+
+ LIST(LENGTH ARCH osx_arch_num)
+ if(osx_arch_num LESS 1)
+ message(FATAL_ERROR "Invalid CMAKE_OSX_ARCHITECTURES: ${CMAKE_OSX_ARCHITECTURES}")
+ endif()
+ else()
+ file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}")
+
+ enable_language(C)
+
+ # Detect the architecture in a rather creative way...
+ # This compiles a small C program which is a series of ifdefs that selects a
+ # particular #error preprocessor directive whose message string contains the
+ # target architecture. The program will always fail to compile (both because
+ # file is not a valid C program, and obviously because of the presence of the
+ # #error preprocessor directives... but by exploiting the preprocessor in this
+ # way, we can detect the correct target architecture even when cross-compiling,
+ # since the program itself never needs to be run (only the compiler/preprocessor)
+ try_run(
+ run_result_unused
+ compile_result_unused
+ "${CMAKE_BINARY_DIR}"
+ "${CMAKE_BINARY_DIR}/arch.c"
+ COMPILE_OUTPUT_VARIABLE ARCH
+ CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
+ )
+
+ # Parse the architecture name from the compiler output
+ string(REGEX MATCH "cmake_ARCH ([a-zA-Z0-9_]+)" ARCH "${ARCH}")
+
+ # Get rid of the value marker leaving just the architecture name
+ string(REPLACE "cmake_ARCH " "" ARCH "${ARCH}")
+
+ # If we are compiling with an unknown architecture this variable should
+ # already be set to "unknown" but in the case that it's empty (i.e. due
+ # to a typo in the code), then set it to unknown
+ if (NOT ARCH)
+ set(ARCH unknown)
+ endif()
+ endif()
+
+ set(${output_var} "${ARCH}" PARENT_SCOPE)
+endfunction()