code:
# - Try to find hamlib
#
# Once done, this will define:
#
#  hamlib_FOUND - system has Hamlib
#  hamlib_INCLUDE_DIRS - the Hamlib include directories
#  hamlib_LIBRARIES - link these to use Hamlib
#  hamlib_LIBRARY_DIRS - required shared/dynamic libraries are here
#
# If hamlib_STATIC is TRUE then static linking will be assumed
#

include (LibFindMacros)

set (hamlib_LIBRARY_DIRS)

# pkg-config?
find_path (__hamlib_pc_path NAMES hamlib.pc
  PATH_SUFFIXES lib/pkgconfig
  )
if (__hamlib_pc_path)
  set (ENV{PKG_CONFIG_PATH} "${__hamlib_pc_path}" "$ENV{PKG_CONFIG_PATH}")
  unset (__hamlib_pc_path CACHE)
endif ()

# Use pkg-config to get hints about paths, libs and, flags
unset (__pkg_config_checked_hamlib CACHE)
# pkg_config will fail on Windows if the Hamlib USB backends are
# configured since libusb-1.0 does not ship with a pkg_config file on
# Windows, that's OK because we fix it up below
libfind_pkg_check_modules (PC_HAMLIB hamlib)

if (NOT PC_HAMLIB_FOUND)
  # The headers
  find_path (hamlib_INCLUDEDIR hamlib/rig.h)
  # The libraries
  if (hamlib_STATIC)
    libfind_library (hamlib libhamlib.a)
  else ()
    libfind_library (hamlib hamlib)
  endif ()
  if (WIN32)
    set (hamlib_EXTRA_LIBRARIES ws2_32)
  else ()
    set (hamlib_EXTRA_LIBRARIES m dl)
  endif ()

  # libusb-1.0 has no pkg-config file on Windows so we have to find it
  # ourselves
  find_library (LIBUSB NAMES usb-1.0 PATH_SUFFIXES MinGW32/dll)
  if (LIBUSB)
    set (hamlib_EXTRA_LIBRARIES ${LIBUSB} ${hamlib_EXTRA_LIBRARIES})
    get_filename_component (hamlib_libusb_path ${LIBUSB} PATH)
    set (hamlib_LIBRARY_DIRS ${hamlib_LIBRARY_DIRS} ${hamlib_libusb_path})
  endif (LIBUSB)
  set (hamlib_PROCESS_INCLUDES hamlib_INCLUDEDIR)
  set (hamlib_PROCESS_LIBS hamlib_LIBRARY hamlib_EXTRA_LIBRARIES)
else ()
  if (hamlib_STATIC)
    set (hamlib_PROCESS_INCLUDES PC_HAMLIB_STATIC_INCLUDE_DIRS)
    set (hamlib_PROCESS_LIBS PC_HAMLIB_STATIC_LDFLAGS)
    set (hamlib_LIBRARY_DIRS ${PC_HAMLIB_STATIC_LIBRARY_DIRS})
  else ()
    set (hamlib_PROCESS_INCLUDES PC_HAMLIB_INCLUDE_DIRS)
    set (hamlib_PROCESS_LIBS PC_HAMLIB_LDFLAGS)
    set (hamlib_LIBRARY_DIRS ${PC_HAMLIB_LIBRARY_DIRS})
  endif ()
endif ()
libfind_process (hamlib)

if (WIN32)
  find_path (hamlib_dll_path libhamlib-2.dll)
  if (hamlib_dll_path)
    set (hamlib_LIBRARY_DIRS ${hamlib_LIBRARY_DIRS} ${hamlib_dll_path})
  endif ()
endif ()

# Handle the  QUIETLY and REQUIRED  arguments and set  HAMLIB_FOUND to
# TRUE if all listed variables are TRUE
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (hamlib DEFAULT_MSG hamlib_INCLUDE_DIRS hamlib_LIBRARIES hamlib_LIBRARY_DIRS)


code:
# - Returns a version string from Git
#
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
#
#  get_git_head_revision(<source_dir> <refspecvar> <hashvar> [<additional arguments to git describe> ...])
#
# Returns the refspec and sha hash of the current head revision
#
#  git_describe(<source-dir> <var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
#
#  git_get_exact_tag(<source-dir> <var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
#
#  git_local_changes(<source-dir> <var>)
#
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
# Uses the return code of "git diff-index --quiet HEAD --".
# Does not regard untracked files.
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)

if(__get_git_revision_description)
	return()
endif()
set(__get_git_revision_description YES)

# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)

function(get_git_head_revision _source_dir _refspecvar _hashvar)
	set(GIT_PARENT_DIR "${_source_dir}")
	set(GIT_DIR "${GIT_PARENT_DIR}/.git")
	while(NOT EXISTS "${GIT_DIR}")	# .git dir not found, search parent directories
		set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
		get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
		if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
			# We have reached the root directory, we are not in git
			set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
			set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
			return()
		endif()
		set(GIT_DIR "${GIT_PARENT_DIR}/.git")
	endwhile()
	# check if this is a submodule
	if(NOT IS_DIRECTORY ${GIT_DIR})
		file(READ ${GIT_DIR} submodule)
		string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
		get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
		get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
	endif()
	set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
	if(NOT EXISTS "${GIT_DATA}")
		file(MAKE_DIRECTORY "${GIT_DATA}")
	endif()

	if(NOT EXISTS "${GIT_DIR}/HEAD")
		return()
	endif()
	set(HEAD_FILE "${GIT_DATA}/HEAD")
	configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)

	configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
		"${GIT_DATA}/grabRef.cmake"
		@ONLY)
	include("${GIT_DATA}/grabRef.cmake")

	set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
	set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
endfunction()

function(git_describe _source_dir _var)
	if(NOT GIT_FOUND)
		find_package(Git QUIET)
	endif()
	get_git_head_revision(${_source_dir} refspec hash)
	if(NOT GIT_FOUND)
		set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
		return()
	endif()
	if(NOT hash)
		set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
		return()
	endif()

	# TODO sanitize
	#if((${ARGN}" MATCHES "&&") OR
	#	(ARGN MATCHES "||") OR
	#	(ARGN MATCHES "\\;"))
	#	message("Please report the following error to the project!")
	#	message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
	#endif()

	#message(STATUS "Arguments to execute_process: ${ARGN}")

	execute_process(COMMAND
		"${GIT_EXECUTABLE}"
		describe
		${hash}
		${ARGN}
		WORKING_DIRECTORY
		"${_source_dir}"
		RESULT_VARIABLE
		res
		OUTPUT_VARIABLE
		out
		ERROR_QUIET
		OUTPUT_STRIP_TRAILING_WHITESPACE)
	if(NOT res EQUAL 0)
		set(out "${out}-${res}-NOTFOUND")
	endif()

	set(${_var} "${out}" PARENT_SCOPE)
endfunction()

function(git_get_exact_tag _source_dir _var)
	git_describe(${_source_dir} out --exact-match ${ARGN})
	set(${_var} "${out}" PARENT_SCOPE)
endfunction()

function(git_local_changes _source_dir _var)
	if(NOT GIT_FOUND)
		find_package(Git QUIET)
	endif()
	get_git_head_revision(${_source_dir} refspec hash)
	if(NOT GIT_FOUND)
		set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
		return()
	endif()
	if(NOT hash)
		set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
		return()
	endif()

	execute_process(COMMAND
		"${GIT_EXECUTABLE}"
		diff-index --quiet HEAD --
		WORKING_DIRECTORY
		"${_source_dir}"
		RESULT_VARIABLE
		res
		OUTPUT_VARIABLE
		out
		ERROR_QUIET
		OUTPUT_STRIP_TRAILING_WHITESPACE)
	if(res EQUAL 0)
		set(${_var} "CLEAN" PARENT_SCOPE)
	else()
		set(${_var} "DIRTY" PARENT_SCOPE)
	endif()
endfunction()

license: mit


code:
#
# Internal file for GetGitRevisionDescription.cmake
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)

set(HEAD_HASH)

file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)

string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
	# named branch
	string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
	if(EXISTS "@GIT_DIR@/${HEAD_REF}")
		configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
	else()
		configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
		file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
		if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
			set(HEAD_HASH "${CMAKE_MATCH_1}")
		endif()
	endif()
else()
	# detached HEAD
	configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()

if(NOT HEAD_HASH)
	file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
	string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()


code:
#.rst:
# GetPrerequisites
# ----------------
#
# Functions to analyze and list executable file prerequisites.
#
# This module provides functions to list the .dll, .dylib or .so files
# that an executable or shared library file depends on.  (Its
# prerequisites.)
#
# It uses various tools to obtain the list of required shared library
# files:
#
# ::
#
#    dumpbin (Windows)
#    objdump (MinGW on Windows)
#    ldd (Linux/Unix)
#    otool (Mac OSX)
#
# The following functions are provided by this module:
#
# ::
#
#    get_prerequisites
#    list_prerequisites
#    list_prerequisites_by_glob
#    gp_append_unique
#    is_file_executable
#    gp_item_default_embedded_path
#      (projects can override with gp_item_default_embedded_path_override)
#    gp_resolve_item
#      (projects can override with gp_resolve_item_override)
#    gp_resolved_file_type
#      (projects can override with gp_resolved_file_type_override)
#    gp_file_type
#
# Requires CMake 2.6 or greater because it uses function, break, return
# and PARENT_SCOPE.
#
# ::
#
#   GET_PREREQUISITES(<target> <prerequisites_var> <exclude_system> <recurse>
#                     <exepath> <dirs> [<rpaths>])
#
# Get the list of shared library files required by <target>.  The list
# in the variable named <prerequisites_var> should be empty on first
# entry to this function.  On exit, <prerequisites_var> will contain the
# list of required shared library files.
#
# <target> is the full path to an executable file.  <prerequisites_var>
# is the name of a CMake variable to contain the results.
# <exclude_system> must be 0 or 1 indicating whether to include or
# exclude "system" prerequisites.  If <recurse> is set to 1 all
# prerequisites will be found recursively, if set to 0 only direct
# prerequisites are listed.  <exepath> is the path to the top level
# executable used for @executable_path replacment on the Mac.  <dirs> is
# a list of paths where libraries might be found: these paths are
# searched first when a target without any path info is given.  Then
# standard system locations are also searched: PATH, Framework
# locations, /usr/lib...
#
# ::
#
#   LIST_PREREQUISITES(<target> [<recurse> [<exclude_system> [<verbose>]]])
#
# Print a message listing the prerequisites of <target>.
#
# <target> is the name of a shared library or executable target or the
# full path to a shared library or executable file.  If <recurse> is set
# to 1 all prerequisites will be found recursively, if set to 0 only
# direct prerequisites are listed.  <exclude_system> must be 0 or 1
# indicating whether to include or exclude "system" prerequisites.  With
# <verbose> set to 0 only the full path names of the prerequisites are
# printed, set to 1 extra informatin will be displayed.
#
# ::
#
#   LIST_PREREQUISITES_BY_GLOB(<glob_arg> <glob_exp>)
#
# Print the prerequisites of shared library and executable files
# matching a globbing pattern.  <glob_arg> is GLOB or GLOB_RECURSE and
# <glob_exp> is a globbing expression used with "file(GLOB" or
# "file(GLOB_RECURSE" to retrieve a list of matching files.  If a
# matching file is executable, its prerequisites are listed.
#
# Any additional (optional) arguments provided are passed along as the
# optional arguments to the list_prerequisites calls.
#
# ::
#
#   GP_APPEND_UNIQUE(<list_var> <value>)
#
# Append <value> to the list variable <list_var> only if the value is
# not already in the list.
#
# ::
#
#   IS_FILE_EXECUTABLE(<file> <result_var>)
#
# Return 1 in <result_var> if <file> is a binary executable, 0
# otherwise.
#
# ::
#
#   GP_ITEM_DEFAULT_EMBEDDED_PATH(<item> <default_embedded_path_var>)
#
# Return the path that others should refer to the item by when the item
# is embedded inside a bundle.
#
# Override on a per-project basis by providing a project-specific
# gp_item_default_embedded_path_override function.
#
# ::
#
#   GP_RESOLVE_ITEM(<context> <item> <exepath> <dirs> <resolved_item_var>
#                   [<rpaths>])
#
# Resolve an item into an existing full path file.
#
# Override on a per-project basis by providing a project-specific
# gp_resolve_item_override function.
#
# ::
#
#   GP_RESOLVED_FILE_TYPE(<original_file> <file> <exepath> <dirs> <type_var>
#                         [<rpaths>])
#
# Return the type of <file> with respect to <original_file>.  String
# describing type of prerequisite is returned in variable named
# <type_var>.
#
# Use <exepath> and <dirs> if necessary to resolve non-absolute <file>
# values -- but only for non-embedded items.
#
# Possible types are:
#
# ::
#
#    system
#    local
#    embedded
#    other
#
# Override on a per-project basis by providing a project-specific
# gp_resolved_file_type_override function.
#
# ::
#
#   GP_FILE_TYPE(<original_file> <file> <type_var>)
#
# Return the type of <file> with respect to <original_file>.  String
# describing type of prerequisite is returned in variable named
# <type_var>.
#
# Possible types are:
#
# ::
#
#    system
#    local
#    embedded
#    other

#=============================================================================
# Copyright 2008-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
#  License text for the above reference.)

function(gp_append_unique list_var value)
  set(contains 0)

  foreach(item ${${list_var}})
    if(item STREQUAL "${value}")
      set(contains 1)
      break()
    endif()
  endforeach()

  if(NOT contains)
    set(${list_var} ${${list_var}} "${value}" PARENT_SCOPE)
  endif()
endfunction()

function(is_file_executable file result_var)
  #
  # A file is not executable until proven otherwise:
  #
  set(${result_var} 0 PARENT_SCOPE)

  get_filename_component(file_full "${file}" ABSOLUTE)
  string(TOLOWER "${file_full}" file_full_lower)

  # If file name ends in .exe on Windows, *assume* executable:
  #
  if(WIN32 AND NOT UNIX)
    if("${file_full_lower}" MATCHES "\\.exe$")
      set(${result_var} 1 PARENT_SCOPE)
      return()
    endif()

    # A clause could be added here that uses output or return value of dumpbin
    # to determine ${result_var}. In 99%+? practical cases, the exe name
    # match will be sufficient...
    #
  endif()

  # Use the information returned from the Unix shell command "file" to
  # determine if ${file_full} should be considered an executable file...
  #
  # If the file command's output contains "executable" and does *not* contain
  # "text" then it is likely an executable suitable for prerequisite analysis
  # via the get_prerequisites macro.
  #
  if(UNIX)
    if(NOT file_cmd)
      find_program(file_cmd "file")
      mark_as_advanced(file_cmd)
    endif()

    if(file_cmd)
      execute_process(COMMAND "${file_cmd}" "${file_full}"
        RESULT_VARIABLE file_rv
        OUTPUT_VARIABLE file_ov
        ERROR_VARIABLE file_ev
        OUTPUT_STRIP_TRAILING_WHITESPACE
        )
      if(NOT file_rv STREQUAL "0")
        message(FATAL_ERROR "${file_cmd} failed: ${file_rv}\n${file_ev}")
      endif()

      # Replace the name of the file in the output with a placeholder token
      # (the string " _file_full_ ") so that just in case the path name of
      # the file contains the word "text" or "executable" we are not fooled
      # into thinking "the wrong thing" because the file name matches the
      # other 'file' command output we are looking for...
      #
      string(REPLACE "${file_full}" " _file_full_ " file_ov "${file_ov}")
      string(TOLOWER "${file_ov}" file_ov)

      #message(STATUS "file_ov='${file_ov}'")
      if("${file_ov}" MATCHES "executable")
        #message(STATUS "executable!")
        if("${file_ov}" MATCHES "text")
          #message(STATUS "but text, so *not* a binary executable!")
        else()
          set(${result_var} 1 PARENT_SCOPE)
          return()
        endif()
      endif()

      # Also detect position independent executables on Linux,
      # where "file" gives "shared object ... (uses shared libraries)"
      if("${file_ov}" MATCHES "shared object.*\(uses shared libs\)")
        set(${result_var} 1 PARENT_SCOPE)
        return()
      endif()

      # "file" version 5.22 does not print "(used shared libraries)"
      # but uses "interpreter"
      if("${file_ov}" MATCHES "shared object.*interpreter")
        set(${result_var} 1 PARENT_SCOPE)
        return()
      endif()

    else()
      message(STATUS "warning: No 'file' command, skipping execute_process...")
    endif()
  endif()
endfunction()

function(gp_item_default_embedded_path item default_embedded_path_var)

  # On Windows and Linux, "embed" prerequisites in the same directory
  # as the executable by default:
  #
  set(path "@executable_path")
  set(overridden 0)

  # On the Mac, relative to the executable depending on the type
  # of the thing we are embedding:
  #
  if(APPLE)
    #
    # The assumption here is that all executables in the bundle will be
    # in same-level-directories inside the bundle. The parent directory
    # of an executable inside the bundle should be MacOS or a sibling of
    # MacOS and all embedded paths returned from here will begin with
    # "@executable_path/../" and will work from all executables in all
    # such same-level-directories inside the bundle.
    #

    # By default, embed things right next to the main bundle executable:
    #
    set(path "@executable_path/../../Contents/MacOS")

    # Embed .dylibs right next to the main bundle executable:
    #
    if(item MATCHES "\\.dylib$")
      set(path "@executable_path/../MacOS")
      set(overridden 1)
    endif()

    # Embed frameworks in the embedded "Frameworks" directory (sibling of MacOS):
    #
    if(NOT overridden)
      if(item MATCHES "[^/]+\\.framework/")
        set(path "@executable_path/../Frameworks")
        set(overridden 1)
      endif()
    endif()
  endif()

  # Provide a hook so that projects can override the default embedded location
  # of any given library by whatever logic they choose:
  #
  if(COMMAND gp_item_default_embedded_path_override)
    gp_item_default_embedded_path_override("${item}" path)
  endif()

  set(${default_embedded_path_var} "${path}" PARENT_SCOPE)
endfunction()

function(gp_resolve_item context item exepath dirs resolved_item_var)
  set(resolved 0)
  set(resolved_item "${item}")
  if(ARGC GREATER 5)
    set(rpaths "${ARGV5}")
  else()
    set(rpaths "")
  endif()

  # Is it already resolved?
  #
  if(IS_ABSOLUTE "${resolved_item}" AND EXISTS "${resolved_item}")
    set(resolved 1)
  endif()

  if(NOT resolved)
    if(item MATCHES "^@executable_path")
      #
      # @executable_path references are assumed relative to exepath
      #
      string(REPLACE "@executable_path" "${exepath}" ri "${item}")
      get_filename_component(ri "${ri}" ABSOLUTE)

      if(EXISTS "${ri}")
        #message(STATUS "info: embedded item exists (${ri})")
        set(resolved 1)
        set(resolved_item "${ri}")
      else()
        message(STATUS "warning: embedded item does not exist '${ri}'")
      endif()
    endif()
  endif()

  if(NOT resolved)
    if(item MATCHES "^@loader_path")
      #
      # @loader_path references are assumed relative to the
      # PATH of the given "context" (presumably another library)
      #
      get_filename_component(contextpath "${context}" PATH)
      string(REPLACE "@loader_path" "${contextpath}" ri "${item}")
      get_filename_component(ri "${ri}" ABSOLUTE)

      if(EXISTS "${ri}")
        #message(STATUS "info: embedded item exists (${ri})")
        set(resolved 1)
        set(resolved_item "${ri}")
      else()
        message(STATUS "warning: embedded item does not exist '${ri}'")
      endif()
    endif()
  endif()

  if(NOT resolved)
    if(item MATCHES "^@rpath")
      #
      # @rpath references are relative to the paths built into the binaries with -rpath
      # We handle this case like we do for other Unixes
      #
      string(REPLACE "@rpath/" "" norpath_item "${item}")

      set(ri "ri-NOTFOUND")
      find_file(ri "${norpath_item}" ${exepath} ${dirs} ${rpaths} NO_DEFAULT_PATH)
      if(ri)
        #message(STATUS "info: 'find_file' in exepath/dirs/rpaths (${ri})")
        set(resolved 1)
        set(resolved_item "${ri}")
        set(ri "ri-NOTFOUND")
      endif()

    endif()
  endif()

  if(NOT resolved)
    set(ri "ri-NOTFOUND")
    find_file(ri "${item}" ${exepath} ${dirs} NO_DEFAULT_PATH)
    find_file(ri "${item}" ${exepath} ${dirs} /usr/lib)
    if(ri)
      #message(STATUS "info: 'find_file' in exepath/dirs (${ri})")
      set(resolved 1)
      set(resolved_item "${ri}")
      set(ri "ri-NOTFOUND")
    endif()
  endif()

  if(NOT resolved)
    if(item MATCHES "[^/]+\\.framework/")
      set(fw "fw-NOTFOUND")
      find_file(fw "${item}"
        "~/Library/Frameworks"
        "/Library/Frameworks"
        "/System/Library/Frameworks"
      )
      if(fw)
        #message(STATUS "info: 'find_file' found framework (${fw})")
        set(resolved 1)
        set(resolved_item "${fw}")
        set(fw "fw-NOTFOUND")
      endif()
    endif()
  endif()

  # Using find_program on Windows will find dll files that are in the PATH.
  # (Converting simple file names into full path names if found.)
  #
  if(WIN32 AND NOT UNIX)
  if(NOT resolved)
    set(ri "ri-NOTFOUND")
    find_program(ri "${item}" PATHS "${exepath};${dirs}" NO_DEFAULT_PATH)
    find_program(ri "${item}" PATHS "${exepath};${dirs}")
    if(ri)
      #message(STATUS "info: 'find_program' in exepath/dirs (${ri})")
      set(resolved 1)
      set(resolved_item "${ri}")
      set(ri "ri-NOTFOUND")
    endif()
  endif()
  endif()

  # Provide a hook so that projects can override item resolution
  # by whatever logic they choose:
  #
  if(COMMAND gp_resolve_item_override)
    gp_resolve_item_override("${context}" "${item}" "${exepath}" "${dirs}" resolved_item resolved)
  endif()

  if(NOT resolved)
    message(STATUS "
warning: cannot resolve item '${item}'

  possible problems:
    need more directories?
    need to use InstallRequiredSystemLibraries?
    run in install tree instead of build tree?
")
#    message(STATUS "
#******************************************************************************
#warning: cannot resolve item '${item}'
#
#  possible problems:
#    need more directories?
#    need to use InstallRequiredSystemLibraries?
#    run in install tree instead of build tree?
#
#    context='${context}'
#    item='${item}'
#    exepath='${exepath}'
#    dirs='${dirs}'
#    resolved_item_var='${resolved_item_var}'
#******************************************************************************
#")
  endif()

  set(${resolved_item_var} "${resolved_item}" PARENT_SCOPE)
endfunction()

function(gp_resolved_file_type original_file file exepath dirs type_var)
  if(ARGC GREATER 5)
    set(rpaths "${ARGV5}")
  else()
    set(rpaths "")
  endif()
  #message(STATUS "**")

  if(NOT IS_ABSOLUTE "${original_file}")
    message(STATUS "warning: gp_resolved_file_type expects absolute full path for first arg original_file")
  endif()

  set(is_embedded 0)
  set(is_local 0)
  set(is_system 0)

  set(resolved_file "${file}")

  if("${file}" MATCHES "^@(executable|loader)_path")
    set(is_embedded 1)
  endif()

  if(NOT is_embedded)
    if(NOT IS_ABSOLUTE "${file}")
      gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file "${rpaths}")
    endif()

    string(TOLOWER "${original_file}" original_lower)
    string(TOLOWER "${resolved_file}" lower)

    if(UNIX)
      if(resolved_file MATCHES "^(/lib/|/lib32/|/lib64/|/usr/lib/|/usr/lib32/|/usr/lib64/|/usr/X11R6/|/usr/bin/)")
        set(is_system 1)
      endif()
    endif()

    if(APPLE)
      if(resolved_file MATCHES "^(/System/Library/|/usr/lib/)")
        set(is_system 1)
      endif()
    endif()

    if(WIN32)
      string(TOLOWER "$ENV{SystemRoot}" sysroot)
      file(TO_CMAKE_PATH "${sysroot}" sysroot)

      string(TOLOWER "$ENV{windir}" windir)
      file(TO_CMAKE_PATH "${windir}" windir)

      if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)")
        set(is_system 1)
      endif()

      if(UNIX)
        # if cygwin, we can get the properly formed windows paths from cygpath
        find_program(CYGPATH_EXECUTABLE cygpath)

        if(CYGPATH_EXECUTABLE)
          execute_process(COMMAND ${CYGPATH_EXECUTABLE} -W
                          RESULT_VARIABLE env_rv
                          OUTPUT_VARIABLE env_windir
                          ERROR_VARIABLE env_ev
                          OUTPUT_STRIP_TRAILING_WHITESPACE)
          if(NOT env_rv STREQUAL "0")
            message(FATAL_ERROR "${CYGPATH_EXECUTABLE} -W failed: ${env_rv}\n${env_ev}")
          endif()
          execute_process(COMMAND ${CYGPATH_EXECUTABLE} -S
                          RESULT_VARIABLE env_rv
                          OUTPUT_VARIABLE env_sysdir
                          ERROR_VARIABLE env_ev
                          OUTPUT_STRIP_TRAILING_WHITESPACE)
          if(NOT env_rv STREQUAL "0")
            message(FATAL_ERROR "${CYGPATH_EXECUTABLE} -S failed: ${env_rv}\n${env_ev}")
          endif()
          string(TOLOWER "${env_windir}" windir)
          string(TOLOWER "${env_sysdir}" sysroot)

          if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)")
            set(is_system 1)
          endif()
        endif()
      endif()
    endif()

    if(NOT is_system)
      get_filename_component(original_path "${original_lower}" PATH)
      get_filename_component(path "${lower}" PATH)
      if(original_path STREQUAL path)
        set(is_local 1)
      else()
        string(LENGTH "${original_path}/" original_length)
        string(LENGTH "${lower}" path_length)
        if(${path_length} GREATER ${original_length})
          string(SUBSTRING "${lower}" 0 ${original_length} path)
          if("${original_path}/" STREQUAL path)
            set(is_embedded 1)
          endif()
        endif()
      endif()
    endif()
  endif()

  # Return type string based on computed booleans:
  #
  set(type "other")

  if(is_system)
    set(type "system")
  elseif(is_embedded)
    set(type "embedded")
  elseif(is_local)
    set(type "local")
  endif()

  #message(STATUS "gp_resolved_file_type: '${file}' '${resolved_file}'")
  #message(STATUS "                type: '${type}'")

  if(NOT is_embedded)
    if(NOT IS_ABSOLUTE "${resolved_file}")
      if(lower MATCHES "^msvc[^/]+dll" AND is_system)
        message(STATUS "info: non-absolute msvc file '${file}' returning type '${type}'")
      else()
        message(STATUS "warning: gp_resolved_file_type non-absolute file '${file}' returning type '${type}' -- possibly incorrect")
      endif()
    endif()
  endif()

  # Provide a hook so that projects can override the decision on whether a
  # library belongs to the system or not by whatever logic they choose:
  #
  if(COMMAND gp_resolved_file_type_override)
    gp_resolved_file_type_override("${resolved_file}" type)
  endif()

  set(${type_var} "${type}" PARENT_SCOPE)

  #message(STATUS "**")
endfunction()

function(gp_file_type original_file file type_var)
  if(NOT IS_ABSOLUTE "${original_file}")
    message(STATUS "warning: gp_file_type expects absolute full path for first arg original_file")
  endif()

  get_filename_component(exepath "${original_file}" PATH)

  set(type "")
  gp_resolved_file_type("${original_file}" "${file}" "${exepath}" "" type)

  set(${type_var} "${type}" PARENT_SCOPE)
endfunction()

function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs)
  set(verbose 0)
  set(eol_char "E")
  if(ARGC GREATER 6)
    set(rpaths "${ARGV6}")
  else()
    set(rpaths "")
  endif()

  if(NOT IS_ABSOLUTE "${target}")
    message("warning: target '${target}' is not absolute...")
  endif()

  if(NOT EXISTS "${target}")
    message("warning: target '${target}' does not exist...")
  endif()

  set(gp_cmd_paths ${gp_cmd_paths}
    "C:/Program Files/Microsoft Visual Studio 9.0/VC/bin"
    "C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin"
    "C:/Program Files/Microsoft Visual Studio 8/VC/BIN"
    "C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN"
    "C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN"
    "C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN"
    "/usr/local/bin"
    "/usr/bin"
    )

  # <setup-gp_tool-vars>
  #
  # Try to choose the right tool by default. Caller can set gp_tool prior to
  # calling this function to force using a different tool.
  #
  if(NOT gp_tool)
    set(gp_tool "ldd")

    if(APPLE)
      set(gp_tool "otool")
    endif()

    if(WIN32 AND NOT UNIX) # This is how to check for cygwin, har!
      find_program(gp_dumpbin "dumpbin" PATHS ${gp_cmd_paths})
      if(gp_dumpbin)
        set(gp_tool "dumpbin")
      else() # Try harder. Maybe we're on MinGW
        set(gp_tool "objdump")
      endif()
    endif()
  endif()

  find_program(gp_cmd ${gp_tool} PATHS ${gp_cmd_paths})

  if(NOT gp_cmd)
    message(STATUS "warning: could not find '${gp_tool}' - cannot analyze prerequisites...")
    return()
  endif()

  set(gp_cmd_maybe_filter)      # optional command to pre-filter gp_tool results

  if(gp_tool STREQUAL "ldd")
    set(gp_cmd_args "")
    set(gp_regex "^[\t ]*[^\t ]+ => ([^\t\(]+) .*${eol_char}$")
    set(gp_regex_error "not found${eol_char}$")
    set(gp_regex_fallback "^[\t ]*([^\t ]+) => ([^\t ]+).*${eol_char}$")
    set(gp_regex_cmp_count 1)
  elseif(gp_tool STREQUAL "otool")
    set(gp_cmd_args "-L")
    set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$")
    set(gp_regex_error "")
    set(gp_regex_fallback "")
    set(gp_regex_cmp_count 3)
  elseif(gp_tool STREQUAL "dumpbin")
    set(gp_cmd_args "/dependents")
    set(gp_regex "^    ([^ ].*[Dd][Ll][Ll])${eol_char}$")
    set(gp_regex_error "")
    set(gp_regex_fallback "")
    set(gp_regex_cmp_count 1)
  elseif(gp_tool STREQUAL "objdump")
    set(gp_cmd_args "-p")
    set(gp_regex "^\t*DLL Name: (.*\\.[Dd][Ll][Ll])${eol_char}$")
    set(gp_regex_error "")
    set(gp_regex_fallback "")
    set(gp_regex_cmp_count 1)
    # objdump generaates copious output so we create a grep filter to pre-filter results
    find_program(gp_grep_cmd grep)
    if(gp_grep_cmd)
      set(gp_cmd_maybe_filter COMMAND ${gp_grep_cmd} "^[[:blank:]]*DLL Name: ")
    endif()
  else()
    message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...")
    message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'")
    message(STATUS "Valid gp_tool values are dumpbin, ldd, objdump and otool.")
    return()
  endif()

  if(gp_tool STREQUAL "dumpbin")
    # When running dumpbin, it also needs the "Common7/IDE" directory in the
    # PATH. It will already be in the PATH if being run from a Visual Studio
    # command prompt. Add it to the PATH here in case we are running from a
    # different command prompt.
    #
    get_filename_component(gp_cmd_dir "${gp_cmd}" PATH)
    get_filename_component(gp_cmd_dlls_dir "${gp_cmd_dir}/../../Common7/IDE" ABSOLUTE)
    # Use cmake paths as a user may have a PATH element ending with a backslash.
    # This will escape the list delimiter and create havoc!
    if(EXISTS "${gp_cmd_dlls_dir}")
      # only add to the path if it is not already in the path
      set(gp_found_cmd_dlls_dir 0)
      file(TO_CMAKE_PATH "$ENV{PATH}" env_path)
      foreach(gp_env_path_element ${env_path})
        if(gp_env_path_element STREQUAL gp_cmd_dlls_dir)
          set(gp_found_cmd_dlls_dir 1)
        endif()
      endforeach()

      if(NOT gp_found_cmd_dlls_dir)
        file(TO_NATIVE_PATH "${gp_cmd_dlls_dir}" gp_cmd_dlls_dir)
        set(ENV{PATH} "$ENV{PATH};${gp_cmd_dlls_dir}")
      endif()
    endif()
  endif()
  #
  # </setup-gp_tool-vars>

  if(gp_tool STREQUAL "ldd")
    set(old_ld_env "$ENV{LD_LIBRARY_PATH}")
    set(new_ld_env "${exepath}")
    foreach(dir ${dirs})
      set(new_ld_env "${new_ld_env}:${dir}")
    endforeach()
    set(ENV{LD_LIBRARY_PATH} "${new_ld_env}:$ENV{LD_LIBRARY_PATH}")
  endif()

  # Track new prerequisites at each new level of recursion. Start with an
  # empty list at each level:
  #
  set(unseen_prereqs)

  # Run gp_cmd on the target:
  #
  execute_process(
    COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
    ${gp_cmd_maybe_filter}
    RESULT_VARIABLE gp_rv
    OUTPUT_VARIABLE gp_cmd_ov
    ERROR_VARIABLE gp_ev
    )
  if(NOT gp_rv STREQUAL "0")
    if(gp_tool STREQUAL "dumpbin")
      # dumpbin error messages seem to go to stdout
      message(FATAL_ERROR "${gp_cmd} failed: ${gp_rv}\n${gp_ev}\n${gp_cmd_ov}")
    else()
      message(FATAL_ERROR "${gp_cmd} failed: ${gp_rv}\n${gp_ev}")
    endif()
  endif()

  if(gp_tool STREQUAL "ldd")
    set(ENV{LD_LIBRARY_PATH} "${old_ld_env}")
  endif()

  if(verbose)
    message(STATUS "<RawOutput cmd='${gp_cmd} ${gp_cmd_args} ${target}'>")
    message(STATUS "gp_cmd_ov='${gp_cmd_ov}'")
    message(STATUS "</RawOutput>")
  endif()

  get_filename_component(target_dir "${target}" PATH)

  # Convert to a list of lines:
  #
  string(REPLACE ";" "\\;" candidates "${gp_cmd_ov}")
  string(REPLACE "\n" "${eol_char};" candidates "${candidates}")

  # check for install id and remove it from list, since otool -L can include a
  # reference to itself
  set(gp_install_id)
  if(gp_tool STREQUAL "otool")
    execute_process(
      COMMAND otool -D ${target}
      RESULT_VARIABLE otool_rv
      OUTPUT_VARIABLE gp_install_id_ov
      ERROR_VARIABLE otool_ev
      )
    if(NOT otool_rv STREQUAL "0")
      message(FATAL_ERROR "otool -D failed: ${otool_rv}\n${otool_ev}")
    endif()
    # second line is install name
    string(REGEX REPLACE ".*:\n" "" gp_install_id "${gp_install_id_ov}")
    if(gp_install_id)
      # trim
      string(REGEX MATCH "[^\n ].*[^\n ]" gp_install_id "${gp_install_id}")
      #message("INSTALL ID is \"${gp_install_id}\"")
    endif()
  endif()

  # Analyze each line for file names that match the regular expression:
  #
  foreach(candidate ${candidates})
  if("${candidate}" MATCHES "${gp_regex}")

    # Extract information from each candidate:
    if(gp_regex_error AND "${candidate}" MATCHES "${gp_regex_error}")
      string(REGEX REPLACE "${gp_regex_fallback}" "\\1" raw_item "${candidate}")
    else()
      string(REGEX REPLACE "${gp_regex}" "\\1" raw_item "${candidate}")
    endif()

    if(gp_regex_cmp_count GREATER 1)
      string(REGEX REPLACE "${gp_regex}" "\\2" raw_compat_version "${candidate}")
      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" compat_major_version "${raw_compat_version}")
      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" compat_minor_version "${raw_compat_version}")
      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" compat_patch_version "${raw_compat_version}")
    endif()

    if(gp_regex_cmp_count GREATER 2)
      string(REGEX REPLACE "${gp_regex}" "\\3" raw_current_version "${candidate}")
      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" current_major_version "${raw_current_version}")
      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" current_minor_version "${raw_current_version}")
      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" current_patch_version "${raw_current_version}")
    endif()

    # Use the raw_item as the list entries returned by this function. Use the
    # gp_resolve_item function to resolve it to an actual full path file if
    # necessary.
    #
    set(item "${raw_item}")

    # Add each item unless it is excluded:
    #
    set(add_item 1)

    if(item STREQUAL gp_install_id)
      set(add_item 0)
    endif()

    if(add_item AND ${exclude_system})
      set(type "")
      gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type "${rpaths}")

      if(type STREQUAL "system")
        set(add_item 0)
      endif()
    endif()

    if(add_item)
      list(LENGTH ${prerequisites_var} list_length_before_append)
      gp_append_unique(${prerequisites_var} "${item}")
      list(LENGTH ${prerequisites_var} list_length_after_append)

      if(${recurse})
        # If item was really added, this is the first time we have seen it.
        # Add it to unseen_prereqs so that we can recursively add *its*
        # prerequisites...
        #
        # But first: resolve its name to an absolute full path name such
        # that the analysis tools can simply accept it as input.
        #
        if(NOT list_length_before_append EQUAL list_length_after_append)
          gp_resolve_item("${target}" "${item}" "${exepath}" "${dirs}" resolved_item "${rpaths}")
          set(unseen_prereqs ${unseen_prereqs} "${resolved_item}")
        endif()
      endif()
    endif()
  else()
    if(verbose)
      message(STATUS "ignoring non-matching line: '${candidate}'")
    endif()
  endif()
  endforeach()

  list(LENGTH ${prerequisites_var} prerequisites_var_length)
  if(prerequisites_var_length GREATER 0)
    list(SORT ${prerequisites_var})
  endif()
  if(${recurse})
    set(more_inputs ${unseen_prereqs})
    foreach(input ${more_inputs})
      get_prerequisites("${input}" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}" "${dirs}" "${rpaths}")
    endforeach()
  endif()

  set(${prerequisites_var} ${${prerequisites_var}} PARENT_SCOPE)
endfunction()

function(list_prerequisites target)
  if(ARGC GREATER 1 AND NOT "${ARGV1}" STREQUAL "")
    set(all "${ARGV1}")
  else()
    set(all 1)
  endif()

  if(ARGC GREATER 2 AND NOT "${ARGV2}" STREQUAL "")
    set(exclude_system "${ARGV2}")
  else()
    set(exclude_system 0)
  endif()

  if(ARGC GREATER 3 AND NOT "${ARGV3}" STREQUAL "")
    set(verbose "${ARGV3}")
  else()
    set(verbose 0)
  endif()

  set(count 0)
  set(count_str "")
  set(print_count "${verbose}")
  set(print_prerequisite_type "${verbose}")
  set(print_target "${verbose}")
  set(type_str "")

  get_filename_component(exepath "${target}" PATH)

  set(prereqs "")
  get_prerequisites("${target}" prereqs ${exclude_system} ${all} "${exepath}" "")

  if(print_target)
    message(STATUS "File '${target}' depends on:")
  endif()

  foreach(d ${prereqs})
    math(EXPR count "${count} + 1")

    if(print_count)
      set(count_str "${count}. ")
    endif()

    if(print_prerequisite_type)
      gp_file_type("${target}" "${d}" type)
      set(type_str " (${type})")
    endif()

    message(STATUS "${count_str}${d}${type_str}")
  endforeach()
endfunction()

function(list_prerequisites_by_glob glob_arg glob_exp)
  message(STATUS "=============================================================================")
  message(STATUS "List prerequisites of executables matching ${glob_arg} '${glob_exp}'")
  message(STATUS "")
  file(${glob_arg} file_list ${glob_exp})
  foreach(f ${file_list})
    is_file_executable("${f}" is_f_executable)
    if(is_f_executable)
      message(STATUS "=============================================================================")
      list_prerequisites("${f}" ${ARGN})
      message(STATUS "")
    endif()
  endforeach()
endfunction()


code:
# Version 1.0 (2013-04-12)
# Public Domain, originally written by Lasse Kärkkäinen <tronic@zi.fi>
# Published at http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries

# If you improve the script, please modify the forementioned wiki page because
# I no longer maintain my scripts (hosted as static files at zi.fi). Feel free
# to remove this entire header if you use real version control instead.

# Changelog:
# 2013-04-12  Added version number (1.0) and this header, no other changes
# 2009-10-08  Originally published

# Works the same as find_package, but forwards the "REQUIRED" and "QUIET" arguments
# used for the current package. For this to work, the first parameter must be the
# prefix of the current package, then the prefix of the new package etc, which are
# passed to find_package.
macro (libfind_package PREFIX)
  set (LIBFIND_PACKAGE_ARGS ${ARGN})
  if (${PREFIX}_FIND_QUIETLY)
    set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} QUIET)
  endif (${PREFIX}_FIND_QUIETLY)
  if (${PREFIX}_FIND_REQUIRED)
    set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} REQUIRED)
  endif (${PREFIX}_FIND_REQUIRED)
  find_package(${LIBFIND_PACKAGE_ARGS})
endmacro (libfind_package)

# CMake developers made the UsePkgConfig system deprecated in the same release (2.6)
# where they added pkg_check_modules. Consequently I need to support both in my scripts
# to avoid those deprecated warnings. Here's a helper that does just that.
# Works identically to pkg_check_modules, except that no checks are needed prior to use.
macro (libfind_pkg_check_modules PREFIX PKGNAME)
  if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
    include(UsePkgConfig)
    pkgconfig(${PKGNAME} ${PREFIX}_INCLUDE_DIRS ${PREFIX}_LIBRARY_DIRS ${PREFIX}_LDFLAGS ${PREFIX}_CFLAGS)
  else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
    find_package(PkgConfig)
    if (PKG_CONFIG_FOUND)
      pkg_check_modules(${PREFIX} ${PKGNAME})
    endif (PKG_CONFIG_FOUND)
  endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
endmacro (libfind_pkg_check_modules)

# Do the final processing once the paths have been detected.
# If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain
# all the variables, each of which contain one include directory.
# Ditto for ${PREFIX}_PROCESS_LIBS and library files.
# Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES.
# Also handles errors in case library detection was required, etc.
macro (libfind_process PREFIX)
  # Skip processing if already processed during this run
  if (NOT ${PREFIX}_FOUND)
    # Start with the assumption that the library was found
    set (${PREFIX}_FOUND TRUE)

    # Process all includes and set _FOUND to false if any are missing
    foreach (i ${${PREFIX}_PROCESS_INCLUDES})
      if (${i})
        set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIRS} ${${i}})
        mark_as_advanced(${i})
      else (${i})
        set (${PREFIX}_FOUND FALSE)
      endif (${i})
    endforeach (i)

    # Process all libraries and set _FOUND to false if any are missing
    foreach (i ${${PREFIX}_PROCESS_LIBS})
      if (${i})
        set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARIES} ${${i}})
        mark_as_advanced(${i})
      else (${i})
        set (${PREFIX}_FOUND FALSE)
      endif (${i})
    endforeach (i)

    # Print message and/or exit on fatal error
    if (${PREFIX}_FOUND)
      if (NOT ${PREFIX}_FIND_QUIETLY)
        message (STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}")
      endif (NOT ${PREFIX}_FIND_QUIETLY)
    else (${PREFIX}_FOUND)
      if (${PREFIX}_FIND_REQUIRED)
        foreach (i ${${PREFIX}_PROCESS_INCLUDES} ${${PREFIX}_PROCESS_LIBS})
          message("${i}=${${i}}")
        endforeach (i)
        message (FATAL_ERROR "Required library ${PREFIX} NOT FOUND.\nInstall the library (dev version) and try again. If the library is already installed, use ccmake to set the missing variables manually.")
      endif (${PREFIX}_FIND_REQUIRED)
    endif (${PREFIX}_FOUND)
  endif (NOT ${PREFIX}_FOUND)
endmacro (libfind_process)

macro(libfind_library PREFIX basename)
  set(TMP "")
  if(MSVC80)
    set(TMP -vc80)
  endif(MSVC80)
  if(MSVC90)
    set(TMP -vc90)
  endif(MSVC90)
  set(${PREFIX}_LIBNAMES ${basename}${TMP})
  if(${ARGC} GREATER 2)
    set(${PREFIX}_LIBNAMES ${basename}${TMP}-${ARGV2})
    string(REGEX REPLACE "\\." "_" TMP ${${PREFIX}_LIBNAMES})
    set(${PREFIX}_LIBNAMES ${${PREFIX}_LIBNAMES} ${TMP})
  endif(${ARGC} GREATER 2)
  find_library(${PREFIX}_LIBRARY
    NAMES ${${PREFIX}_LIBNAMES}
    PATHS ${${PREFIX}_PKGCONF_LIBRARY_DIRS}
  )
endmacro(libfind_library)


code:
; CPack install script designed for a nmake build

;--------------------------------
; You must define these values

  !define VERSION "@CPACK_PACKAGE_VERSION@"
  !define PATCH  "@CPACK_PACKAGE_VERSION_PATCH@"
  !define INST_DIR "@CPACK_TEMPORARY_DIRECTORY@"

;--------------------------------
;Variables

  Var MUI_TEMP
  Var STARTMENU_FOLDER
  Var SV_ALLUSERS
  Var START_MENU
  Var RB_DO_NOT_ADD_TO_PATH
  Var DO_NOT_ADD_TO_PATH
  Var RB_ADD_TO_PATH_ALL_USERS
  Var ADD_TO_PATH_ALL_USERS
  Var RB_ADD_TO_PATH_CURRENT_USER
  Var ADD_TO_PATH_CURRENT_USER
  Var CB_INSTALL_DESKTOP
  Var INSTALL_DESKTOP
  Var IS_DEFAULT_INSTALLDIR

;--------------------------------
;Include Modern UI

  !include "MUI2.nsh"
  !include "nsDialogs.nsh"

;--------------------------------
;Include Logic Lib and add a DirExists command

  !include "LogicLib.nsh"
;FileExists is already part of LogicLib, but returns true for directories as well as files
  !macro _FileExists2 _a _b _t _f
	!insertmacro _LOGICLIB_TEMP
	StrCpy $_LOGICLIB_TEMP '0'
	StrCmp `${_b}` `` +4 0 ;if path is not blank, continue to next check
	IfFileExists `${_b}` `0` +3 ;if path exists, continue to next check (IfFileExists returns true if this is a directory)
	IfFileExists `${_b}\*.*` +2 0 ;if path is not a directory, continue to confirm exists
	StrCpy $_LOGICLIB_TEMP '1' ;file exists
	;now we have a definitive value - the file exists or it does not
	StrCmp $_LOGICLIB_TEMP '1' `${_t}` `${_f}`
  !macroend
  !undef FileExists
  !define FileExists `'' FileExists2`
  !macro _DirExists _a _b _t _f
	!insertmacro _LOGICLIB_TEMP
	StrCpy $_LOGICLIB_TEMP '0'
	StrCmp `${_b}` `` +3 0 ;if path is not blank, continue to next check
	IfFileExists `${_b}\*.*` 0 +2 ;if directory exists, continue to confirm exists
	StrCpy $_LOGICLIB_TEMP '1'
	StrCmp $_LOGICLIB_TEMP '1' `${_t}` `${_f}`
  !macroend
  !define DirExists `'' DirExists`

  ;Default installation folder
  InstallDir "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@"

;--------------------------------
;General

  ;Name and file
  Name "@CPACK_NSIS_PACKAGE_NAME@"
  OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@"

  ;Set compression
  SetCompressor @CPACK_NSIS_COMPRESSOR@

  ;Require administrator access
  RequestExecutionLevel admin

@CPACK_NSIS_DEFINES@
@CPACK_NSIS_EXTRA_DEFINES@

  !include Sections.nsh

;--- Component support macros: ---
; The code for the add/remove functionality is from:
;   http://nsis.sourceforge.net/Add/Remove_Functionality
; It has been modified slightly and extended to provide
; inter-component dependencies.
Var AR_SecFlags
Var AR_RegFlags
@CPACK_NSIS_SECTION_SELECTED_VARS@

; Loads the "selected" flag for the section named SecName into the
; variable VarName.
!macro LoadSectionSelectedIntoVar SecName VarName
 SectionGetFlags ${${SecName}} $${VarName}
 IntOp $${VarName} $${VarName} & ${SF_SELECTED}  ;Turn off all other bits
!macroend

; Loads the value of a variable... can we get around this?
!macro LoadVar VarName
  IntOp $R0 0 + $${VarName}
!macroend

; Sets the value of a variable
!macro StoreVar VarName IntValue
  IntOp $${VarName} 0 + ${IntValue}
!macroend

!macro InitSection SecName
  ;  This macro reads component installed flag from the registry and
  ;changes checked state of the section on the components page.
  ;Input: section index constant name specified in Section command.

  ClearErrors
  ;Reading component status from registry
  ReadRegDWORD $AR_RegFlags HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" "Installed"
  IfErrors "default_${SecName}"
    ;Status will stay default if registry value not found
    ;(component was never installed)
  IntOp $AR_RegFlags $AR_RegFlags & ${SF_SELECTED} ;Turn off all other bits
  SectionGetFlags ${${SecName}} $AR_SecFlags  ;Reading default section flags
  IntOp $AR_SecFlags $AR_SecFlags & 0xFFFE  ;Turn lowest (enabled) bit off
  IntOp $AR_SecFlags $AR_RegFlags | $AR_SecFlags      ;Change lowest bit

  ; Note whether this component was installed before
  !insertmacro StoreVar ${SecName}_was_installed $AR_RegFlags
  IntOp $R0 $AR_RegFlags & $AR_RegFlags

  ;Writing modified flags
  SectionSetFlags ${${SecName}} $AR_SecFlags

 "default_${SecName}:"
 !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected
!macroend

!macro FinishSection SecName
  ;  This macro reads section flag set by user and removes the section
  ;if it is not selected.
  ;Then it writes component installed flag to registry
  ;Input: section index constant name specified in Section command.

  SectionGetFlags ${${SecName}} $AR_SecFlags  ;Reading section flags
  ;Checking lowest bit:
  IntOp $AR_SecFlags $AR_SecFlags & ${SF_SELECTED}
  IntCmp $AR_SecFlags 1 "leave_${SecName}"
    ;Section is not selected:
    ;Calling Section uninstall macro and writing zero installed flag
    !insertmacro "Remove_${${SecName}}"
    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \
  "Installed" 0
    Goto "exit_${SecName}"

 "leave_${SecName}:"
    ;Section is selected:
    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \
  "Installed" 1

 "exit_${SecName}:"
!macroend

!macro RemoveSection_CPack SecName
  ;  This macro is used to call section's Remove_... macro
  ;from the uninstaller.
  ;Input: section index constant name specified in Section command.

  !insertmacro "Remove_${${SecName}}"
!macroend

; Determine whether the selection of SecName changed
!macro MaybeSelectionChanged SecName
  !insertmacro LoadVar ${SecName}_selected
  SectionGetFlags ${${SecName}} $R1
  IntOp $R1 $R1 & ${SF_SELECTED} ;Turn off all other bits

  ; See if the status has changed:
  IntCmp $R0 $R1 "${SecName}_unchanged"
  !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected

  IntCmp $R1 ${SF_SELECTED} "${SecName}_was_selected"
  !insertmacro "Deselect_required_by_${SecName}"
  goto "${SecName}_unchanged"

  "${SecName}_was_selected:"
  !insertmacro "Select_${SecName}_depends"

  "${SecName}_unchanged:"
!macroend
;--- End of Add/Remove macros ---

;--------------------------------
;Interface Settings

  !define MUI_HEADERIMAGE
  !define MUI_ABORTWARNING
  !define MUI_FINISHPAGE_NOAUTOCLOSE

;--------------------------------
; path functions

!verbose 3
!include "WinMessages.NSH"
!verbose 4

;----------------------------------------
; based upon a script of "Written by KiCHiK 2003-01-18 05:57:02"
;----------------------------------------
!verbose 3
!include "WinMessages.NSH"
!verbose 4
;====================================================
; get_NT_environment
;     Returns: the selected environment
;     Output : head of the stack
;====================================================
!macro select_NT_profile UN
Function ${UN}select_NT_profile
   ${If} $ADD_TO_PATH_ALL_USERS = ${BST_CHECKED}
      DetailPrint "Selected environment for all users"
      Push "all"
   ${Else}
      DetailPrint "Selected environment for current user only."
      Push "current"
   ${EndIf}
FunctionEnd
!macroend
!insertmacro select_NT_profile ""
!insertmacro select_NT_profile "un."
;----------------------------------------------------
!define NT_current_env 'HKCU "Environment"'
!define NT_all_env     'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'

!ifndef WriteEnvStr_RegKey
  !ifdef ALL_USERS
    !define WriteEnvStr_RegKey \
       'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
  !else
    !define WriteEnvStr_RegKey 'HKCU "Environment"'
  !endif
!endif

; AddToPath - Adds the given dir to the search path.
;        Input - head of the stack
;        Note - Win9x systems requires reboot

Function AddToPath
  Exch $0
  Push $1
  Push $2
  Push $3

  # don't add if the path doesn't exist
  IfFileExists "$0\*.*" "" AddToPath_done

  ReadEnvStr $1 PATH
  ; if the path is too long for a NSIS variable NSIS will return a 0
  ; length string.  If we find that, then warn and skip any path
  ; modification as it will trash the existing path.
  StrLen $2 $1
  IntCmp $2 0 CheckPathLength_ShowPathWarning CheckPathLength_Done CheckPathLength_Done
    CheckPathLength_ShowPathWarning:
    Messagebox MB_OK|MB_ICONEXCLAMATION "Warning! PATH too long installer unable to modify PATH!"
    Goto AddToPath_done
  CheckPathLength_Done:
  Push "$1;"
  Push "$0;"
  Call StrStr
  Pop $2
  StrCmp $2 "" "" AddToPath_done
  Push "$1;"
  Push "$0\;"
  Call StrStr
  Pop $2
  StrCmp $2 "" "" AddToPath_done
  GetFullPathName /SHORT $3 $0
  Push "$1;"
  Push "$3;"
  Call StrStr
  Pop $2
  StrCmp $2 "" "" AddToPath_done
  Push "$1;"
  Push "$3\;"
  Call StrStr
  Pop $2
  StrCmp $2 "" "" AddToPath_done

  Call IsNT
  Pop $1
  StrCmp $1 1 AddToPath_NT
    ; Not on NT
    StrCpy $1 $WINDIR 2
    FileOpen $1 "$1\autoexec.bat" a
    FileSeek $1 -1 END
    FileReadByte $1 $2
    IntCmp $2 26 0 +2 +2 # DOS EOF
      FileSeek $1 -1 END # write over EOF
    FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n"
    FileClose $1
    SetRebootFlag true
    Goto AddToPath_done

  AddToPath_NT:
    ${If} $ADD_TO_PATH_ALL_USERS = ${BST_CHECKED}
      ReadRegStr $1 ${NT_all_env} "PATH"
    ${Else}
      ReadRegStr $1 ${NT_current_env} "PATH"
    ${EndIf}
    StrCmp $1 "" AddToPath_NTdoIt
      Push $1
      Call Trim
      Pop $1
      StrCpy $0 "$1;$0"
    AddToPath_NTdoIt:
      ${If} $ADD_TO_PATH_ALL_USERS = ${BST_CHECKED}
        WriteRegExpandStr ${NT_all_env} "PATH" $0
      ${Else}
        WriteRegExpandStr ${NT_current_env} "PATH" $0
      ${EndIf}
      SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000

  AddToPath_done:
    Pop $3
    Pop $2
    Pop $1
    Pop $0
FunctionEnd

; RemoveFromPath - Remove a given dir from the path
;     Input: head of the stack

Function un.RemoveFromPath
  Exch $0
  Push $1
  Push $2
  Push $3
  Push $4
  Push $5
  Push $6

  IntFmt $6 "%c" 26 # DOS EOF

  Call un.IsNT
  Pop $1
  StrCmp $1 1 unRemoveFromPath_NT
    ; Not on NT
    StrCpy $1 $WINDIR 2
    FileOpen $1 "$1\autoexec.bat" r
    GetTempFileName $4
    FileOpen $2 $4 w
    GetFullPathName /SHORT $0 $0
    StrCpy $0 "SET PATH=%PATH%;$0"
    Goto unRemoveFromPath_dosLoop

    unRemoveFromPath_dosLoop:
      FileRead $1 $3
      StrCpy $5 $3 1 -1 # read last char
      StrCmp $5 $6 0 +2 # if DOS EOF
        StrCpy $3 $3 -1 # remove DOS EOF so we can compare
      StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoopRemoveLine
      StrCmp $3 "$0$\n" unRemoveFromPath_dosLoopRemoveLine
      StrCmp $3 "$0" unRemoveFromPath_dosLoopRemoveLine
      StrCmp $3 "" unRemoveFromPath_dosLoopEnd
      FileWrite $2 $3
      Goto unRemoveFromPath_dosLoop
      unRemoveFromPath_dosLoopRemoveLine:
        SetRebootFlag true
        Goto unRemoveFromPath_dosLoop

    unRemoveFromPath_dosLoopEnd:
      FileClose $2
      FileClose $1
      StrCpy $1 $WINDIR 2
      Delete "$1\autoexec.bat"
      CopyFiles /SILENT $4 "$1\autoexec.bat"
      Delete $4
      Goto unRemoveFromPath_done

  unRemoveFromPath_NT:
    ${If} $ADD_TO_PATH_ALL_USERS = ${BST_CHECKED}
      ReadRegStr $1 ${NT_all_env} "PATH"
    ${Else}
      ReadRegStr $1 ${NT_current_env} "PATH"
    ${EndIf}
    StrCpy $5 $1 1 -1 # copy last char
    StrCmp $5 ";" +2 # if last char != ;
      StrCpy $1 "$1;" # append ;
    Push $1
    Push "$0;"
    Call un.StrStr ; Find `$0;` in $1
    Pop $2 ; pos of our dir
    StrCmp $2 "" unRemoveFromPath_done
      ; else, it is in path
      # $0 - path to add
      # $1 - path var
      StrLen $3 "$0;"
      StrLen $4 $2
      StrCpy $5 $1 -$4 # $5 is now the part before the path to remove
      StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove
      StrCpy $3 $5$6

      StrCpy $5 $3 1 -1 # copy last char
      StrCmp $5 ";" 0 +2 # if last char == ;
        StrCpy $3 $3 -1 # remove last char

      ${If} $ADD_TO_PATH_ALL_USERS = ${BST_CHECKED}
        WriteRegExpandStr ${NT_all_env} "PATH" $3
      ${Else}
        WriteRegExpandStr ${NT_current_env} "PATH" $3
      ${EndIf}
      SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000

  unRemoveFromPath_done:
    Pop $6
    Pop $5
    Pop $4
    Pop $3
    Pop $2
    Pop $1
    Pop $0
FunctionEnd

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Uninstall sutff
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

###########################################
#            Utility Functions            #
###########################################

;====================================================
; IsNT - Returns 1 if the current system is NT, 0
;        otherwise.
;     Output: head of the stack
;====================================================
; IsNT
; no input
; output, top of the stack = 1 if NT or 0 if not
;
; Usage:
;   Call IsNT
;   Pop $R0
;  ($R0 at this point is 1 or 0)

!macro IsNT un
Function ${un}IsNT
  Push $0
  ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
  StrCmp $0 "" 0 IsNT_yes
  ; we are not NT.
  Pop $0
  Push 0
  Return

  IsNT_yes:
    ; NT!!!
    Pop $0
    Push 1
FunctionEnd
!macroend
!insertmacro IsNT ""
!insertmacro IsNT "un."

; StrStr
; input, top of stack = string to search for
;        top of stack-1 = string to search in
; output, top of stack (replaces with the portion of the string remaining)
; modifies no other variables.
;
; Usage:
;   Push "this is a long ass string"
;   Push "ass"
;   Call StrStr
;   Pop $R0
;  ($R0 at this point is "ass string")

!macro StrStr un
Function ${un}StrStr
Exch $R1 ; st=haystack,old$R1, $R1=needle
  Exch    ; st=old$R1,haystack
  Exch $R2 ; st=old$R1,old$R2, $R2=haystack
  Push $R3
  Push $R4
  Push $R5
  StrLen $R3 $R1
  StrCpy $R4 0
  ; $R1=needle
  ; $R2=haystack
  ; $R3=len(needle)
  ; $R4=cnt
  ; $R5=tmp
  loop:
    StrCpy $R5 $R2 $R3 $R4
    StrCmp $R5 $R1 done
    StrCmp $R5 "" done
    IntOp $R4 $R4 + 1
    Goto loop
done:
  StrCpy $R1 $R2 "" $R4
  Pop $R5
  Pop $R4
  Pop $R3
  Pop $R2
  Exch $R1
FunctionEnd
!macroend
!insertmacro StrStr ""
!insertmacro StrStr "un."

Function Trim ; Added by Pelaca
	Exch $R1
	Push $R2
Loop:
	StrCpy $R2 "$R1" 1 -1
	StrCmp "$R2" " " RTrim
	StrCmp "$R2" "$\n" RTrim
	StrCmp "$R2" "$\r" RTrim
	StrCmp "$R2" ";" RTrim
	GoTo Done
RTrim:
	StrCpy $R1 "$R1" -1
	Goto Loop
Done:
	Pop $R2
	Exch $R1
FunctionEnd

Function ConditionalAddToRegisty
  Pop $0
  Pop $1
  StrCmp "$0" "" ConditionalAddToRegisty_EmptyString
    WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \
    "$1" "$0"
    ;MessageBox MB_OK "Set Registry: '$1' to '$0'"
    DetailPrint "Set install registry entry: '$1' to '$0'"
  ConditionalAddToRegisty_EmptyString:
FunctionEnd

;--------------------------------

!ifdef CPACK_USES_DOWNLOAD
Function DownloadFile
    IfFileExists $INSTDIR\* +2
    CreateDirectory $INSTDIR
    Pop $0

    ; Skip if already downloaded
    IfFileExists $INSTDIR\$0 0 +2
    Return

    StrCpy $1 "@CPACK_DOWNLOAD_SITE@"

  try_again:
    NSISdl::download "$1/$0" "$INSTDIR\$0"

    Pop $1
    StrCmp $1 "success" success
    StrCmp $1 "Cancelled" cancel
    MessageBox MB_OK "Download failed: $1"
  cancel:
    Return
  success:
FunctionEnd
!endif

;--------------------------------
; Installation types
@CPACK_NSIS_INSTALLATION_TYPES@

;--------------------------------
; Component sections
@CPACK_NSIS_COMPONENT_SECTIONS@

;--------------------------------
; Define some macro setting for the gui
@CPACK_NSIS_INSTALLER_MUI_ICON_CODE@
@CPACK_NSIS_INSTALLER_ICON_CODE@
@CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC@
@CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE@

;--------------------------------
;Pages
  !insertmacro MUI_PAGE_WELCOME

  !insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@"
  Page custom InstallOptionsPage InstallOptionsPageLeave
  !insertmacro MUI_PAGE_DIRECTORY

  ;Start Menu Folder Page Configuration
  !define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX"
  !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
  !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
  !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER

  @CPACK_NSIS_PAGE_COMPONENTS@

  @CPACK_NSIS_EXTRA_PAGES@

  !insertmacro MUI_PAGE_INSTFILES
  !insertmacro MUI_PAGE_FINISH

  !insertmacro MUI_UNPAGE_CONFIRM
  !insertmacro MUI_UNPAGE_INSTFILES

;--------------------------------
;Languages

  !insertmacro MUI_LANGUAGE "English" ;first language is the default language
  !insertmacro MUI_LANGUAGE "Albanian"
  !insertmacro MUI_LANGUAGE "Arabic"
  !insertmacro MUI_LANGUAGE "Basque"
  !insertmacro MUI_LANGUAGE "Belarusian"
  !insertmacro MUI_LANGUAGE "Bosnian"
  !insertmacro MUI_LANGUAGE "Breton"
  !insertmacro MUI_LANGUAGE "Bulgarian"
  !insertmacro MUI_LANGUAGE "Croatian"
  !insertmacro MUI_LANGUAGE "Czech"
  !insertmacro MUI_LANGUAGE "Danish"
  !insertmacro MUI_LANGUAGE "Dutch"
  !insertmacro MUI_LANGUAGE "Estonian"
  !insertmacro MUI_LANGUAGE "Farsi"
  !insertmacro MUI_LANGUAGE "Finnish"
  !insertmacro MUI_LANGUAGE "French"
  !insertmacro MUI_LANGUAGE "German"
  !insertmacro MUI_LANGUAGE "Greek"
  !insertmacro MUI_LANGUAGE "Hebrew"
  !insertmacro MUI_LANGUAGE "Hungarian"
  !insertmacro MUI_LANGUAGE "Icelandic"
  !insertmacro MUI_LANGUAGE "Indonesian"
  !insertmacro MUI_LANGUAGE "Irish"
  !insertmacro MUI_LANGUAGE "Italian"
  !insertmacro MUI_LANGUAGE "Japanese"
  !insertmacro MUI_LANGUAGE "Korean"
  !insertmacro MUI_LANGUAGE "Kurdish"
  !insertmacro MUI_LANGUAGE "Latvian"
  !insertmacro MUI_LANGUAGE "Lithuanian"
  !insertmacro MUI_LANGUAGE "Luxembourgish"
  !insertmacro MUI_LANGUAGE "Macedonian"
  !insertmacro MUI_LANGUAGE "Malay"
  !insertmacro MUI_LANGUAGE "Mongolian"
  !insertmacro MUI_LANGUAGE "Norwegian"
  !insertmacro MUI_LANGUAGE "Polish"
  !insertmacro MUI_LANGUAGE "Portuguese"
  !insertmacro MUI_LANGUAGE "PortugueseBR"
  !insertmacro MUI_LANGUAGE "Romanian"
  !insertmacro MUI_LANGUAGE "Russian"
  !insertmacro MUI_LANGUAGE "Serbian"
  !insertmacro MUI_LANGUAGE "SerbianLatin"
  !insertmacro MUI_LANGUAGE "SimpChinese"
  !insertmacro MUI_LANGUAGE "Slovak"
  !insertmacro MUI_LANGUAGE "Slovenian"
  !insertmacro MUI_LANGUAGE "Spanish"
  !insertmacro MUI_LANGUAGE "Swedish"
  !insertmacro MUI_LANGUAGE "Thai"
  !insertmacro MUI_LANGUAGE "TradChinese"
  !insertmacro MUI_LANGUAGE "Turkish"
  !insertmacro MUI_LANGUAGE "Ukrainian"
  !insertmacro MUI_LANGUAGE "Welsh"

;--------------------------------
;Reserve Files

  ;These files should be inserted before other files in the data block
  ;Keep these lines before any File command
  ;Only for solid compression (by default, solid compression is enabled for BZIP2 and LZMA)

;--------------------------------
;Installer Sections

Section "-Core installation"
  ;Use the entire tree produced by the INSTALL target.  Keep the
  ;list of directories here in sync with the RMDir commands below.
  SetOutPath "$INSTDIR"
  @CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS@
  @CPACK_NSIS_FULL_INSTALL@

  ;Store installation folder
  WriteRegStr SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "" $INSTDIR

  ;Create uninstaller
  WriteUninstaller "$INSTDIR\Uninstall.exe"
  Push "DisplayName"
  Push "@CPACK_NSIS_DISPLAY_NAME@"
  Call ConditionalAddToRegisty
  Push "DisplayVersion"
  Push "@CPACK_PACKAGE_VERSION@"
  Call ConditionalAddToRegisty
  Push "Publisher"
  Push "@CPACK_PACKAGE_VENDOR@"
  Call ConditionalAddToRegisty
  Push "UninstallString"
  Push "$INSTDIR\Uninstall.exe"
  Call ConditionalAddToRegisty
  Push "NoRepair"
  Push "1"
  Call ConditionalAddToRegisty

  !ifdef CPACK_NSIS_ADD_REMOVE
  ;Create add/remove functionality
  Push "ModifyPath"
  Push "$INSTDIR\AddRemove.exe"
  Call ConditionalAddToRegisty
  !else
  Push "NoModify"
  Push "1"
  Call ConditionalAddToRegisty
  !endif

  ; Optional registration
  Push "DisplayIcon"
  Push "$INSTDIR\@CPACK_NSIS_INSTALLED_ICON_NAME@"
  Call ConditionalAddToRegisty
  Push "HelpLink"
  Push "@CPACK_NSIS_HELP_LINK@"
  Call ConditionalAddToRegisty
  Push "URLInfoAbout"
  Push "@CPACK_NSIS_URL_INFO_ABOUT@"
  Call ConditionalAddToRegisty
  Push "Contact"
  Push "@CPACK_NSIS_CONTACT@"
  Call ConditionalAddToRegisty
  !insertmacro MUI_STARTMENU_WRITE_BEGIN Application

  ;Create shortcuts
  CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
@CPACK_NSIS_CREATE_ICONS@
@CPACK_NSIS_CREATE_ICONS_EXTRA@
  CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe"

  ; Write special uninstall registry entries
  Push "StartMenu"
  Push "$STARTMENU_FOLDER"
  Call ConditionalAddToRegisty
  WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \
    "DoNotAddToPath" $DO_NOT_ADD_TO_PATH
  WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \
    "AddToPathAllUsers" $ADD_TO_PATH_ALL_USERS
  WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \
    "AddToPathCurrentUser" $ADD_TO_PATH_CURRENT_USER
  WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \
    "InstallToDesktop" $INSTALL_DESKTOP

  !insertmacro MUI_STARTMENU_WRITE_END

@CPACK_NSIS_EXTRA_INSTALL_COMMANDS@

SectionEnd

Section "-Add to path"
  Push $INSTDIR\bin
  ${If} "@CPACK_NSIS_MODIFY_PATH@" == "ON"
    ${If} $DO_NOT_ADD_TO_PATH = ${BST_UNCHECKED}
      Call AddToPath
    ${EndIf}
  ${EndIf}
SectionEnd

;--------------------------------
; Create custom pages
Function InstallOptionsPage
  Push $R0
  Push $0

  !insertmacro MUI_HEADER_TEXT "Install Options" "Choose options for installing @CPACK_NSIS_PACKAGE_NAME@"

  nsDialogs::Create 1018
  Pop $R0
  ${If} $R0 == error
    Abort
  ${EndIf}

  ${NSD_CreateLabel} 0u 0u 100% 20u 'By default @CPACK_PACKAGE_INSTALL_DIRECTORY@ does not add its directory to the system PATH.'
  Pop $0

  ${NSD_CreateRadioButton} 0u 30u 100% 10u 'Do not add @CPACK_PACKAGE_NAME@ to the system PATH'
  Pop $RB_DO_NOT_ADD_TO_PATH
  ${NSD_SetState} $RB_DO_NOT_ADD_TO_PATH $DO_NOT_ADD_TO_PATH

  ${NSD_CreateRadioButton} 0u 40u 100% 10u 'Add @CPACK_PACKAGE_NAME@ to the system PATH for all users'
  Pop $RB_ADD_TO_PATH_ALL_USERS
  ${NSD_SetState} $RB_ADD_TO_PATH_ALL_USERS $ADD_TO_PATH_ALL_USERS

  ${NSD_CreateRadioButton} 0u 50u 100% 10u 'Add @CPACK_PACKAGE_NAME@ to the system PATH for the current user'
  Pop $RB_ADD_TO_PATH_CURRENT_USER
  ${NSD_SetState} $RB_ADD_TO_PATH_CURRENT_USER $ADD_TO_PATH_CURRENT_USER

  ${NSD_CreateCheckBox} 0u 80u 100% 10u 'Create @CPACK_PACKAGE_NAME@ Desktop Icon'
  Pop $CB_INSTALL_DESKTOP
  ${NSD_SetState} $CB_INSTALL_DESKTOP $INSTALL_DESKTOP

  @CPACK_NSIS_EXTRA_INSTALL_OPTIONS@

  nsDialogs::Show

  Pop $0
  Pop $R0
FunctionEnd

Function InstallOptionsPageLeave
  ${NSD_GetState} $RB_DO_NOT_ADD_TO_PATH $DO_NOT_ADD_TO_PATH
  ${NSD_GetState} $RB_ADD_TO_PATH_ALL_USERS $ADD_TO_PATH_ALL_USERS
  ${NSD_GetState} $RB_ADD_TO_PATH_CURRENT_USER $ADD_TO_PATH_CURRENT_USER

  ${NSD_GetState} $CB_INSTALL_DESKTOP $INSTALL_DESKTOP

  @CPACK_NSIS_EXTRA_INSTALL_OPTIONS_READ@
FunctionEnd

;--------------------------------
; determine admin versus local install
Function un.onInit
  Push $0
  Push $1

  ClearErrors
  UserInfo::GetName
  IfErrors noLM
  Pop $0
  UserInfo::GetAccountType
  Pop $1
  StrCmp $1 "Admin" 0 +3
    SetShellVarContext all
    ;MessageBox MB_OK 'User "$0" is in the Admin group'
    Goto done
  StrCmp $1 "Power" 0 +3
    SetShellVarContext all
    ;MessageBox MB_OK 'User "$0" is in the Power Users group'
    Goto done

  noLM:
    ;Get installation folder from registry if available

  done:

  Pop $1
  Pop $0
FunctionEnd

;--- Add/Remove callback functions: ---
!macro SectionList MacroName
  ;This macro used to perform operation on multiple sections.
  ;List all of your components in following manner here.
@CPACK_NSIS_COMPONENT_SECTION_LIST@
!macroend

Section -FinishComponents
  ;Removes unselected components and writes component status to registry
  !insertmacro SectionList "FinishSection"

!ifdef CPACK_NSIS_ADD_REMOVE
  ; Get the name of the installer executable
  System::Call 'kernel32::GetModuleFileNameA(i 0, t .R0, i 1024) i r1'
  StrCpy $R3 $R0

  ; Strip off the last 13 characters, to see if we have AddRemove.exe
  StrLen $R1 $R0
  IntOp $R1 $R0 - 13
  StrCpy $R2 $R0 13 $R1
  StrCmp $R2 "AddRemove.exe" addremove_installed

  ; We're not running AddRemove.exe, so install it
  CopyFiles $R3 $INSTDIR\AddRemove.exe

  addremove_installed:
!endif
SectionEnd
;--- End of Add/Remove callback functions ---

;--------------------------------
; Component dependencies
Function .onSelChange
  !insertmacro SectionList MaybeSelectionChanged
FunctionEnd

;--------------------------------
;Uninstaller Section

Section "Uninstall"
  ReadRegStr $START_MENU SHCTX \
   "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "StartMenu"
  ;MessageBox MB_OK "Start menu is in: $START_MENU"
  ReadRegDWORD $DO_NOT_ADD_TO_PATH SHCTX \
    "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "DoNotAddToPath"
  ReadRegDWORD $ADD_TO_PATH_ALL_USERS SHCTX \
    "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathAllUsers"
  ReadRegDWORD $ADD_TO_PATH_CURRENT_USER SHCTX \
    "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathCurrentUser"
  ;MessageBox MB_OK "Add to path: $DO_NOT_ADD_TO_PATH all users: $ADD_TO_PATH_ALL_USERS"
  ReadRegDWORD $INSTALL_DESKTOP SHCTX \
    "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "InstallToDesktop"
  ;MessageBox MB_OK "Install to desktop: $INSTALL_DESKTOP "

@CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@

  ;Remove files we installed.
  ;Keep the list of directories here in sync with the File commands above.
@CPACK_NSIS_DELETE_FILES@
@CPACK_NSIS_DELETE_DIRECTORIES@

!ifdef CPACK_NSIS_ADD_REMOVE
  ;Remove the add/remove program
  Delete "$INSTDIR\AddRemove.exe"
!endif

  ;Remove the uninstaller itself.
  Delete "$INSTDIR\Uninstall.exe"
  DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"

  ;Remove the installation directory if it is empty.
  RMDir "$INSTDIR"

  ; Remove the registry entries.
  DeleteRegKey SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"

  ; Removes all optional components
  !insertmacro SectionList "RemoveSection_CPack"

  !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP

  Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
@CPACK_NSIS_DELETE_ICONS@
@CPACK_NSIS_DELETE_ICONS_EXTRA@

  ;Delete empty start menu parent diretories
  StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"

  startMenuDeleteLoop:
    ClearErrors
    RMDir $MUI_TEMP
    GetFullPathName $MUI_TEMP "$MUI_TEMP\.."

    IfErrors startMenuDeleteLoopDone

    StrCmp "$MUI_TEMP" "$SMPROGRAMS" startMenuDeleteLoopDone startMenuDeleteLoop
  startMenuDeleteLoopDone:

  ; If the user changed the shortcut, then untinstall may not work. This should
  ; try to fix it.
  StrCpy $MUI_TEMP "$START_MENU"
  Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
@CPACK_NSIS_DELETE_ICONS_EXTRA@

  ;Delete empty start menu parent diretories
  StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"

  secondStartMenuDeleteLoop:
    ClearErrors
    RMDir $MUI_TEMP
    GetFullPathName $MUI_TEMP "$MUI_TEMP\.."

    IfErrors secondStartMenuDeleteLoopDone

    StrCmp "$MUI_TEMP" "$SMPROGRAMS" secondStartMenuDeleteLoopDone secondStartMenuDeleteLoop
  secondStartMenuDeleteLoopDone:

  DeleteRegKey /ifempty SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"

  Push $INSTDIR\bin
  ${Unless} $DO_NOT_ADD_TO_PATH = ${BST_CHECKED}
    Call un.RemoveFromPath
  ${EndUnless}
SectionEnd

;--------------------------------
; determine admin versus local install
; Is install for "AllUsers" or "JustMe"?
; Default to "JustMe" - set to "AllUsers" if admin or on Win9x
; This function is used for the very first "custom page" of the installer.
; This custom page does not show up visibly, but it executes prior to the
; first visible page and sets up $INSTDIR properly...
; Choose different default installation folder based on SV_ALLUSERS...
; "Program Files" for AllUsers, "My Documents" for JustMe...

Function .onInit
  Push $0
  Push $1
  Push $2
  Push $3

  StrCmp "@CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL@" "ON" 0 inst

  ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "UninstallString"
  StrCmp $0 "" inst

  MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION \
  "@CPACK_NSIS_PACKAGE_NAME@ is already installed. $\n$\nDo you want to uninstall the old version before installing the new one?" \
  IDYES uninst IDNO inst
  Abort

;Run the uninstaller
uninst:
  ClearErrors
  StrLen $2 "\Uninstall.exe"
  StrCpy $3 $0 -$2 # remove "\Uninstall.exe" from UninstallString to get path
  ExecWait '$0 _?=$3' ;Do not copy the uninstaller to a temp file

  IfErrors uninst_failed inst
uninst_failed:
  MessageBox MB_OK|MB_ICONSTOP "Uninstall failed."
  Abort

inst:
  ; Reads components status for registry
  !insertmacro SectionList "InitSection"

  ; check to see if /D has been used to change
  ; the install directory by comparing it to the
  ; install directory that is expected to be the
  ; default
  StrCpy $IS_DEFAULT_INSTALLDIR 0
  StrCmp "$INSTDIR" "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" 0 +2
    StrCpy $IS_DEFAULT_INSTALLDIR 1

  StrCpy $SV_ALLUSERS "JustMe"
  ; if default install dir then change the default
  ; if it is installed for JustMe
  StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2
    StrCpy $INSTDIR "$DOCUMENTS\@CPACK_PACKAGE_INSTALL_DIRECTORY@"

  ClearErrors
  UserInfo::GetName
  IfErrors noLM
  Pop $0
  UserInfo::GetAccountType
  Pop $1
  StrCmp $1 "Admin" 0 +4
    SetShellVarContext all
    ;MessageBox MB_OK 'User "$0" is in the Admin group'
    StrCpy $SV_ALLUSERS "AllUsers"
    Goto done
  StrCmp $1 "Power" 0 +4
    SetShellVarContext all
    ;MessageBox MB_OK 'User "$0" is in the Power Users group'
    StrCpy $SV_ALLUSERS "AllUsers"
    Goto done

  noLM:
    StrCpy $SV_ALLUSERS "AllUsers"
    ;Get installation folder from registry if available

  done:
  StrCmp $SV_ALLUSERS "AllUsers" 0 +3
    StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2
      StrCpy $INSTDIR "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@"

  IntOp $DO_NOT_ADD_TO_PATH 0 + ${BST_CHECKED} ; set to checked
  IntOp $ADD_TO_PATH_ALL_USERS 0 + ${BST_UNCHECKED} ; set to unchecked
  IntOp $ADD_TO_PATH_CURRENT_USER 0 + ${BST_UNCHECKED} ; ditto
  IntOp $INSTALL_DESKTOP 0 + ${BST_UNCHECKED} ; set to unchecked

  @CPACK_NSIS_EXTRA_INIT_COMMANDS@

  Pop $3
  Pop $2
  Pop $1
  Pop $0
FunctionEnd


code:
#
# Macros for processing ActiveX and COM controls with ActiveQt
#

if (WIN32)
  include (CMakeParseArguments)

  find_program (DUMPCPP_Executable dumpcpp.exe)

  # wrap_ax_server (outfiles inputfile ...)

  function (WRAP_AX_SERVER outfiles)
    set (options)
    set (oneValueArgs)
    set (multiValueArgs OPTIONS)

    cmake_parse_arguments (_WRAP_AX_SERVER "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

    set (ax_server_files ${_WRAP_AX_SERVER_UNPARSED_ARGUMENTS})
    set (ax_server_options ${_WRAP_AX_SERVER_OPTIONS})

    foreach (it ${ax_server_files})
      get_filename_component (outfile ${it} NAME_WE)
      get_filename_component (infile ${it} ABSOLUTE)
      set (outfile ${CMAKE_CURRENT_BINARY_DIR}/${outfile})
      add_custom_command (
	OUTPUT ${outfile}.h ${outfile}.cpp
	COMMAND ${DUMPCPP_Executable}
	ARGS ${AX_SERVER_options} -o "${outfile}" "${infile}"
	MAIN_DEPENDENCY ${infile} VERBATIM)
      list (APPEND ${outfiles} ${outfile}.cpp)
    endforeach()
    set(${outfiles} ${${outfiles}} PARENT_SCOPE)
  endfunction ()

endif (WIN32)


code:
# Load version number components.
include (${CMAKE_SOURCE_DIR}/Versions.cmake)

# Compute the full version string.
if (WSJTX_RC AND NOT WSJTX_VERSION_IS_RELEASE)
  set (WSJTX_VERSION_PATCH ${WSJTX_VERSION_PATCH}-rc${WSJTX_RC})
elseif (NOT WSJTX_VERSION_IS_RELEASE)
  set (WSJTX_VERSION_PATCH ${WSJTX_VERSION_PATCH}-devel)
endif (WSJTX_RC AND NOT WSJTX_VERSION_IS_RELEASE)

set (wsjtx_VERSION ${WSJTX_VERSION_MAJOR}.${WSJTX_VERSION_MINOR}.${WSJTX_VERSION_PATCH})


code:
if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
  message (FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
endif ()

file (READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string (REGEX REPLACE "\n" ";" files "${files}")
foreach (file ${files})
  message (STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
  if (EXISTS "$ENV{DESTDIR}${file}")
    exec_program (
      "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
      OUTPUT_VARIABLE rm_out
      RETURN_VALUE rm_retval
      )
    if ("${rm_retval}" STREQUAL 0)
    else ()
      message (FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
    endif ()
  else ()
    message (STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
  endif ()
endforeach ()


code:
message (STATUS "Checking for revision information")
if (EXISTS "${SOURCE_DIR}/.svn")
  message (STATUS "Checking for Subversion revision information")
  find_package (Subversion QUIET REQUIRED)
  # the FindSubversion.cmake module is part of the standard distribution
  include (FindSubversion)
  # extract working copy information for SOURCE_DIR into MY_XXX variables
  Subversion_WC_INFO (${SOURCE_DIR} MY)
  message ("${MY_WC_INFO}")
  # determine if the working copy has outstanding changes
  execute_process (COMMAND ${Subversion_SVN_EXECUTABLE} status ${SOURCE_DIR}
    OUTPUT_FILE "${BINARY_DIR}/svn_status.txt"
    OUTPUT_STRIP_TRAILING_WHITESPACE)
  file (STRINGS "${BINARY_DIR}/svn_status.txt" __svn_changes
    REGEX "^[^?].*$"
    )
  if (__svn_changes)
    message (WARNING "Source tree based on revision ${MY_WC_LAST_CHANGED_REV} appears to have local changes")
    set (MY_WC_LAST_CHANGED_REV "${MY_WC_LAST_CHANGED_REV}-dirty")
    foreach (__svn_change ${__svn_changes})
      message (STATUS "${__svn_change}")
    endforeach (__svn_change ${__svn_changes})
  endif (__svn_changes)
  message (STATUS "${SOURCE_DIR} contains a .svn and is revision ${MY_WC_LAST_CHANGED_REV}")
  # write a file with the SCS_VERSION define
  file (WRITE "${BINARY_DIR}/scs_version.h.txt" "#define SCS_VERSION r${MY_WC_LAST_CHANGED_REV}\n")
elseif (EXISTS "${SOURCE_DIR}/.git")
  if (EXISTS "${SOURCE_DIR}/.git/svn/.metadata")  # try git-svn
    message (STATUS "Checking for Subversion revision information using git-svn")
    include (${SOURCE_DIR}/CMake/Modules/FindGitSubversion.cmake)
    # extract working copy information for SOURCE_DIR into MY_XXX variables
    GitSubversion_WC_INFO (${SOURCE_DIR} MY)
    message ("${MY_WC_INFO}")
    # try and determine if the working copy has outstanding changes
    execute_process (COMMAND ${GIT_EXECUTABLE} --git-dir=${SOURCE_DIR}/.git --work-tree=${SOURCE_DIR} svn dcommit --dry-run
      RESULT_VARIABLE __git_svn_status
      OUTPUT_FILE "${BINARY_DIR}/svn_status.txt"
      ERROR_QUIET
      OUTPUT_STRIP_TRAILING_WHITESPACE)
    file (STRINGS "${BINARY_DIR}/svn_status.txt" __svn_changes
      REGEX "^diff-tree"
      )
    if ((NOT ${__git_svn_status} EQUAL 0) OR __svn_changes)
      message (WARNING "Source tree based on revision ${MY_WC_LAST_CHANGED_REV} appears to have local changes")
      set (MY_WC_LAST_CHANGED_REV "${MY_WC_LAST_CHANGED_REV}-dirty")
    endif ()
    # write a file with the SVNVERSION define
    file (WRITE "${BINARY_DIR}/scs_version.h.txt" "#define SCS_VERSION r${MY_WC_LAST_CHANGED_REV}\n")
  else ()
    #
    # try git
    #
    message (STATUS "Checking for gitrevision information")
    include (${SOURCE_DIR}/CMake/Modules/GetGitRevisionDescription.cmake)
    get_git_head_revision (${SOURCE_DIR} GIT_REFSPEC GIT_SHA1)
    git_local_changes (${SOURCE_DIR} GIT_DIRTY)
    string (SUBSTRING "${GIT_SHA1}" 0 6 GIT_SHA1)
    if ("${GIT_DIRTY}" STREQUAL "DIRTY")
      message (WARNING "Source tree based on revision ${GIT_REFSPEC} ${GIT_SHA1} appears to have local changes")
      set (GIT_SHA1 "${GIT_SHA1}-dirty")
      execute_process (COMMAND ${GIT_EXECUTABLE} --git-dir=${SOURCE_DIR}/.git --work-tree=${SOURCE_DIR} status
	ERROR_QUIET
	OUTPUT_STRIP_TRAILING_WHITESPACE)
    endif ()
    message (STATUS "refspec: ${GIT_REFSPEC} - SHA1: ${GIT_SHA1}")
    file (WRITE "${BINARY_DIR}/scs_version.h.txt" "#define SCS_VERSION ${GIT_SHA1}\n")
  endif ()
else()
  message (STATUS "No SCS found")
  file (WRITE "${BINARY_DIR}/scs_version.h.txt" "#define SCS_VERSION\n")
endif ()

# copy the file to the final header only if the version changes
# reduces needless rebuilds
execute_process (COMMAND ${CMAKE_COMMAND} -E copy_if_different "${BINARY_DIR}/scs_version.h.txt" "${OUTPUT_DIR}/scs_version.h")


code:
# This file is configured at cmake time, and loaded at cpack time.
# To pass variables to cpack from cmake, they must be configured
# in this file.

set (CPACK_SET_DESTDIR true)

set (CPACK_PACKAGE_VENDOR "@PROJECT_VENDOR@")
set (CPACK_PACKAGE_CONTACT "@PROJECT_CONTACT@")
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "@PROJECT_SUMMARY_DESCRIPTION@")
set (CPACK_RESOURCE_FILE_LICENSE "@PROJECT_SOURCE_DIR@/COPYING")
set (CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
set (CPACK_PACKAGE_EXECUTABLES js8call "@PROJECT_NAME@")
set (CPACK_CREATE_DESKTOP_LINKS js8call)
set (CPACK_STRIP_FILES TRUE)

#
# components
#
#set (CPACK_COMPONENTS_ALL runtime)
#set (CPACK_COMPONENT_RUNTIME_DISPLAY_NAME "@PROJECT_NAME@ Application")
#set (CPACK_COMPONENT_RUNTIME_DESCRIPTION "@WSJTX_DESCRIPTION_SUMMARY@")

if (CPACK_GENERATOR MATCHES "NSIS")
  set (CPACK_SET_DESTDIR FALSE)
  set (CPACK_STRIP_FILES FALSE)	# breaks Qt packaging on Windows

  # set (CPACK_NSIS_INSTALL_ROOT "C:\\JS8Call")

  if(CMAKE_CL_64)
    set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
    set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} (Win64)")
    set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION} (Win64)")
  else()
    set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
    set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
    set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
  endif()

  # set the install/unistall icon used for the installer itself
  # There is a bug in NSI that does not handle full unix paths properly.
  set (CPACK_NSIS_MUI_ICON "@PROJECT_SOURCE_DIR@/icons/windows-icons\\js8call.ico")
  set (CPACK_NSIS_MUI_UNIICON "@PROJECT_SOURCE_DIR@/icons/windows-icons\\js8call.ico")
  # set the package header icon for MUI
  set (CPACK_PACKAGE_ICON "@PROJECT_SOURCE_DIR@/icons/windows-icons\\installer_logo.bmp")
  # tell cpack to create links to the doc files
  set (CPACK_NSIS_MENU_LINKS
    "@PROJECT_HOMEPAGE@" "@PROJECT_NAME@ Web Site"
    )
  # Use the icon from wsjtx for add-remove programs
  set (CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\js8call.exe")

  set (CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
  set (CPACK_NSIS_HELP_LINK "@PROJECT_HOMEPAGE@")
  set (CPACK_NSIS_URL_INFO_ABOUT "@PROJECT_HOMEPAGE@")
  set (CPACK_NSIS_CONTACT "${CPACK_PACKAGE_CONTACT}")
  set (CPACK_NSIS_MUI_FINISHPAGE_RUN "js8call.exe")
  set (CPACK_NSIS_MODIFY_PATH ON)
endif ()

if ("${CPACK_GENERATOR}" STREQUAL "PackageMaker")
  set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-pkg")
  set (CPACK_PACKAGE_DEFAULT_LOCATION "/Applications")
  set (CPACK_PACKAGING_INSTALL_PREFIX "/")
endif ()

if ("${CPACK_GENERATOR}" STREQUAL "DragNDrop")
  set (CPACK_DMG_VOLUME_NAME "@PROJECT_NAME@")
  set (CPACK_DMG_BACKGROUND_IMAGE "@PROJECT_SOURCE_DIR@/icons/Darwin/DragNDrop Background.png")
  set (CPACK_DMG_DS_STORE "@PROJECT_SOURCE_DIR@/Darwin/js8call_DMG.DS_Store")
  set (CPACK_BUNDLE_NAME "@WSJTX_BUNDLE_NAME@")
  set (CPACK_PACKAGE_ICON "@PROJECT_BINARY_DIR@/js8call.icns")
  set (CPACK_BUNDLE_ICON "@PROJECT_BINARY_DIR@/js8call.icns")
  set (CPACK_BUNDLE_STARTUP_COMMAND "@PROJECT_SOURCE_DIR@/Mac-js8call-startup.sh")
  set (CPACK_PACKAGING_INSTALL_PREFIX "/")
endif ()

if ("${CPACK_GENERATOR}" STREQUAL "WIX")
  # Reset CPACK_PACKAGE_VERSION to deal with WiX restriction.
  # But the file names still use the full CMake_VERSION value:
  set (CPACK_PACKAGE_FILE_NAME
    "${CPACK_PACKAGE_NAME}-@js8call_VERSION@-${CPACK_SYSTEM_NAME}")
  set (CPACK_SOURCE_PACKAGE_FILE_NAME
    "${CPACK_PACKAGE_NAME}-@js8call_VERSION@-Source")

  if (NOT CPACK_WIX_SIZEOF_VOID_P)
    set (CPACK_WIX_SIZEOF_VOID_P "@CMAKE_SIZEOF_VOID_P@")
  endif ()
endif ()

if ("${CPACK_GENERATOR}" STREQUAL "DEB")
  set (CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE})
  set (CPACK_COMPONENTS_ALL ${CPACK_COMPONENTS_ALL} Debian)
endif ("${CPACK_GENERATOR}" STREQUAL "DEB")

if ("${CPACK_GENERATOR}" STREQUAL "RPM")
  set (CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}.${CPACK_RPM_PACKAGE_ARCHITECTURE})
endif ("${CPACK_GENERATOR}" STREQUAL "RPM")

message (STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")