Commit 44850a26 authored by Konstantin Podsvirov's avatar Konstantin Podsvirov Committed by Brad King

CPack: Add an "IFW" generator for Qt Framework Installer

Add support for packaging with the Qt Framework Installer tools:

 http://qt-project.org/doc/qtinstallerframework/index.htmlReviewed-by: Nils Gladitz's avatarNils Gladitz <nilsgladitz@gmail.com>
parent 3e3ab2ad
......@@ -59,11 +59,43 @@ if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
if(${CPACK_SYSTEM_NAME} MATCHES Windows)
if(CMAKE_CL_64)
set(CPACK_SYSTEM_NAME win64-x64)
set(CPACK_IFW_TARGET_DIRECTORY "@RootDir@/Program Files/${CMAKE_PROJECT_NAME}")
else()
set(CPACK_SYSTEM_NAME win32-x86)
endif()
endif()
# default component for IFW
if(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
set(_CPACK_IFW_COMPONENT_NAME ${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME})
else()
set(_CPACK_IFW_COMPONENT_NAME Unspecified)
endif()
string(TOUPPER ${_CPACK_IFW_COMPONENT_NAME} _CPACK_IFW_COMPONENT_UNAME)
if(${CMAKE_SYSTEM_NAME} MATCHES Windows)
if(BUILD_QtDialog)
set(_CPACK_IFW_SHORTCUT_OPTIONAL "${_CPACK_IFW_SHORTCUT_OPTIONAL}component.addOperation(\"CreateShortcut\", \"@TargetDir@/bin/cmake-gui.exe\", \"@StartMenuDir@/CMake (cmake-gui).lnk\");\n")
endif()
if(SPHINX_HTML)
set(_CPACK_IFW_SHORTCUT_OPTIONAL "${_CPACK_IFW_SHORTCUT_OPTIONAL}component.addOperation(\"CreateShortcut\", \"@TargetDir@/doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/html/index.html\", \"@StartMenuDir@/CMake Documentation.lnk\");\n")
endif()
configure_file("${CMake_SOURCE_DIR}/Source/QtIFW/installscript.qs.in"
"${CMake_BINARY_DIR}/installscript.qs" @ONLY
)
install(FILES "${CMake_SOURCE_DIR}/Source/QtIFW/cmake.org.html"
DESTINATION "."
)
set(_CPACK_IFW_COMPONENT_SCRIPT "set(CPACK_IFW_COMPONENT_${_CPACK_IFW_COMPONENT_UNAME}_SCRIPT \"${CMake_BINARY_DIR}/installscript.qs\")")
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES Linux)
set(CPACK_IFW_TARGET_DIRECTORY "@HomeDir@/${CMAKE_PROJECT_NAME}")
set(CPACK_IFW_ADMIN_TARGET_DIRECTORY "@ApplicationsDir@/${CMAKE_PROJECT_NAME}")
endif()
set(_CPACK_IFW_PACKAGE_VERSION ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH})
if(NOT DEFINED CPACK_PACKAGE_FILE_NAME)
# if the CPACK_PACKAGE_FILE_NAME is not defined by the cache
# default to source package - system, on cygwin system is not
......
......@@ -31,6 +31,20 @@ endif()
# they might not if qt was not enabled for the build
include("@QT_DIALOG_CPACK_OPTIONS_FILE@" OPTIONAL)
if(CPACK_GENERATOR MATCHES "IFW")
# Version with QtIFW limitations
set(CPACK_PACKAGE_VERSION "@_CPACK_IFW_PACKAGE_VERSION@")
# Enable install default component
set(CPACK_COMPONENTS_ALL "@_CPACK_IFW_COMPONENT_NAME@")
# Configuration
set(CPACK_COMPONENT_@_CPACK_IFW_COMPONENT_UNAME@_DISPLAY_NAME "@CPACK_PACKAGE_NAME@")
set(CPACK_COMPONENT_@_CPACK_IFW_COMPONENT_UNAME@_DESCRIPTION "@CPACK_PACKAGE_DESCRIPTION_SUMMARY@")
# IFW Configuration
set(CPACK_IFW_COMPONENT_@_CPACK_IFW_COMPONENT_UNAME@_NAME "@CPACK_PACKAGE_NAME@")
set(CPACK_IFW_COMPONENT_@_CPACK_IFW_COMPONENT_UNAME@_LICENSES "@CPACK_PACKAGE_NAME@ Copyright" "@CPACK_RESOURCE_FILE_LICENSE@")
@_CPACK_IFW_COMPONENT_SCRIPT@
endif()
if(CPACK_GENERATOR MATCHES "CygwinSource")
# when packaging source make sure the .build directory is not included
set(CPACK_SOURCE_IGNORE_FILES
......
......@@ -55,6 +55,7 @@ All Modules
/module/CPackCygwin
/module/CPackDeb
/module/CPackDMG
/module/CPackIFW
/module/CPackNSIS
/module/CPackPackageMaker
/module/CPackRPM
......
.. cmake-module:: ../../Modules/CPackIFW.cmake
......@@ -435,6 +435,7 @@ if(NOT CPACK_GENERATOR)
option(CPACK_BINARY_WIX "Enable to build WiX packages" OFF)
option(CPACK_BINARY_ZIP "Enable to build ZIP packages" OFF)
endif()
option(CPACK_BINARY_IFW "Enable to build IFW packages" OFF)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_BUNDLE Bundle)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_DRAGNDROP DragNDrop)
......@@ -450,6 +451,7 @@ if(NOT CPACK_GENERATOR)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_TZ TZ)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_WIX WIX)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_ZIP ZIP)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_IFW IFW)
endif()
......
......@@ -458,6 +458,9 @@ macro(cpack_add_component_group grpname)
cpack_append_string_variable_set_command(
CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}_DESCRIPTION
CPACK_ADDGRP_STR)
cpack_append_string_variable_set_command(
CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}_PARENT_GROUP
CPACK_ADDGRP_STR)
cpack_append_option_set_command(
CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}_EXPANDED
CPACK_ADDGRP_STR)
......
#.rst:
# CPackIFW
# --------
#
# .. _QtIFW: http://qt-project.org/doc/qtinstallerframework/index.html
#
# This module looks for the location of the command line utilities supplied with
# the Qt Installer Framework (QtIFW_).
#
# The module also defines several commands to control the behavior of the
# CPack ``IFW`` generator.
#
#
# Overview
# ^^^^^^^^
#
# CPack ``IFW`` generator helps you create online and offline
# binary cross-platform installers with a graphical user interface.
#
# CPack IFW generator prepare project installation and generate configuration
# and meta information for QtIFW_ tools.
#
# The QtIFW_ provides a set of tools and utilities to create
# installers for the supported desktop Qt platforms: Linux, Microsoft Windows,
# and Mac OS X.
#
# To use CPack ``IFW`` generator you must also install QtIFW_.
#
# Variables
# ^^^^^^^^^
#
# Variables that Change Behavior
# """"""""""""""""""""""""""""""
#
# .. variable:: CPACK_IFW_TARGET_DIRECTORY
#
# Default target directory for installation.
# By default used "@ApplicationsDir@/:variable:`CPACK_PACKAGE_INSTALL_DIRECTORY`"
#
# You can use predefined variables.
#
# .. variable:: CPACK_IFW_ADMIN_TARGET_DIRECTORY
#
# Default target directory for installation with administrator rights.
#
# You can use predefined variables.
#
# .. variable:: CPACK_IFW_RESOLVE_DUPLICATE_NAMES
#
# Resolve duplicate names when installing components with groups.
#
# .. variable:: CPACK_IFW_PACKAGES_DIRECTORIES
#
# Additional prepared packages dirs that will be used to resolve
# dependent components.
#
# Advanced Variables
# """"""""""""""""""
#
# .. variable:: CPACK_IFW_BINARYCREATOR_EXECUTABLE
#
# The path to "binarycreator" command line client.
#
# This variable is cached and can be configured user if need.
#
# .. variable:: CPACK_IFW_BINARYCREATOR_EXECUTABLE_FOUND
#
# True if the "binarycreator" command line client was found.
#
# .. variable:: CPACK_IFW_REPOGEN_EXECUTABLE
#
# The path to "repogen" command line client.
#
# This variable is cached and can be configured user if need.
#
# .. variable:: CPACK_IFW_REPOGEN_EXECUTABLE_FOUND
#
# True if the "repogen" command line client was found.
#
# Commands
# ^^^^^^^^^
#
# The module defines the following commands:
#
# --------------------------------------------------------------------------
#
# .. command:: cpack_ifw_configure_component
#
# Sets the arguments specific to the CPack IFW generator.
#
# ::
#
# cpack_ifw_configure_component(<compname>
# [VERSION <version>]
# [SCRIPT <script>]
# [NAME <name>]
# [PRIORITY <priority>]
# [LICENSES <display_name> <file_path> ...])
#
# This command should be called after cpack_add_component command.
#
# ``VERSION`` is version of component. By default used :variable:`CPACK_PACKAGE_VERSION`.
#
# ``SCRIPT`` is relative or absolute path to operations script
# for this component.
#
# ``NAME`` is used to create domain-like identification for this component.
# By default used origin component name.
#
# ``PRIORITY`` is priority of the component in the tree.
#
# ``LICENSES`` pair of <display_name> and <file_path> of license text for this
# component. You can specify more then one license.
#
# --------------------------------------------------------------------------
#
# .. command:: cpack_ifw_configure_component_group
#
# Sets the arguments specific to the CPack IFW generator.
#
# ::
#
# cpack_ifw_configure_component_group(<grpname>
# [VERSION <version>]
# [NAME <name>]
# [PRIORITY <priority>]
# [LICENSES <display_name> <file_path> ...])
#
# This command should be called after cpack_add_component_group command.
#
# ``VERSION`` is version of component group. By default used :variable:`CPACK_PACKAGE_VERSION`.
#
# ``NAME`` is used to create domain-like identification for this component group.
# By default used origin component group name.
#
# ``PRIORITY`` is priority of the component group in the tree.
#
# ``LICENSES`` pair of <display_name> and <file_path> of license text for this
# component group. You can specify more then one license.
#
# Example usage
# ^^^^^^^^^^^^^
#
# .. code-block:: cmake
#
# set(CPACK_PACKAGE_NAME "MyPackage")
# set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MyPackage Installation Example")
# set(CPACK_PACKAGE_VERSION "1.0.0")
#
# include(CPack)
# include(CPackIFW)
#
# cpack_add_component(myapp
# DISPLAY_NAME "MyApp"
# DESCRIPTION "My Application")
# cpack_ifw_configure_component(myapp
# VERSION "1.2.3"
# SCRIPT "operations.qs")
#
#
# Online installer
# ^^^^^^^^^^^^^^^^
#
# By defaul CPack IFW generator make offline installer. This means that all
# components will be packaged into a binary file.
#
# To make a component downloaded, you must set the ``DOWNLOADED`` option in
# :command:`cpack_add_component`.
#
# Then you would use the command :command:`cpack_configure_downloads`.
# If you set ``ALL`` option all components will be downloaded.
#
# CPack IFW generator create "repository" dir in current binary dir. You
# would copy content of this dir to specified ``site``.
#
# See Also
# ^^^^^^^^
#
# Qt Installer Framework Manual:
#
# Index page
# http://qt-project.org/doc/qtinstallerframework/index.html
#
# Component Scripting
# http://qt-project.org/doc/qtinstallerframework/scripting.html
#
# Predefined Variables
# http://qt-project.org/doc/qtinstallerframework/scripting.html#predefined-variables
#
# Download Qt Installer Framework for you platform from Qt Project site:
# http://download.qt-project.org/official_releases/qt-installer-framework/
#
#=============================================================================
# Copyright 2014 Kitware, Inc.
# Copyright 2014 Konstantin Podsvirov <konstantin@podsvirov.pro>
#
# 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.)
#=============================================================================
# Search Qt Installer Framework tools
#=============================================================================
# Default path
if(WIN32)
set(_CPACK_IFW_PATHS
"$ENV{HOMEDRIVE}/Qt"
"C:/Qt"
)
else()
set(_CPACK_IFW_PATHS
"$ENV{HOME}/Qt"
"/opt/Qt"
)
endif()
set(_CPACK_IFW_SUFFIXES
"QtIFW-1.7.0/bin"
"QtIFW-1.6.0/bin"
"QtIFW-1.5.0/bin"
"QtIFW-1.4.0/bin"
"QtIFW-1.3.0/bin"
)
# Look for 'binarycreator'
if(NOT CPACK_IFW_BINARYCREATOR_EXECUTABLE_FOUND)
find_program(CPACK_IFW_BINARYCREATOR_EXECUTABLE
NAMES binarycreator
PATHS ${_CPACK_IFW_PATHS}
PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES}
DOC "QtIFW binarycreator command line client"
)
mark_as_advanced(CPACK_IFW_BINARYCREATOR_EXECUTABLE)
if(EXISTS ${CPACK_IFW_BINARYCREATOR_EXECUTABLE})
set(CPACK_IFW_BINARYCREATOR_EXECUTABLE_FOUND 1)
endif()
endif() # NOT CPACK_IFW_BINARYCREATOR_EXECUTABLE_FOUND
# Look for 'repogen'
if(NOT CPACK_IFW_REPOGEN_EXECUTABLE_FOUND)
find_program(CPACK_IFW_REPOGEN_EXECUTABLE
NAMES repogen
PATHS ${_CPACK_IFW_PATHS}
PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES}
DOC "QtIFW repogen command line client"
)
mark_as_advanced(CPACK_IFW_REPOGEN_EXECUTABLE)
if(EXISTS ${CPACK_IFW_REPOGEN_EXECUTABLE})
set(CPACK_IFW_REPOGEN_EXECUTABLE_FOUND 1)
endif()
endif() # NOT CPACK_IFW_REPOGEN_EXECUTABLE_FOUND
#
## Next code is included only once
#
if(NOT CPackIFW_CMake_INCLUDED)
set(CPackIFW_CMake_INCLUDED 1)
#=============================================================================
# Macro definition
#=============================================================================
# Macro definition based on CPackComponent
if(NOT CPackComponent_CMake_INCLUDED)
include(CPackComponent)
endif()
if(NOT __CMAKE_PARSE_ARGUMENTS_INCLUDED)
include(CMakeParseArguments)
endif()
# Resolve full path to lisense file
macro(_cpack_ifw_resolve_lisenses _variable)
if(${_variable})
set(_ifw_license_file FALSE)
set(_ifw_licenses_fix)
foreach(_ifw_licenses_arg ${${_variable}})
if(_ifw_license_file)
get_filename_component(_ifw_licenses_arg "${_ifw_licenses_arg}" ABSOLUTE)
set(_ifw_license_file FALSE)
else()
set(_ifw_license_file TRUE)
endif()
list(APPEND _ifw_licenses_fix "${_ifw_licenses_arg}")
endforeach(_ifw_licenses_arg)
set(${_variable} "${_ifw_licenses_fix}")
endif()
endmacro()
# Macro for configure component
macro(cpack_ifw_configure_component compname)
string(TOUPPER ${compname} _CPACK_IFWCOMP_UNAME)
set(_IFW_OPT)
set(_IFW_ARGS VERSION SCRIPT NAME PRIORITY)
set(_IFW_MULTI_ARGS DEPENDS LICENSES)
cmake_parse_arguments(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})
# Resolve full filename for script file
set(_IFW_SCRIPT_MACRO CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_SCRIPT)
set(_IFW_SCRIPT_FILE ${${_IFW_SCRIPT_MACRO}})
if(DEFINED ${_IFW_SCRIPT_MACRO})
get_filename_component(${_IFW_SCRIPT_MACRO} ${_IFW_SCRIPT_FILE} ABSOLUTE)
set(_IFW_SCRIPT_FILE ${${_IFW_SCRIPT_MACRO}})
if(NOT EXISTS ${_IFW_SCRIPT_FILE})
message(WARNING "CPack IFW: script file \"${_IFW_SCRIPT_FILE}\" for component \"${compname}\" is not exists" )
set(${_IFW_SCRIPT_MACRO})
endif()
endif()
_cpack_ifw_resolve_lisenses(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_LICENSES)
set(_CPACK_IFWCOMP_STR "\n# Configuration for IFW component \"${compname}\"\n")
foreach(_IFW_ARG_NAME ${_IFW_ARGS})
cpack_append_string_variable_set_command(
CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_${_IFW_ARG_NAME}
_CPACK_IFWCOMP_STR)
endforeach()
foreach(_IFW_ARG_NAME ${_IFW_MULTI_ARGS})
cpack_append_variable_set_command(
CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_${_IFW_ARG_NAME}
_CPACK_IFWCOMP_STR)
endforeach()
if(CPack_CMake_INCLUDED)
file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWCOMP_STR}")
endif()
endmacro()
# Macro for configure group
macro(cpack_ifw_configure_component_group grpname)
string(TOUPPER ${grpname} _CPACK_IFWGRP_UNAME)
set(_IFW_OPT)
set(_IFW_ARGS VERSION NAME PRIORITY)
set(_IFW_MULTI_ARGS LICENSES)
cmake_parse_arguments(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})
_cpack_ifw_resolve_lisenses(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_LICENSES)
set(_CPACK_IFWGRP_STR "\n# Configuration for IFW component group \"${grpname}\"\n")
foreach(_IFW_ARG_NAME ${_IFW_ARGS})
cpack_append_string_variable_set_command(
CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_${_IFW_ARG_NAME}
_CPACK_IFWGRP_STR)
endforeach()
foreach(_IFW_ARG_NAME ${_IFW_MULTI_ARGS})
cpack_append_variable_set_command(
CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_${_IFW_ARG_NAME}
_CPACK_IFWGRP_STR)
endforeach()
if(CPack_CMake_INCLUDED)
file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWGRP_STR}")
endif()
endmacro()
endif() # NOT CPackIFW_CMake_INCLUDED
......@@ -577,6 +577,7 @@ set(CPACK_SRCS
CPack/cmCPackGenerator.cxx
CPack/cmCPackLog.cxx
CPack/cmCPackNSISGenerator.cxx
CPack/cmCPackIFWGenerator.cxx
CPack/cmCPackSTGZGenerator.cxx
CPack/cmCPackTGZGenerator.cxx
CPack/cmCPackTarBZip2Generator.cxx
......
......@@ -19,6 +19,7 @@
#include "cmCPackZIPGenerator.h"
#include "cmCPackSTGZGenerator.h"
#include "cmCPackNSISGenerator.h"
#include "cmCPackIFWGenerator.h"
#ifdef __APPLE__
# include "cmCPackDragNDropGenerator.h"
......@@ -68,6 +69,11 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
this->RegisterGenerator("NSIS64", "Null Soft Installer (64-bit)",
cmCPackNSISGenerator::CreateGenerator64);
}
if (cmCPackIFWGenerator::CanGenerate())
{
this->RegisterGenerator("IFW", "Qt Installer Framework",
cmCPackIFWGenerator::CreateGenerator);
}
#ifdef __CYGWIN__
if (cmCPackCygwinBinaryGenerator::CanGenerate())
{
......
This diff is collapsed.
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2000-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.
============================================================================*/
#ifndef cmCPackIFWGenerator_h
#define cmCPackIFWGenerator_h
#include "cmCPackGenerator.h"
#include <set>
/** \class cmCPackIFWGenerator
* \brief A generator for Qt Installer Framework tools
*
* http://qt-project.org/doc/qtinstallerframework/index.html
*/
class cmCPackIFWGenerator : public cmCPackGenerator
{
public:
cmCPackTypeMacro(cmCPackIFWGenerator, cmCPackGenerator);
/**
* Construct generator
*/
cmCPackIFWGenerator();
virtual ~cmCPackIFWGenerator();
protected:
virtual int InitializeInternal();
virtual int PackageFiles();
virtual const char* GetPackagingInstallPrefix();
virtual const char* GetOutputExtension();
std::string IfwGetGroupId(cmCPackComponentGroup *group);
std::string IfwGetComponentId(cmCPackComponent *component);
std::string IfwGetGroupName(cmCPackComponentGroup *group);
std::string IfwGetComponentName(cmCPackComponent *component);
std::string IfwGetComponentName(const std::string &componentName);
virtual std::string GetComponentInstallDirNamePrefix(
const std::string& componentName);
virtual std::string GetComponentInstallDirNameSuffix(
const std::string& componentName);
bool GetListOfSubdirectories(const char* dir,
std::vector<std::string>& dirs);
enum cmCPackGenerator::CPackSetDestdirSupport SupportsSetDestdir() const;
virtual bool SupportsAbsoluteDestination() const;
virtual bool SupportsComponentInstallation() const;
private:
int IfwCreateConfigFile();
int IfwCreatePackageFile();
std::string IfwCreateCurrentDate();
bool IfwParseLicenses(std::vector<std::string> &licenses,
const std::string &variable,
const std::string &metaDir);
std::string ifwRepoGen;
std::string ifwBinCreator;
std::string ifwDownloadSite;
bool ifwOnlineOnly;
bool ifwResolveDuplicateNames;
std::vector<std::string> ifwPkgsDirsVector;
};
#endif
<html>
<head>
<meta http-equiv="Refresh" content="0; url=http://cmake.org/" />
</head>
<body>
</body>
</html>
function Component()
{
// default constructor
}
Component.prototype.createOperations = function()
{
// call default implementation to actually install applications!
component.createOperations();
// Create shortcut
if (installer.value("os") === "win") {
@_CPACK_IFW_SHORTCUT_OPTIONAL@
component.addOperation("CreateShortcut",
installer.value("TargetDir") + "/cmake.org.html",
installer.value("StartMenuDir") + "/CMake Web Site.lnk");