Merge branch 'master' into generator-toolset
We need the latest Tests/CMakeLists.txt so we can refactor all tests.
This commit is contained in:
commit
c0debb1f89
|
@ -9,6 +9,8 @@
|
|||
# configure_file() command when creating the <Name>Config.cmake or <Name>-config.cmake
|
||||
# file for installing a project or library. It helps making the resulting package
|
||||
# relocatable by avoiding hardcoded paths in the installed Config.cmake file.
|
||||
# <Name>Config.cmake files installed under UNIX into /lib(64) or /usr/lib(64) are
|
||||
# considered system packages and are not relocatable.
|
||||
#
|
||||
# In a FooConfig.cmake file there may be code like this to make the
|
||||
# install destinations know to the using project:
|
||||
|
@ -173,17 +175,33 @@ function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
|
|||
else()
|
||||
set(absInstallDir "${CMAKE_INSTALL_PREFIX}/${CCF_INSTALL_DESTINATION}")
|
||||
endif()
|
||||
|
||||
# with the /usr-move, /lib(64) is a symlink to /usr/lib on Fedora, ArchLinux, Mageira and others.
|
||||
# If we are installed to such a location, force using absolute paths.
|
||||
set(forceAbsolutePaths FALSE)
|
||||
if("${absInstallDir}" MATCHES "^(/usr)?/lib(64)?/.+")
|
||||
set(forceAbsolutePaths TRUE)
|
||||
endif()
|
||||
|
||||
file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${absInstallDir}" "${CMAKE_INSTALL_PREFIX}" )
|
||||
|
||||
foreach(var ${CCF_PATH_VARS})
|
||||
if(NOT DEFINED ${var})
|
||||
message(FATAL_ERROR "Variable ${var} does not exist")
|
||||
else()
|
||||
if(IS_ABSOLUTE "${${var}}")
|
||||
string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${PACKAGE_PREFIX_DIR}"
|
||||
PACKAGE_${var} "${${var}}")
|
||||
if(forceAbsolutePaths)
|
||||
if(IS_ABSOLUTE "${${var}}")
|
||||
set(PACKAGE_${var} "${${var}}")
|
||||
else()
|
||||
set(PACKAGE_${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
|
||||
endif()
|
||||
else()
|
||||
set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}")
|
||||
if(IS_ABSOLUTE "${${var}}")
|
||||
string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${PACKAGE_PREFIX_DIR}"
|
||||
PACKAGE_${var} "${${var}}")
|
||||
else()
|
||||
set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
|
|
@ -0,0 +1,761 @@
|
|||
# - Manage data files stored outside source tree
|
||||
# Use this module to unambiguously reference data files stored outside the
|
||||
# source tree and fetch them at build time from arbitrary local and remote
|
||||
# content-addressed locations. Functions provided by this module recognize
|
||||
# arguments with the syntax "DATA{<name>}" as references to external data,
|
||||
# replace them with full paths to local copies of those data, and create build
|
||||
# rules to fetch and update the local copies.
|
||||
#
|
||||
# The DATA{} syntax is literal and the <name> is a full or relative path
|
||||
# within the source tree. The source tree must contain either a real data
|
||||
# file at <name> or a "content link" at <name><ext> containing a hash of the
|
||||
# real file using a hash algorithm corresponding to <ext>. For example, the
|
||||
# argument "DATA{img.png}" may be satisfied by either a real "img.png" file in
|
||||
# the current source directory or a "img.png.md5" file containing its MD5 sum.
|
||||
#
|
||||
# The 'ExternalData_Expand_Arguments' function evaluates DATA{} references
|
||||
# in its arguments and constructs a new list of arguments:
|
||||
# ExternalData_Expand_Arguments(
|
||||
# <target> # Name of data management target
|
||||
# <outVar> # Output variable
|
||||
# [args...] # Input arguments, DATA{} allowed
|
||||
# )
|
||||
# It replaces each DATA{} reference in an argument with the full path of a
|
||||
# real data file on disk that will exist after the <target> builds.
|
||||
#
|
||||
# The 'ExternalData_Add_Test' function wraps around the CMake add_test()
|
||||
# command but supports DATA{} references in its arguments:
|
||||
# ExternalData_Add_Test(
|
||||
# <target> # Name of data management target
|
||||
# ... # Arguments of add_test(), DATA{} allowed
|
||||
# )
|
||||
# It passes its arguments through ExternalData_Expand_Arguments and then
|
||||
# invokes add_test() using the results.
|
||||
#
|
||||
# The 'ExternalData_Add_Target' function creates a custom target to manage
|
||||
# local instances of data files stored externally:
|
||||
# ExternalData_Add_Target(
|
||||
# <target> # Name of data management target
|
||||
# )
|
||||
# It creates custom commands in the target as necessary to make data files
|
||||
# available for each DATA{} reference previously evaluated by other functions
|
||||
# provided by this module. A list of URL templates must be provided in the
|
||||
# variable ExternalData_URL_TEMPLATES using the placeholders "%(algo)" and
|
||||
# "%(hash)" in each template. Data fetch rules try each URL template in order
|
||||
# by substituting the hash algorithm name for "%(algo)" and the hash value for
|
||||
# "%(hash)".
|
||||
#
|
||||
# The following hash algorithms are supported:
|
||||
# %(algo) <ext> Description
|
||||
# ------- ----- -----------
|
||||
# MD5 .md5 Message-Digest Algorithm 5, RFC 1321
|
||||
# SHA1 .sha1 US Secure Hash Algorithm 1, RFC 3174
|
||||
# SHA224 .sha224 US Secure Hash Algorithms, RFC 4634
|
||||
# SHA256 .sha256 US Secure Hash Algorithms, RFC 4634
|
||||
# SHA384 .sha384 US Secure Hash Algorithms, RFC 4634
|
||||
# SHA512 .sha512 US Secure Hash Algorithms, RFC 4634
|
||||
# Note that the hashes are used only for unique data identification and
|
||||
# download verification. This is not security software.
|
||||
#
|
||||
# Example usage:
|
||||
# include(ExternalData)
|
||||
# set(ExternalData_URL_TEMPLATES "file:///local/%(algo)/%(hash)"
|
||||
# "http://data.org/%(algo)/%(hash)")
|
||||
# ExternalData_Add_Test(MyData
|
||||
# NAME MyTest
|
||||
# COMMAND MyExe DATA{MyInput.png}
|
||||
# )
|
||||
# ExternalData_Add_Target(MyData)
|
||||
# When test "MyTest" runs the "DATA{MyInput.png}" argument will be replaced by
|
||||
# the full path to a real instance of the data file "MyInput.png" on disk. If
|
||||
# the source tree contains a content link such as "MyInput.png.md5" then the
|
||||
# "MyData" target creates a real "MyInput.png" in the build tree.
|
||||
#
|
||||
# The DATA{} syntax can be told to fetch a file series using the form
|
||||
# "DATA{<name>,:}", where the ":" is literal. If the source tree contains a
|
||||
# group of files or content links named like a series then a reference to one
|
||||
# member adds rules to fetch all of them. Although all members of a series
|
||||
# are fetched, only the file originally named by the DATA{} argument is
|
||||
# substituted for it. The default configuration recognizes file series names
|
||||
# ending with "#.ext", "_#.ext", ".#.ext", or "-#.ext" where "#" is a sequence
|
||||
# of decimal digits and ".ext" is any single extension. Configure it with a
|
||||
# regex that parses <number> and <suffix> parts from the end of <name>:
|
||||
# ExternalData_SERIES_PARSE = regex of the form (<number>)(<suffix>)$
|
||||
# For more complicated cases set:
|
||||
# ExternalData_SERIES_PARSE = regex with at least two () groups
|
||||
# ExternalData_SERIES_PARSE_PREFIX = <prefix> regex group number, if any
|
||||
# ExternalData_SERIES_PARSE_NUMBER = <number> regex group number
|
||||
# ExternalData_SERIES_PARSE_SUFFIX = <suffix> regex group number
|
||||
# Configure series number matching with a regex that matches the
|
||||
# <number> part of series members named <prefix><number><suffix>:
|
||||
# ExternalData_SERIES_MATCH = regex matching <number> in all series members
|
||||
# Note that the <suffix> of a series does not include a hash-algorithm
|
||||
# extension.
|
||||
#
|
||||
# The DATA{} syntax can alternatively match files associated with the named
|
||||
# file and contained in the same directory. Associated files may be specified
|
||||
# by options using the syntax DATA{<name>,<opt1>,<opt2>,...}. Each option may
|
||||
# specify one file by name or specify a regular expression to match file names
|
||||
# using the syntax REGEX:<regex>. For example, the arguments
|
||||
# DATA{MyData/MyInput.mhd,MyInput.img} # File pair
|
||||
# DATA{MyData/MyFrames00.png,REGEX:MyFrames[0-9]+\\.png} # Series
|
||||
# will pass MyInput.mha and MyFrames00.png on the command line but ensure
|
||||
# that the associated files are present next to them.
|
||||
#
|
||||
# The DATA{} syntax may reference a directory using a trailing slash and a
|
||||
# list of associated files. The form DATA{<name>/,<opt1>,<opt2>,...} adds
|
||||
# rules to fetch any files in the directory that match one of the associated
|
||||
# file options. For example, the argument DATA{MyDataDir/,REGEX:.*} will pass
|
||||
# the full path to a MyDataDir directory on the command line and ensure that
|
||||
# the directory contains files corresponding to every file or content link in
|
||||
# the MyDataDir source directory.
|
||||
#
|
||||
# The variable ExternalData_LINK_CONTENT may be set to the name of a supported
|
||||
# hash algorithm to enable automatic conversion of real data files referenced
|
||||
# by the DATA{} syntax into content links. For each such <file> a content
|
||||
# link named "<file><ext>" is created. The original file is renamed to the
|
||||
# form ".ExternalData_<algo>_<hash>" to stage it for future transmission to
|
||||
# one of the locations in the list of URL templates (by means outside the
|
||||
# scope of this module). The data fetch rule created for the content link
|
||||
# will use the staged object if it cannot be found using any URL template.
|
||||
#
|
||||
# The variable ExternalData_OBJECT_STORES may be set to a list of local
|
||||
# directories that store objects using the layout <dir>/%(algo)/%(hash).
|
||||
# These directories will be searched first for a needed object. If the object
|
||||
# is not available in any store then it will be fetched remotely using the URL
|
||||
# templates and added to the first local store listed. If no stores are
|
||||
# specified the default is a location inside the build tree.
|
||||
#
|
||||
# The variable ExternalData_SOURCE_ROOT may be set to the highest source
|
||||
# directory containing any path named by a DATA{} reference. The default is
|
||||
# CMAKE_SOURCE_DIR. ExternalData_SOURCE_ROOT and CMAKE_SOURCE_DIR must refer
|
||||
# to directories within a single source distribution (e.g. they come together
|
||||
# in one tarball).
|
||||
#
|
||||
# The variable ExternalData_BINARY_ROOT may be set to the directory to hold
|
||||
# the real data files named by expanded DATA{} references. The default is
|
||||
# CMAKE_BINARY_DIR. The directory layout will mirror that of content links
|
||||
# under ExternalData_SOURCE_ROOT.
|
||||
#
|
||||
# Variables ExternalData_TIMEOUT_INACTIVITY and ExternalData_TIMEOUT_ABSOLUTE
|
||||
# set the download inactivity and absolute timeouts, in seconds. The defaults
|
||||
# are 60 seconds and 300 seconds, respectively. Set either timeout to 0
|
||||
# seconds to disable enforcement.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2010-2013 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(ExternalData_add_test target)
|
||||
ExternalData_expand_arguments("${target}" testArgs ${ARGN})
|
||||
add_test(${testArgs})
|
||||
endfunction()
|
||||
|
||||
function(ExternalData_add_target target)
|
||||
if(NOT ExternalData_URL_TEMPLATES)
|
||||
message(FATAL_ERROR "ExternalData_URL_TEMPLATES is not set!")
|
||||
endif()
|
||||
if(NOT ExternalData_OBJECT_STORES)
|
||||
set(ExternalData_OBJECT_STORES ${CMAKE_BINARY_DIR}/ExternalData/Objects)
|
||||
endif()
|
||||
set(config ${CMAKE_CURRENT_BINARY_DIR}/${target}_config.cmake)
|
||||
configure_file(${_ExternalData_SELF_DIR}/ExternalData_config.cmake.in ${config} @ONLY)
|
||||
|
||||
set(files "")
|
||||
|
||||
# Set "_ExternalData_FILE_${file}" for each output file to avoid duplicate
|
||||
# rules. Use local data first to prefer real files over content links.
|
||||
|
||||
# Custom commands to copy or link local data.
|
||||
get_property(data_local GLOBAL PROPERTY _ExternalData_${target}_LOCAL)
|
||||
foreach(entry IN LISTS data_local)
|
||||
string(REPLACE "|" ";" tuple "${entry}")
|
||||
list(GET tuple 0 file)
|
||||
list(GET tuple 1 name)
|
||||
if(NOT DEFINED "_ExternalData_FILE_${file}")
|
||||
set("_ExternalData_FILE_${file}" 1)
|
||||
add_custom_command(
|
||||
COMMENT "Generating ${file}"
|
||||
OUTPUT "${file}"
|
||||
COMMAND ${CMAKE_COMMAND} -Drelative_top=${CMAKE_BINARY_DIR}
|
||||
-Dfile=${file} -Dname=${name}
|
||||
-DExternalData_ACTION=local
|
||||
-DExternalData_CONFIG=${config}
|
||||
-P ${_ExternalData_SELF}
|
||||
MAIN_DEPENDENCY "${name}"
|
||||
)
|
||||
list(APPEND files "${file}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Custom commands to fetch remote data.
|
||||
get_property(data_fetch GLOBAL PROPERTY _ExternalData_${target}_FETCH)
|
||||
foreach(entry IN LISTS data_fetch)
|
||||
string(REPLACE "|" ";" tuple "${entry}")
|
||||
list(GET tuple 0 file)
|
||||
list(GET tuple 1 name)
|
||||
list(GET tuple 2 ext)
|
||||
set(stamp "${ext}-stamp")
|
||||
if(NOT DEFINED "_ExternalData_FILE_${file}")
|
||||
set("_ExternalData_FILE_${file}" 1)
|
||||
add_custom_command(
|
||||
# Users care about the data file, so hide the hash/timestamp file.
|
||||
COMMENT "Generating ${file}"
|
||||
# The hash/timestamp file is the output from the build perspective.
|
||||
# List the real file as a second output in case it is a broken link.
|
||||
# The files must be listed in this order so CMake can hide from the
|
||||
# make tool that a symlink target may not be newer than the input.
|
||||
OUTPUT "${file}${stamp}" "${file}"
|
||||
# Run the data fetch/update script.
|
||||
COMMAND ${CMAKE_COMMAND} -Drelative_top=${CMAKE_BINARY_DIR}
|
||||
-Dfile=${file} -Dname=${name} -Dext=${ext}
|
||||
-DExternalData_ACTION=fetch
|
||||
-DExternalData_CONFIG=${config}
|
||||
-P ${_ExternalData_SELF}
|
||||
# Update whenever the object hash changes.
|
||||
MAIN_DEPENDENCY "${name}${ext}"
|
||||
)
|
||||
list(APPEND files "${file}${stamp}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Custom target to drive all update commands.
|
||||
add_custom_target(${target} ALL DEPENDS ${files})
|
||||
endfunction()
|
||||
|
||||
function(ExternalData_expand_arguments target outArgsVar)
|
||||
# Replace DATA{} references with real arguments.
|
||||
set(data_regex "DATA{([^{}\r\n]*)}")
|
||||
set(other_regex "([^D]|D[^A]|DA[^T]|DAT[^A]|DATA[^{])+|.")
|
||||
set(outArgs "")
|
||||
foreach(arg IN LISTS ARGN)
|
||||
if("x${arg}" MATCHES "${data_regex}")
|
||||
# Split argument into DATA{}-pieces and other pieces.
|
||||
string(REGEX MATCHALL "${data_regex}|${other_regex}" pieces "${arg}")
|
||||
# Compose output argument with DATA{}-pieces replaced.
|
||||
set(outArg "")
|
||||
foreach(piece IN LISTS pieces)
|
||||
if("x${piece}" MATCHES "^x${data_regex}$")
|
||||
# Replace this DATA{}-piece with a file path.
|
||||
string(REGEX REPLACE "${data_regex}" "\\1" data "${piece}")
|
||||
_ExternalData_arg("${target}" "${piece}" "${data}" file)
|
||||
set(outArg "${outArg}${file}")
|
||||
else()
|
||||
# No replacement needed for this piece.
|
||||
set(outArg "${outArg}${piece}")
|
||||
endif()
|
||||
endforeach()
|
||||
list(APPEND outArgs "${outArg}")
|
||||
else()
|
||||
# No replacements needed in this argument.
|
||||
list(APPEND outArgs "${arg}")
|
||||
endif()
|
||||
endforeach()
|
||||
set("${outArgsVar}" "${outArgs}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Private helper interface
|
||||
|
||||
set(_ExternalData_REGEX_ALGO "MD5|SHA1|SHA224|SHA256|SHA384|SHA512")
|
||||
set(_ExternalData_REGEX_EXT "md5|sha1|sha224|sha256|sha384|sha512")
|
||||
set(_ExternalData_SELF "${CMAKE_CURRENT_LIST_FILE}")
|
||||
get_filename_component(_ExternalData_SELF_DIR "${_ExternalData_SELF}" PATH)
|
||||
|
||||
function(_ExternalData_compute_hash var_hash algo file)
|
||||
if("${algo}" MATCHES "^${_ExternalData_REGEX_ALGO}$")
|
||||
file("${algo}" "${file}" hash)
|
||||
set("${var_hash}" "${hash}" PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "Hash algorithm ${algo} unimplemented.")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(_ExternalData_random var)
|
||||
string(RANDOM LENGTH 6 random)
|
||||
set("${var}" "${random}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_ExternalData_exact_regex regex_var string)
|
||||
string(REGEX REPLACE "([][+.*()^])" "\\\\\\1" regex "${string}")
|
||||
set("${regex_var}" "${regex}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_ExternalData_atomic_write file content)
|
||||
_ExternalData_random(random)
|
||||
set(tmp "${file}.tmp${random}")
|
||||
file(WRITE "${tmp}" "${content}")
|
||||
file(RENAME "${tmp}" "${file}")
|
||||
endfunction()
|
||||
|
||||
function(_ExternalData_link_content name var_ext)
|
||||
if("${ExternalData_LINK_CONTENT}" MATCHES "^(${_ExternalData_REGEX_ALGO})$")
|
||||
set(algo "${ExternalData_LINK_CONTENT}")
|
||||
else()
|
||||
message(FATAL_ERROR
|
||||
"Unknown hash algorithm specified by ExternalData_LINK_CONTENT:\n"
|
||||
" ${ExternalData_LINK_CONTENT}")
|
||||
endif()
|
||||
_ExternalData_compute_hash(hash "${algo}" "${name}")
|
||||
get_filename_component(dir "${name}" PATH)
|
||||
set(staged "${dir}/.ExternalData_${algo}_${hash}")
|
||||
string(TOLOWER ".${algo}" ext)
|
||||
_ExternalData_atomic_write("${name}${ext}" "${hash}\n")
|
||||
file(RENAME "${name}" "${staged}")
|
||||
set("${var_ext}" "${ext}" PARENT_SCOPE)
|
||||
|
||||
file(RELATIVE_PATH relname "${ExternalData_SOURCE_ROOT}" "${name}${ext}")
|
||||
message(STATUS "Linked ${relname} to ExternalData ${algo}/${hash}")
|
||||
endfunction()
|
||||
|
||||
function(_ExternalData_arg target arg options var_file)
|
||||
# Separate data path from the options.
|
||||
string(REPLACE "," ";" options "${options}")
|
||||
list(GET options 0 data)
|
||||
list(REMOVE_AT options 0)
|
||||
|
||||
# Interpret trailing slashes as directories.
|
||||
set(data_is_directory 0)
|
||||
if("x${data}" MATCHES "^x(.*)([/\\])$")
|
||||
set(data_is_directory 1)
|
||||
set(data "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
|
||||
# Convert to full path.
|
||||
if(IS_ABSOLUTE "${data}")
|
||||
set(absdata "${data}")
|
||||
else()
|
||||
set(absdata "${CMAKE_CURRENT_SOURCE_DIR}/${data}")
|
||||
endif()
|
||||
get_filename_component(absdata "${absdata}" ABSOLUTE)
|
||||
|
||||
# Convert to relative path under the source tree.
|
||||
if(NOT ExternalData_SOURCE_ROOT)
|
||||
set(ExternalData_SOURCE_ROOT "${CMAKE_SOURCE_DIR}")
|
||||
endif()
|
||||
set(top_src "${ExternalData_SOURCE_ROOT}")
|
||||
file(RELATIVE_PATH reldata "${top_src}" "${absdata}")
|
||||
if(IS_ABSOLUTE "${reldata}" OR "${reldata}" MATCHES "^\\.\\./")
|
||||
message(FATAL_ERROR "Data file referenced by argument\n"
|
||||
" ${arg}\n"
|
||||
"does not lie under the top-level source directory\n"
|
||||
" ${top_src}\n")
|
||||
endif()
|
||||
if(data_is_directory AND NOT IS_DIRECTORY "${top_src}/${reldata}")
|
||||
message(FATAL_ERROR "Data directory referenced by argument\n"
|
||||
" ${arg}\n"
|
||||
"corresponds to source tree path\n"
|
||||
" ${reldata}\n"
|
||||
"that does not exist as a directory!")
|
||||
endif()
|
||||
if(NOT ExternalData_BINARY_ROOT)
|
||||
set(ExternalData_BINARY_ROOT "${CMAKE_BINARY_DIR}")
|
||||
endif()
|
||||
set(top_bin "${ExternalData_BINARY_ROOT}")
|
||||
|
||||
# Handle in-source builds gracefully.
|
||||
if("${top_src}" STREQUAL "${top_bin}")
|
||||
if(ExternalData_LINK_CONTENT)
|
||||
message(WARNING "ExternalData_LINK_CONTENT cannot be used in-source")
|
||||
set(ExternalData_LINK_CONTENT 0)
|
||||
endif()
|
||||
set(top_same 1)
|
||||
endif()
|
||||
|
||||
set(external "") # Entries external to the source tree.
|
||||
set(internal "") # Entries internal to the source tree.
|
||||
set(have_original ${data_is_directory})
|
||||
|
||||
# Process options.
|
||||
set(series_option "")
|
||||
set(associated_files "")
|
||||
set(associated_regex "")
|
||||
foreach(opt ${options})
|
||||
if("x${opt}" MATCHES "^xREGEX:[^:/]+$")
|
||||
# Regular expression to match associated files.
|
||||
string(REGEX REPLACE "^REGEX:" "" regex "${opt}")
|
||||
list(APPEND associated_regex "${regex}")
|
||||
elseif("x${opt}" MATCHES "^x:$")
|
||||
# Activate series matching.
|
||||
set(series_option "${opt}")
|
||||
elseif("x${opt}" MATCHES "^[^][:/*?]+$")
|
||||
# Specific associated file.
|
||||
list(APPEND associated_files "${opt}")
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown option \"${opt}\" in argument\n"
|
||||
" ${arg}\n")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(series_option)
|
||||
if(data_is_directory)
|
||||
message(FATAL_ERROR "Series option \"${series_option}\" not allowed with directories.")
|
||||
endif()
|
||||
if(associated_files OR associated_regex)
|
||||
message(FATAL_ERROR "Series option \"${series_option}\" not allowed with associated files.")
|
||||
endif()
|
||||
# Load a whole file series.
|
||||
_ExternalData_arg_series()
|
||||
elseif(data_is_directory)
|
||||
if(associated_files OR associated_regex)
|
||||
# Load listed/matching associated files in the directory.
|
||||
_ExternalData_arg_associated()
|
||||
else()
|
||||
message(FATAL_ERROR "Data directory referenced by argument\n"
|
||||
" ${arg}\n"
|
||||
"must list associated files.")
|
||||
endif()
|
||||
else()
|
||||
# Load the named data file.
|
||||
_ExternalData_arg_single()
|
||||
if(associated_files OR associated_regex)
|
||||
# Load listed/matching associated files.
|
||||
_ExternalData_arg_associated()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT have_original)
|
||||
message(FATAL_ERROR "Data file referenced by argument\n"
|
||||
" ${arg}\n"
|
||||
"corresponds to source tree path\n"
|
||||
" ${reldata}\n"
|
||||
"that does not exist as a file (with or without an extension)!")
|
||||
endif()
|
||||
|
||||
if(external)
|
||||
# Make the series available in the build tree.
|
||||
set_property(GLOBAL APPEND PROPERTY
|
||||
_ExternalData_${target}_FETCH "${external}")
|
||||
set_property(GLOBAL APPEND PROPERTY
|
||||
_ExternalData_${target}_LOCAL "${internal}")
|
||||
set("${var_file}" "${top_bin}/${reldata}" PARENT_SCOPE)
|
||||
else()
|
||||
# The whole series is in the source tree.
|
||||
set("${var_file}" "${top_src}/${reldata}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
macro(_ExternalData_arg_associated)
|
||||
# Associated files lie in the same directory.
|
||||
if(data_is_directory)
|
||||
set(reldir "${reldata}")
|
||||
else()
|
||||
get_filename_component(reldir "${reldata}" PATH)
|
||||
endif()
|
||||
if(reldir)
|
||||
set(reldir "${reldir}/")
|
||||
endif()
|
||||
_ExternalData_exact_regex(reldir_regex "${reldir}")
|
||||
|
||||
# Find files named explicitly.
|
||||
foreach(file ${associated_files})
|
||||
_ExternalData_exact_regex(file_regex "${file}")
|
||||
_ExternalData_arg_find_files("${reldir}${file}" "${reldir_regex}${file_regex}")
|
||||
endforeach()
|
||||
|
||||
# Find files matching the given regular expressions.
|
||||
set(all "")
|
||||
set(sep "")
|
||||
foreach(regex ${associated_regex})
|
||||
set(all "${all}${sep}${reldir_regex}${regex}")
|
||||
set(sep "|")
|
||||
endforeach()
|
||||
_ExternalData_arg_find_files("${reldir}" "${all}")
|
||||
endmacro()
|
||||
|
||||
macro(_ExternalData_arg_single)
|
||||
# Match only the named data by itself.
|
||||
_ExternalData_exact_regex(data_regex "${reldata}")
|
||||
_ExternalData_arg_find_files("${reldata}" "${data_regex}")
|
||||
endmacro()
|
||||
|
||||
macro(_ExternalData_arg_series)
|
||||
# Configure series parsing and matching.
|
||||
set(series_parse_prefix "")
|
||||
set(series_parse_number "\\1")
|
||||
set(series_parse_suffix "\\2")
|
||||
if(ExternalData_SERIES_PARSE)
|
||||
if(ExternalData_SERIES_PARSE_NUMBER AND ExternalData_SERIES_PARSE_SUFFIX)
|
||||
if(ExternalData_SERIES_PARSE_PREFIX)
|
||||
set(series_parse_prefix "\\${ExternalData_SERIES_PARSE_PREFIX}")
|
||||
endif()
|
||||
set(series_parse_number "\\${ExternalData_SERIES_PARSE_NUMBER}")
|
||||
set(series_parse_suffix "\\${ExternalData_SERIES_PARSE_SUFFIX}")
|
||||
elseif(NOT "x${ExternalData_SERIES_PARSE}" MATCHES "^x\\([^()]*\\)\\([^()]*\\)\\$$")
|
||||
message(FATAL_ERROR
|
||||
"ExternalData_SERIES_PARSE is set to\n"
|
||||
" ${ExternalData_SERIES_PARSE}\n"
|
||||
"which is not of the form\n"
|
||||
" (<number>)(<suffix>)$\n"
|
||||
"Fix the regular expression or set variables\n"
|
||||
" ExternalData_SERIES_PARSE_PREFIX = <prefix> regex group number, if any\n"
|
||||
" ExternalData_SERIES_PARSE_NUMBER = <number> regex group number\n"
|
||||
" ExternalData_SERIES_PARSE_SUFFIX = <suffix> regex group number\n"
|
||||
)
|
||||
endif()
|
||||
set(series_parse "${ExternalData_SERIES_PARSE}")
|
||||
else()
|
||||
set(series_parse "([0-9]*)(\\.[^./]*)$")
|
||||
endif()
|
||||
if(ExternalData_SERIES_MATCH)
|
||||
set(series_match "${ExternalData_SERIES_MATCH}")
|
||||
else()
|
||||
set(series_match "[_.-]?[0-9]*")
|
||||
endif()
|
||||
|
||||
# Parse the base, number, and extension components of the series.
|
||||
string(REGEX REPLACE "${series_parse}" "${series_parse_prefix};${series_parse_number};${series_parse_suffix}" tuple "${reldata}")
|
||||
list(LENGTH tuple len)
|
||||
if(NOT "${len}" EQUAL 3)
|
||||
message(FATAL_ERROR "Data file referenced by argument\n"
|
||||
" ${arg}\n"
|
||||
"corresponds to path\n"
|
||||
" ${reldata}\n"
|
||||
"that does not match regular expression\n"
|
||||
" ${series_parse}")
|
||||
endif()
|
||||
list(GET tuple 0 relbase)
|
||||
list(GET tuple 2 ext)
|
||||
|
||||
# Glob files that might match the series.
|
||||
# Then match base, number, and extension.
|
||||
_ExternalData_exact_regex(series_base "${relbase}")
|
||||
_ExternalData_exact_regex(series_ext "${ext}")
|
||||
_ExternalData_arg_find_files("${relbase}*${ext}"
|
||||
"${series_base}${series_match}${series_ext}")
|
||||
endmacro()
|
||||
|
||||
function(_ExternalData_arg_find_files pattern regex)
|
||||
file(GLOB globbed RELATIVE "${top_src}" "${top_src}/${pattern}*")
|
||||
foreach(entry IN LISTS globbed)
|
||||
if("x${entry}" MATCHES "^x(.*)(\\.(${_ExternalData_REGEX_EXT}))$")
|
||||
set(relname "${CMAKE_MATCH_1}")
|
||||
set(alg "${CMAKE_MATCH_2}")
|
||||
else()
|
||||
set(relname "${entry}")
|
||||
set(alg "")
|
||||
endif()
|
||||
if("x${relname}" MATCHES "^x${regex}$" AND NOT IS_DIRECTORY "${top_src}/${entry}")
|
||||
set(name "${top_src}/${relname}")
|
||||
set(file "${top_bin}/${relname}")
|
||||
if(alg)
|
||||
list(APPEND external "${file}|${name}|${alg}")
|
||||
elseif(ExternalData_LINK_CONTENT)
|
||||
_ExternalData_link_content("${name}" alg)
|
||||
list(APPEND external "${file}|${name}|${alg}")
|
||||
elseif(NOT top_same)
|
||||
list(APPEND internal "${file}|${name}")
|
||||
endif()
|
||||
if("${relname}" STREQUAL "${reldata}")
|
||||
set(have_original 1)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
set(external "${external}" PARENT_SCOPE)
|
||||
set(internal "${internal}" PARENT_SCOPE)
|
||||
set(have_original "${have_original}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Private script mode interface
|
||||
|
||||
if(CMAKE_GENERATOR OR NOT ExternalData_ACTION)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(ExternalData_CONFIG)
|
||||
include(${ExternalData_CONFIG})
|
||||
endif()
|
||||
if(NOT ExternalData_URL_TEMPLATES)
|
||||
message(FATAL_ERROR "No ExternalData_URL_TEMPLATES set!")
|
||||
endif()
|
||||
|
||||
function(_ExternalData_link_or_copy src dst)
|
||||
# Create a temporary file first.
|
||||
get_filename_component(dst_dir "${dst}" PATH)
|
||||
file(MAKE_DIRECTORY "${dst_dir}")
|
||||
_ExternalData_random(random)
|
||||
set(tmp "${dst}.tmp${random}")
|
||||
if(UNIX)
|
||||
# Create a symbolic link.
|
||||
set(tgt "${src}")
|
||||
if(relative_top)
|
||||
# Use relative path if files are close enough.
|
||||
file(RELATIVE_PATH relsrc "${relative_top}" "${src}")
|
||||
file(RELATIVE_PATH relfile "${relative_top}" "${dst}")
|
||||
if(NOT IS_ABSOLUTE "${relsrc}" AND NOT "${relsrc}" MATCHES "^\\.\\./" AND
|
||||
NOT IS_ABSOLUTE "${reldst}" AND NOT "${reldst}" MATCHES "^\\.\\./")
|
||||
file(RELATIVE_PATH tgt "${dst_dir}" "${src}")
|
||||
endif()
|
||||
endif()
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink "${tgt}" "${tmp}" RESULT_VARIABLE result)
|
||||
else()
|
||||
# Create a copy.
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -E copy "${src}" "${tmp}" RESULT_VARIABLE result)
|
||||
endif()
|
||||
if(result)
|
||||
file(REMOVE "${tmp}")
|
||||
message(FATAL_ERROR "Failed to create\n ${tmp}\nfrom\n ${obj}")
|
||||
endif()
|
||||
|
||||
# Atomically create/replace the real destination.
|
||||
file(RENAME "${tmp}" "${dst}")
|
||||
endfunction()
|
||||
|
||||
function(_ExternalData_download_file url file err_var msg_var)
|
||||
set(retry 3)
|
||||
while(retry)
|
||||
math(EXPR retry "${retry} - 1")
|
||||
if(ExternalData_TIMEOUT_INACTIVITY)
|
||||
set(inactivity_timeout INACTIVITY_TIMEOUT ${ExternalData_TIMEOUT_INACTIVITY})
|
||||
elseif(NOT "${ExternalData_TIMEOUT_INACTIVITY}" EQUAL 0)
|
||||
set(inactivity_timeout INACTIVITY_TIMEOUT 60)
|
||||
else()
|
||||
set(inactivity_timeout "")
|
||||
endif()
|
||||
if(ExternalData_TIMEOUT_ABSOLUTE)
|
||||
set(absolute_timeout TIMEOUT ${ExternalData_TIMEOUT_ABSOLUTE})
|
||||
elseif(NOT "${ExternalData_TIMEOUT_ABSOLUTE}" EQUAL 0)
|
||||
set(absolute_timeout TIMEOUT 300)
|
||||
else()
|
||||
set(absolute_timeout "")
|
||||
endif()
|
||||
file(DOWNLOAD "${url}" "${file}" STATUS status LOG log ${inactivity_timeout} ${absolute_timeout} SHOW_PROGRESS)
|
||||
list(GET status 0 err)
|
||||
list(GET status 1 msg)
|
||||
if(err)
|
||||
if("${msg}" MATCHES "HTTP response code said error" AND
|
||||
"${log}" MATCHES "error: 503")
|
||||
set(msg "temporarily unavailable")
|
||||
endif()
|
||||
elseif("${log}" MATCHES "\nHTTP[^\n]* 503")
|
||||
set(err TRUE)
|
||||
set(msg "temporarily unavailable")
|
||||
endif()
|
||||
if(NOT err OR NOT "${msg}" MATCHES "partial|timeout|temporarily")
|
||||
break()
|
||||
elseif(retry)
|
||||
message(STATUS "[download terminated: ${msg}, retries left: ${retry}]")
|
||||
endif()
|
||||
endwhile()
|
||||
set("${err_var}" "${err}" PARENT_SCOPE)
|
||||
set("${msg_var}" "${msg}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_ExternalData_download_object name hash algo var_obj)
|
||||
# Search all object stores for an existing object.
|
||||
foreach(dir ${ExternalData_OBJECT_STORES})
|
||||
set(obj "${dir}/${algo}/${hash}")
|
||||
if(EXISTS "${obj}")
|
||||
message(STATUS "Found object: \"${obj}\"")
|
||||
set("${var_obj}" "${obj}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Download object to the first store.
|
||||
list(GET ExternalData_OBJECT_STORES 0 store)
|
||||
set(obj "${store}/${algo}/${hash}")
|
||||
|
||||
_ExternalData_random(random)
|
||||
set(tmp "${obj}.tmp${random}")
|
||||
set(found 0)
|
||||
set(tried "")
|
||||
foreach(url_template IN LISTS ExternalData_URL_TEMPLATES)
|
||||
string(REPLACE "%(hash)" "${hash}" url_tmp "${url_template}")
|
||||
string(REPLACE "%(algo)" "${algo}" url "${url_tmp}")
|
||||
message(STATUS "Fetching \"${url}\"")
|
||||
_ExternalData_download_file("${url}" "${tmp}" err errMsg)
|
||||
set(tried "${tried}\n ${url}")
|
||||
if(err)
|
||||
set(tried "${tried} (${errMsg})")
|
||||
else()
|
||||
# Verify downloaded object.
|
||||
_ExternalData_compute_hash(dl_hash "${algo}" "${tmp}")
|
||||
if("${dl_hash}" STREQUAL "${hash}")
|
||||
set(found 1)
|
||||
break()
|
||||
else()
|
||||
set(tried "${tried} (wrong hash ${algo}=${dl_hash})")
|
||||
if("$ENV{ExternalData_DEBUG_DOWNLOAD}" MATCHES ".")
|
||||
file(RENAME "${tmp}" "${store}/${algo}/${dl_hash}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
file(REMOVE "${tmp}")
|
||||
endforeach()
|
||||
|
||||
get_filename_component(dir "${name}" PATH)
|
||||
set(staged "${dir}/.ExternalData_${algo}_${hash}")
|
||||
|
||||
if(found)
|
||||
file(RENAME "${tmp}" "${obj}")
|
||||
message(STATUS "Downloaded object: \"${obj}\"")
|
||||
elseif(EXISTS "${staged}")
|
||||
set(obj "${staged}")
|
||||
message(STATUS "Staged object: \"${obj}\"")
|
||||
else()
|
||||
message(FATAL_ERROR "Object ${algo}=${hash} not found at:${tried}")
|
||||
endif()
|
||||
|
||||
set("${var_obj}" "${obj}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if("${ExternalData_ACTION}" STREQUAL "fetch")
|
||||
foreach(v ExternalData_OBJECT_STORES file name ext)
|
||||
if(NOT DEFINED "${v}")
|
||||
message(FATAL_ERROR "No \"-D${v}=\" value provided!")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
file(READ "${name}${ext}" hash)
|
||||
string(STRIP "${hash}" hash)
|
||||
|
||||
if("${ext}" MATCHES "^\\.(${_ExternalData_REGEX_EXT})$")
|
||||
string(TOUPPER "${CMAKE_MATCH_1}" algo)
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown hash algorithm extension \"${ext}\"")
|
||||
endif()
|
||||
|
||||
_ExternalData_download_object("${name}" "${hash}" "${algo}" obj)
|
||||
|
||||
# Check if file already corresponds to the object.
|
||||
set(stamp "${ext}-stamp")
|
||||
set(file_up_to_date 0)
|
||||
if(EXISTS "${file}" AND EXISTS "${file}${stamp}")
|
||||
file(READ "${file}${stamp}" f_hash)
|
||||
string(STRIP "${f_hash}" f_hash)
|
||||
if("${f_hash}" STREQUAL "${hash}")
|
||||
#message(STATUS "File already corresponds to object")
|
||||
set(file_up_to_date 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(file_up_to_date)
|
||||
# Touch the file to convince the build system it is up to date.
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${file}")
|
||||
else()
|
||||
_ExternalData_link_or_copy("${obj}" "${file}")
|
||||
endif()
|
||||
|
||||
# Atomically update the hash/timestamp file to record the object referenced.
|
||||
_ExternalData_atomic_write("${file}${stamp}" "${hash}\n")
|
||||
elseif("${ExternalData_ACTION}" STREQUAL "local")
|
||||
foreach(v file name)
|
||||
if(NOT DEFINED "${v}")
|
||||
message(FATAL_ERROR "No \"-D${v}=\" value provided!")
|
||||
endif()
|
||||
endforeach()
|
||||
_ExternalData_link_or_copy("${name}" "${file}")
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown ExternalData_ACTION=[${ExternalData_ACTION}]")
|
||||
endif()
|
|
@ -0,0 +1,4 @@
|
|||
set(ExternalData_OBJECT_STORES "@ExternalData_OBJECT_STORES@")
|
||||
set(ExternalData_URL_TEMPLATES "@ExternalData_URL_TEMPLATES@")
|
||||
set(ExternalData_TIMEOUT_INACTIVITY "@ExternalData_TIMEOUT_INACTIVITY@")
|
||||
set(ExternalData_TIMEOUT_ABSOLUTE "@ExternalData_TIMEOUT_ABSOLUTE@")
|
|
@ -1559,8 +1559,11 @@ function(_ep_add_configure_command name)
|
|||
set(file_deps)
|
||||
get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
|
||||
foreach(dep IN LISTS deps)
|
||||
_ep_get_step_stampfile(${dep} "done" done_stamp_file)
|
||||
list(APPEND file_deps ${done_stamp_file})
|
||||
get_property(is_ep TARGET ${dep} PROPERTY _EP_IS_EXTERNAL_PROJECT)
|
||||
if(is_ep)
|
||||
_ep_get_step_stampfile(${dep} "done" done_stamp_file)
|
||||
list(APPEND file_deps ${done_stamp_file})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
get_property(cmd_set TARGET ${name} PROPERTY _EP_CONFIGURE_COMMAND SET)
|
||||
|
|
|
@ -439,28 +439,19 @@ list(APPEND GTK2_LIBRARIES ${FREETYPE_LIBRARIES})
|
|||
|
||||
foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
|
||||
if(_GTK2_component STREQUAL "gtk")
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GLIB_INCLUDE_DIR glib.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GLIBCONFIG_INCLUDE_DIR glibconfig.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GLIB_LIBRARY glib false true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GOBJECT_INCLUDE_DIR gobject/gobject.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GOBJECT_LIBRARY gobject false true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GDK_PIXBUF_INCLUDE_DIR gdk-pixbuf/gdk-pixbuf.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GDK_PIXBUF_LIBRARY gdk_pixbuf false true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GDK_INCLUDE_DIR gdk/gdk.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GDKCONFIG_INCLUDE_DIR gdkconfig.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h)
|
||||
|
||||
if(UNIX)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-x11 false true)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GTK_LIBRARY gtk-x11 false true)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-x11 false true)
|
||||
else()
|
||||
_GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-win32 false true)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GTK_LIBRARY gtk-win32 false true)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-win32 false true)
|
||||
endif()
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GDK_INCLUDE_DIR gdk/gdk.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GDKCONFIG_INCLUDE_DIR gdkconfig.h)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_CAIRO_INCLUDE_DIR cairo.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_CAIRO_LIBRARY cairo false false)
|
||||
|
||||
|
@ -469,35 +460,40 @@ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
|
|||
_GTK2_FIND_INCLUDE_DIR(GTK2_PANGO_INCLUDE_DIR pango/pango.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_PANGO_LIBRARY pango false true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GDK_PIXBUF_INCLUDE_DIR gdk-pixbuf/gdk-pixbuf.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GDK_PIXBUF_LIBRARY gdk_pixbuf false true)
|
||||
|
||||
_GTK2_FIND_LIBRARY (GTK2_GIO_LIBRARY gio false true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_ATK_INCLUDE_DIR atk/atk.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_ATK_LIBRARY atk false true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GOBJECT_INCLUDE_DIR gobject/gobject.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GOBJECT_LIBRARY gobject false true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GLIB_INCLUDE_DIR glib.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GLIBCONFIG_INCLUDE_DIR glibconfig.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GLIB_LIBRARY glib false true)
|
||||
|
||||
elseif(_GTK2_component STREQUAL "gtkmm")
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMM_INCLUDE_DIR glibmm.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMMCONFIG_INCLUDE_DIR glibmmconfig.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GLIBMM_LIBRARY glibmm true true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GDKMM_INCLUDE_DIR gdkmm.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GDKMMCONFIG_INCLUDE_DIR gdkmmconfig.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GDKMM_LIBRARY gdkmm true true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GTKMM_INCLUDE_DIR gtkmm.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GTKMMCONFIG_INCLUDE_DIR gtkmmconfig.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GTKMM_LIBRARY gtkmm true true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMM_INCLUDE_DIR cairomm/cairomm.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMMCONFIG_INCLUDE_DIR cairommconfig.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_CAIROMM_LIBRARY cairomm true true)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GDKMM_INCLUDE_DIR gdkmm.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GDKMMCONFIG_INCLUDE_DIR gdkmmconfig.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GDKMM_LIBRARY gdkmm true true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMM_INCLUDE_DIR pangomm.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMMCONFIG_INCLUDE_DIR pangommconfig.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_PANGOMM_LIBRARY pangomm true true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++_INCLUDE_DIR sigc++/sigc++.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++CONFIG_INCLUDE_DIR sigc++config.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_SIGC++_LIBRARY sigc true true)
|
||||
_GTK2_FIND_LIBRARY (GTK2_PANGOCAIRO_LIBRARY pangocairo true true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMM_INCLUDE_DIR cairomm/cairomm.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMMCONFIG_INCLUDE_DIR cairommconfig.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_CAIROMM_LIBRARY cairomm true true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GIOMM_INCLUDE_DIR giomm.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GIOMMCONFIG_INCLUDE_DIR giommconfig.h)
|
||||
|
@ -506,6 +502,15 @@ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
|
|||
_GTK2_FIND_INCLUDE_DIR(GTK2_ATKMM_INCLUDE_DIR atkmm.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_ATKMM_LIBRARY atkmm true true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMM_INCLUDE_DIR glibmm.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMMCONFIG_INCLUDE_DIR glibmmconfig.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_GLIBMM_LIBRARY glibmm true true)
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++_INCLUDE_DIR sigc++/sigc++.h)
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++CONFIG_INCLUDE_DIR sigc++config.h)
|
||||
_GTK2_FIND_LIBRARY (GTK2_SIGC++_LIBRARY sigc true true)
|
||||
|
||||
|
||||
elseif(_GTK2_component STREQUAL "glade")
|
||||
|
||||
_GTK2_FIND_INCLUDE_DIR(GTK2_GLADE_INCLUDE_DIR glade/glade.h)
|
||||
|
@ -549,13 +554,13 @@ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
|
|||
GTK2_GTK_LIBRARY
|
||||
GTK2_GTK_INCLUDE_DIR
|
||||
|
||||
GTK2_GLIB_INCLUDE_DIR
|
||||
GTK2_GLIBCONFIG_INCLUDE_DIR
|
||||
GTK2_GLIB_LIBRARY
|
||||
|
||||
GTK2_GDK_INCLUDE_DIR
|
||||
GTK2_GDKCONFIG_INCLUDE_DIR
|
||||
GTK2_GDK_LIBRARY
|
||||
|
||||
GTK2_GLIB_INCLUDE_DIR
|
||||
GTK2_GLIBCONFIG_INCLUDE_DIR
|
||||
GTK2_GLIB_LIBRARY
|
||||
)
|
||||
elseif(_GTK2_component STREQUAL "gtkmm")
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtkmm libraries were not found."
|
||||
|
@ -563,13 +568,14 @@ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
|
|||
GTK2_GTKMM_INCLUDE_DIR
|
||||
GTK2_GTKMMCONFIG_INCLUDE_DIR
|
||||
|
||||
GTK2_GDKMM_INCLUDE_DIR
|
||||
GTK2_GDKMMCONFIG_INCLUDE_DIR
|
||||
GTK2_GDKMM_LIBRARY
|
||||
|
||||
GTK2_GLIBMM_INCLUDE_DIR
|
||||
GTK2_GLIBMMCONFIG_INCLUDE_DIR
|
||||
GTK2_GLIBMM_LIBRARY
|
||||
|
||||
GTK2_GDKMM_INCLUDE_DIR
|
||||
GTK2_GDKMMCONFIG_INCLUDE_DIR
|
||||
GTK2_GDKMM_LIBRARY
|
||||
)
|
||||
elseif(_GTK2_component STREQUAL "glade")
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glade library was not found."
|
||||
|
|
|
@ -65,6 +65,12 @@
|
|||
# is much more flexible, but requires that FindQt4.cmake is executed before
|
||||
# such an exported dependency file is processed.
|
||||
#
|
||||
# Note that if using IMPORTED targets, the qtmain.lib static library is
|
||||
# automatically linked on Windows. To disable that globally, set the
|
||||
# QT4_NO_LINK_QTMAIN variable before finding Qt4. To disable that for a
|
||||
# particular executable, set the QT4_NO_LINK_QTMAIN target property to
|
||||
# True on the executable.
|
||||
#
|
||||
# QT_INCLUDE_DIRS_NO_SYSTEM
|
||||
# If this variable is set to TRUE, the Qt include directories
|
||||
# in the QT_USE_FILE will NOT have the SYSTEM keyword set.
|
||||
|
@ -1009,7 +1015,14 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
|
|||
# platform dependent libraries
|
||||
if(Q_WS_WIN)
|
||||
_QT4_ADJUST_LIB_VARS(qtmain)
|
||||
|
||||
_QT4_ADJUST_LIB_VARS(QAxServer)
|
||||
set_property(TARGET Qt4::QAxServer PROPERTY
|
||||
INTERFACE_QT4_NO_LINK_QTMAIN ON
|
||||
)
|
||||
set_property(TARGET Qt4::QAxServer APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_BOOL QT4_NO_LINK_QTMAIN)
|
||||
|
||||
_QT4_ADJUST_LIB_VARS(QAxContainer)
|
||||
endif()
|
||||
|
||||
|
@ -1049,6 +1062,21 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
|
|||
_qt4_add_target_private_depends(phonon DBus)
|
||||
endif()
|
||||
|
||||
if (WIN32 AND NOT QT4_NO_LINK_QTMAIN)
|
||||
set(_isExe $<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>)
|
||||
set(_isWin32 $<BOOL:$<TARGET_PROPERTY:WIN32_EXECUTABLE>>)
|
||||
set(_isNotExcluded $<NOT:$<BOOL:$<TARGET_PROPERTY:QT4_NO_LINK_QTMAIN>>>)
|
||||
set(_isPolicyNEW $<TARGET_POLICY:CMP0020>)
|
||||
set_property(TARGET Qt4::QtCore APPEND PROPERTY
|
||||
IMPORTED_LINK_INTERFACE_LIBRARIES
|
||||
$<$<AND:${_isExe},${_isWin32},${_isNotExcluded},${_isPolicyNEW}>:Qt4::qtmain>
|
||||
)
|
||||
unset(_isExe)
|
||||
unset(_isWin32)
|
||||
unset(_isNotExcluded)
|
||||
unset(_isPolicyNEW)
|
||||
endif()
|
||||
|
||||
#######################################
|
||||
#
|
||||
# Check the executables of Qt
|
||||
|
|
|
@ -41,6 +41,7 @@ set(WIN32 1)
|
|||
if(CMAKE_SYSTEM_NAME MATCHES "WindowsCE")
|
||||
set(CMAKE_CREATE_WIN32_EXE "/subsystem:windowsce /entry:WinMainCRTStartup")
|
||||
set(CMAKE_CREATE_CONSOLE_EXE "/subsystem:windowsce /entry:mainACRTStartup")
|
||||
set(WINCE 1)
|
||||
else()
|
||||
set(CMAKE_CREATE_WIN32_EXE "/subsystem:windows")
|
||||
set(CMAKE_CREATE_CONSOLE_EXE "/subsystem:console")
|
||||
|
@ -122,7 +123,7 @@ endif()
|
|||
# default to Debug builds
|
||||
set(CMAKE_BUILD_TYPE_INIT Debug)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "WindowsCE")
|
||||
if(WINCE)
|
||||
string(TOUPPER "${MSVC_C_ARCHITECTURE_ID}" _MSVC_C_ARCHITECTURE_ID_UPPER)
|
||||
string(TOUPPER "${MSVC_CXX_ARCHITECTURE_ID}" _MSVC_CXX_ARCHITECTURE_ID_UPPER)
|
||||
|
||||
|
@ -170,7 +171,7 @@ set(_MACHINE_ARCH_FLAG ${MSVC_C_ARCHITECTURE_ID})
|
|||
if(NOT _MACHINE_ARCH_FLAG)
|
||||
set(_MACHINE_ARCH_FLAG ${MSVC_CXX_ARCHITECTURE_ID})
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "WindowsCE")
|
||||
if(WINCE)
|
||||
if(_MACHINE_ARCH_FLAG MATCHES "ARM")
|
||||
set(_MACHINE_ARCH_FLAG "THUMB")
|
||||
elseif(_MACHINE_ARCH_FLAG MATCHES "SH")
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
set(CMake_VERSION_MAJOR 2)
|
||||
set(CMake_VERSION_MINOR 8)
|
||||
set(CMake_VERSION_PATCH 10)
|
||||
set(CMake_VERSION_TWEAK 20130118)
|
||||
set(CMake_VERSION_TWEAK 20130205)
|
||||
#set(CMake_VERSION_RC 1)
|
||||
|
|
|
@ -47,9 +47,24 @@
|
|||
" $<TARGET_LINKER_FILE_DIR:tgt>/$<TARGET_LINKER_FILE_NAME:tgt>\n" \
|
||||
" $<TARGET_SONAME_FILE_DIR:tgt>/$<TARGET_SONAME_FILE_NAME:tgt>\n" \
|
||||
"\n" \
|
||||
" $<TARGET_PROPERTY:tgt,prop> = The value of the property prop\n" \
|
||||
"on the target tgt. Note that tgt is not added as a dependency of\n" \
|
||||
"the target this expression is evaluated on.\n" \
|
||||
" $<TARGET_PROPERTY:tgt,prop> = The value of the property prop " \
|
||||
"on the target tgt.\n" \
|
||||
"Note that tgt is not added as a dependency of the target this " \
|
||||
"expression is evaluated on.\n" \
|
||||
" $<LINKED:item> = An empty string if item is not a " \
|
||||
"target. If item is a target then the " \
|
||||
"INTERFACE_INCLUDE_DIRECTORIES or INTERFACE_COMPILE_DEFINITIONS " \
|
||||
"content is read from the target. " \
|
||||
"This generator expression can only be used in evaluation of the " \
|
||||
"INCLUDE_DIRECTORIES or COMPILE_DEFINITIONS property. Note that " \
|
||||
"this expression is for internal use and may be changed or removed " \
|
||||
"in the future.\n" \
|
||||
" $<TARGET_POLICY:pol> = '1' if the policy was NEW when " \
|
||||
"the 'head' target was created, else '0'. If the policy was not " \
|
||||
"set, the warning message for the policy will be emitted. This " \
|
||||
"generator expression only works for a subset of policies.\n" \
|
||||
" $<INSTALL_PREFIX> = Content of the install prefix when " \
|
||||
"the target is exported via INSTALL(EXPORT) and empty otherwise.\n" \
|
||||
"Boolean expressions:\n" \
|
||||
" $<AND:?[,?]...> = '1' if all '?' are '1', else '0'\n" \
|
||||
" $<OR:?[,?]...> = '0' if all '?' are '0', else '1'\n" \
|
||||
|
@ -60,7 +75,7 @@
|
|||
#define CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS \
|
||||
CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS \
|
||||
"Expressions with an implicit 'this' target:\n" \
|
||||
" $<TARGET_PROPERTY:prop> = The value of the property prop on\n" \
|
||||
" $<TARGET_PROPERTY:prop> = The value of the property prop on " \
|
||||
"the target on which the generator expression is evaluated.\n" \
|
||||
""
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
|
||||
te, properties);
|
||||
this->PopulateCompatibleInterfaceProperties(te, properties);
|
||||
|
||||
this->GenerateInterfaceProperties(te, os, properties);
|
||||
}
|
||||
|
|
|
@ -21,9 +21,12 @@
|
|||
#include "cmTarget.h"
|
||||
#include "cmTargetExport.h"
|
||||
#include "cmVersion.h"
|
||||
#include "cmComputeLinkInformation.h"
|
||||
|
||||
#include <cmsys/auto_ptr.hxx>
|
||||
|
||||
#include "assert.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmExportFileGenerator::cmExportFileGenerator()
|
||||
{
|
||||
|
@ -81,16 +84,16 @@ bool cmExportFileGenerator::GenerateImportFile()
|
|||
|
||||
// Protect that file against use with older CMake versions.
|
||||
os << "# Generated by CMake " << cmVersion::GetCMakeVersion() << "\n\n";
|
||||
os << "IF(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
|
||||
<< " MESSAGE(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
|
||||
<< "ENDIF(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n";
|
||||
os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
|
||||
<< " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
|
||||
<< "endif()\n";
|
||||
|
||||
// Isolate the file policy level.
|
||||
// We use 2.6 here instead of the current version because newer
|
||||
// versions of CMake should be able to export files imported by 2.6
|
||||
// until the import format changes.
|
||||
os << "CMAKE_POLICY(PUSH)\n"
|
||||
<< "CMAKE_POLICY(VERSION 2.6)\n";
|
||||
os << "cmake_policy(PUSH)\n"
|
||||
<< "cmake_policy(VERSION 2.6)\n";
|
||||
|
||||
// Start with the import file header.
|
||||
this->GenerateImportHeaderCode(os);
|
||||
|
@ -100,7 +103,7 @@ bool cmExportFileGenerator::GenerateImportFile()
|
|||
|
||||
// End with the import file footer.
|
||||
this->GenerateImportFooterCode(os);
|
||||
os << "CMAKE_POLICY(POP)\n";
|
||||
os << "cmake_policy(POP)\n";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -159,7 +162,7 @@ void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
|
|||
preprocessRule);
|
||||
if (!prepro.empty())
|
||||
{
|
||||
this->ResolveTargetsInGeneratorExpressions(prepro, target,
|
||||
this->ResolveTargetsInGeneratorExpressions(prepro, target, propName,
|
||||
missingTargets);
|
||||
properties[outputName] = prepro;
|
||||
}
|
||||
|
@ -177,6 +180,85 @@ void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
|
|||
properties, missingTargets);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void getPropertyContents(cmTarget *tgt, const char *prop,
|
||||
std::set<std::string> &ifaceProperties)
|
||||
{
|
||||
const char *p = tgt->GetProperty(prop);
|
||||
if (!p)
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> content;
|
||||
cmSystemTools::ExpandListArgument(p, content);
|
||||
for (std::vector<std::string>::const_iterator ci = content.begin();
|
||||
ci != content.end(); ++ci)
|
||||
{
|
||||
ifaceProperties.insert(*ci);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void getCompatibleInterfaceProperties(cmTarget *target,
|
||||
std::set<std::string> &ifaceProperties,
|
||||
const char *config)
|
||||
{
|
||||
cmComputeLinkInformation *info = target->GetLinkInformation(config);
|
||||
|
||||
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
||||
|
||||
for(cmComputeLinkInformation::ItemVector::const_iterator li =
|
||||
deps.begin();
|
||||
li != deps.end(); ++li)
|
||||
{
|
||||
if (!li->Target)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
getPropertyContents(li->Target,
|
||||
"COMPATIBLE_INTERFACE_BOOL",
|
||||
ifaceProperties);
|
||||
getPropertyContents(li->Target,
|
||||
"COMPATIBLE_INTERFACE_STRING",
|
||||
ifaceProperties);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
|
||||
cmTarget *target,
|
||||
ImportPropertyMap &properties)
|
||||
{
|
||||
this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL",
|
||||
target, properties);
|
||||
this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_STRING",
|
||||
target, properties);
|
||||
|
||||
std::set<std::string> ifaceProperties;
|
||||
|
||||
getPropertyContents(target, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties);
|
||||
getPropertyContents(target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties);
|
||||
|
||||
getCompatibleInterfaceProperties(target, ifaceProperties, 0);
|
||||
|
||||
std::vector<std::string> configNames;
|
||||
target->GetMakefile()->GetConfigurations(configNames);
|
||||
|
||||
for (std::vector<std::string>::const_iterator ci = configNames.begin();
|
||||
ci != configNames.end(); ++ci)
|
||||
{
|
||||
getCompatibleInterfaceProperties(target, ifaceProperties, ci->c_str());
|
||||
}
|
||||
|
||||
for (std::set<std::string>::const_iterator it = ifaceProperties.begin();
|
||||
it != ifaceProperties.end(); ++it)
|
||||
{
|
||||
this->PopulateInterfaceProperty(("INTERFACE_" + *it).c_str(),
|
||||
target, properties);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
|
||||
std::ostream& os,
|
||||
|
@ -184,15 +266,16 @@ void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
|
|||
{
|
||||
if (!properties.empty())
|
||||
{
|
||||
os << "if(NOT ${CMAKE_FIND_PACKAGE_NAME}_NO_INTERFACES)\n";
|
||||
std::string targetName = this->Namespace;
|
||||
targetName += target->GetName();
|
||||
os << "SET_TARGET_PROPERTIES(" << targetName << " PROPERTIES\n";
|
||||
os << " set_target_properties(" << targetName << " PROPERTIES\n";
|
||||
for(ImportPropertyMap::const_iterator pi = properties.begin();
|
||||
pi != properties.end(); ++pi)
|
||||
{
|
||||
os << " " << pi->first << " \"" << pi->second << "\"\n";
|
||||
os << " " << pi->first << " \"" << pi->second << "\"\n";
|
||||
}
|
||||
os << ")\n\n";
|
||||
os << " )\nendif()\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,13 +326,14 @@ static bool isGeneratorExpression(const std::string &lib)
|
|||
void
|
||||
cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
|
||||
std::string &input,
|
||||
cmTarget* target,
|
||||
cmTarget* target, const char *propName,
|
||||
std::vector<std::string> &missingTargets,
|
||||
FreeTargetsReplace replace)
|
||||
{
|
||||
if (replace == NoReplaceFreeTargets)
|
||||
{
|
||||
this->ResolveTargetsInGeneratorExpression(input, target, missingTargets);
|
||||
this->ResolveTargetsInGeneratorExpression(input, target, propName,
|
||||
missingTargets);
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> parts;
|
||||
|
@ -268,7 +352,7 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
|
|||
{
|
||||
this->ResolveTargetsInGeneratorExpression(
|
||||
*li,
|
||||
target,
|
||||
target, propName,
|
||||
missingTargets);
|
||||
}
|
||||
input += sep + *li;
|
||||
|
@ -280,14 +364,13 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
|
|||
void
|
||||
cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
|
||||
std::string &input,
|
||||
cmTarget* target,
|
||||
cmTarget* target, const char *propName,
|
||||
std::vector<std::string> &missingTargets)
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type lastPos = pos;
|
||||
|
||||
cmMakefile *mf = target->GetMakefile();
|
||||
std::string errorString;
|
||||
|
||||
while((pos = input.find("$<TARGET_PROPERTY:", lastPos)) != input.npos)
|
||||
{
|
||||
|
@ -308,14 +391,58 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
|
|||
std::string targetName = input.substr(nameStartPos,
|
||||
commaPos - nameStartPos);
|
||||
|
||||
if (!this->AddTargetNamespace(targetName, target, missingTargets))
|
||||
if (this->AddTargetNamespace(targetName, target, missingTargets))
|
||||
{
|
||||
errorString = "$<TARGET_PROPERTY:" + targetName + ",prop> requires "
|
||||
"its first parameter to be a reachable target.";
|
||||
input.replace(nameStartPos, commaPos - nameStartPos, targetName);
|
||||
}
|
||||
lastPos = nameStartPos + targetName.size() + 1;
|
||||
}
|
||||
|
||||
std::string errorString;
|
||||
pos = 0;
|
||||
lastPos = pos;
|
||||
while((pos = input.find("$<LINKED:", lastPos)) != input.npos)
|
||||
{
|
||||
std::string::size_type nameStartPos = pos + sizeof("$<LINKED:") - 1;
|
||||
std::string::size_type endPos = input.find(">", nameStartPos);
|
||||
if (endPos == input.npos)
|
||||
{
|
||||
errorString = "$<LINKED:...> expression incomplete";
|
||||
break;
|
||||
}
|
||||
input.replace(nameStartPos, commaPos - nameStartPos, targetName);
|
||||
lastPos = pos + targetName.size();
|
||||
std::string targetName = input.substr(nameStartPos,
|
||||
endPos - nameStartPos);
|
||||
if(targetName.find("$<") != input.npos)
|
||||
{
|
||||
errorString = "$<LINKED:...> requires its parameter to be a "
|
||||
"literal.";
|
||||
break;
|
||||
}
|
||||
if (this->AddTargetNamespace(targetName, target, missingTargets))
|
||||
{
|
||||
assert(propName); // The link libraries strings will
|
||||
// never contain $<LINKED>
|
||||
std::string replacement = "$<TARGET_PROPERTY:"
|
||||
+ targetName + "," + propName;
|
||||
input.replace(pos, endPos - pos, replacement);
|
||||
lastPos = pos + replacement.size() + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pos != 0)
|
||||
{
|
||||
if (input[pos - 1] == ';')
|
||||
{
|
||||
--pos;
|
||||
}
|
||||
}
|
||||
else if (input[endPos + 1] == ';')
|
||||
{
|
||||
++endPos;
|
||||
}
|
||||
input.replace(pos, endPos - pos + 1, "");
|
||||
lastPos = pos;
|
||||
}
|
||||
}
|
||||
if (!errorString.empty())
|
||||
{
|
||||
|
@ -351,12 +478,22 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
|
|||
input.replace(pos, endPos - pos + 1, targetName);
|
||||
lastPos = endPos;
|
||||
}
|
||||
|
||||
this->ReplaceInstallPrefix(input);
|
||||
|
||||
if (!errorString.empty())
|
||||
{
|
||||
mf->IssueMessage(cmake::FATAL_ERROR, errorString);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmExportFileGenerator::ReplaceInstallPrefix(std::string &)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmExportFileGenerator
|
||||
|
@ -408,7 +545,7 @@ cmExportFileGenerator
|
|||
preprocessRule);
|
||||
if (!prepro.empty())
|
||||
{
|
||||
this->ResolveTargetsInGeneratorExpressions(prepro, target,
|
||||
this->ResolveTargetsInGeneratorExpressions(prepro, target, 0,
|
||||
missingTargets,
|
||||
ReplaceFreeTargets);
|
||||
properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro;
|
||||
|
@ -536,7 +673,7 @@ void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os,
|
|||
void cmExportFileGenerator::GenerateImportFooterCode(std::ostream& os)
|
||||
{
|
||||
os << "# Commands beyond this point should not need to know the version.\n"
|
||||
<< "SET(CMAKE_IMPORT_FILE_VERSION)\n";
|
||||
<< "set(CMAKE_IMPORT_FILE_VERSION)\n";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -545,7 +682,7 @@ void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os)
|
|||
// Store an import file format version. This will let us change the
|
||||
// format later while still allowing old import files to work.
|
||||
os << "# Commands may need to know the format version.\n"
|
||||
<< "SET(CMAKE_IMPORT_FILE_VERSION 1)\n"
|
||||
<< "set(CMAKE_IMPORT_FILE_VERSION 1)\n"
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
|
@ -553,31 +690,31 @@ void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os)
|
|||
void cmExportFileGenerator::GenerateExpectedTargetsCode(std::ostream& os,
|
||||
const std::string &expectedTargets)
|
||||
{
|
||||
os << "SET(_targetsDefined)\n"
|
||||
"SET(_targetsNotDefined)\n"
|
||||
"SET(_expectedTargets)\n"
|
||||
"FOREACH(_expectedTarget " << expectedTargets << ")\n"
|
||||
" LIST(APPEND _expectedTargets ${_expectedTarget})\n"
|
||||
" IF(NOT TARGET ${_expectedTarget})\n"
|
||||
" LIST(APPEND _targetsNotDefined ${_expectedTarget})\n"
|
||||
" ENDIF(NOT TARGET ${_expectedTarget})\n"
|
||||
" IF(TARGET ${_expectedTarget})\n"
|
||||
" LIST(APPEND _targetsDefined ${_expectedTarget})\n"
|
||||
" ENDIF(TARGET ${_expectedTarget})\n"
|
||||
"ENDFOREACH(_expectedTarget)\n"
|
||||
"IF(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n"
|
||||
" SET(CMAKE_IMPORT_FILE_VERSION)\n"
|
||||
" CMAKE_POLICY(POP)\n"
|
||||
" RETURN()\n"
|
||||
"ENDIF(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n"
|
||||
"IF(NOT \"${_targetsDefined}\" STREQUAL \"\")\n"
|
||||
" MESSAGE(FATAL_ERROR \"Some (but not all) targets in this export "
|
||||
os << "set(_targetsDefined)\n"
|
||||
"set(_targetsNotDefined)\n"
|
||||
"set(_expectedTargets)\n"
|
||||
"foreach(_expectedTarget " << expectedTargets << ")\n"
|
||||
" list(APPEND _expectedTargets ${_expectedTarget})\n"
|
||||
" if(NOT TARGET ${_expectedTarget})\n"
|
||||
" list(APPEND _targetsNotDefined ${_expectedTarget})\n"
|
||||
" endif()\n"
|
||||
" if(TARGET ${_expectedTarget})\n"
|
||||
" list(APPEND _targetsDefined ${_expectedTarget})\n"
|
||||
" endif()\n"
|
||||
"endforeach()\n"
|
||||
"if(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n"
|
||||
" set(CMAKE_IMPORT_FILE_VERSION)\n"
|
||||
" cmake_policy(POP)\n"
|
||||
" return()\n"
|
||||
"endif()\n"
|
||||
"if(NOT \"${_targetsDefined}\" STREQUAL \"\")\n"
|
||||
" message(FATAL_ERROR \"Some (but not all) targets in this export "
|
||||
"set were already defined.\\nTargets Defined: ${_targetsDefined}\\n"
|
||||
"Targets not yet defined: ${_targetsNotDefined}\\n\")\n"
|
||||
"ENDIF(NOT \"${_targetsDefined}\" STREQUAL \"\")\n"
|
||||
"UNSET(_targetsDefined)\n"
|
||||
"UNSET(_targetsNotDefined)\n"
|
||||
"UNSET(_expectedTargets)\n"
|
||||
"endif()\n"
|
||||
"unset(_targetsDefined)\n"
|
||||
"unset(_targetsNotDefined)\n"
|
||||
"unset(_expectedTargets)\n"
|
||||
"\n\n";
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -594,16 +731,16 @@ cmExportFileGenerator
|
|||
switch(target->GetType())
|
||||
{
|
||||
case cmTarget::EXECUTABLE:
|
||||
os << "ADD_EXECUTABLE(" << targetName << " IMPORTED)\n";
|
||||
os << "add_executable(" << targetName << " IMPORTED)\n";
|
||||
break;
|
||||
case cmTarget::STATIC_LIBRARY:
|
||||
os << "ADD_LIBRARY(" << targetName << " STATIC IMPORTED)\n";
|
||||
os << "add_library(" << targetName << " STATIC IMPORTED)\n";
|
||||
break;
|
||||
case cmTarget::SHARED_LIBRARY:
|
||||
os << "ADD_LIBRARY(" << targetName << " SHARED IMPORTED)\n";
|
||||
os << "add_library(" << targetName << " SHARED IMPORTED)\n";
|
||||
break;
|
||||
case cmTarget::MODULE_LIBRARY:
|
||||
os << "ADD_LIBRARY(" << targetName << " MODULE IMPORTED)\n";
|
||||
os << "add_library(" << targetName << " MODULE IMPORTED)\n";
|
||||
break;
|
||||
default: // should never happen
|
||||
break;
|
||||
|
@ -612,27 +749,27 @@ cmExportFileGenerator
|
|||
// Mark the imported executable if it has exports.
|
||||
if(target->IsExecutableWithExports())
|
||||
{
|
||||
os << "SET_PROPERTY(TARGET " << targetName
|
||||
os << "set_property(TARGET " << targetName
|
||||
<< " PROPERTY ENABLE_EXPORTS 1)\n";
|
||||
}
|
||||
|
||||
// Mark the imported library if it is a framework.
|
||||
if(target->IsFrameworkOnApple())
|
||||
{
|
||||
os << "SET_PROPERTY(TARGET " << targetName
|
||||
os << "set_property(TARGET " << targetName
|
||||
<< " PROPERTY FRAMEWORK 1)\n";
|
||||
}
|
||||
|
||||
// Mark the imported executable if it is an application bundle.
|
||||
if(target->IsAppBundleOnApple())
|
||||
{
|
||||
os << "SET_PROPERTY(TARGET " << targetName
|
||||
os << "set_property(TARGET " << targetName
|
||||
<< " PROPERTY MACOSX_BUNDLE 1)\n";
|
||||
}
|
||||
|
||||
if (target->IsCFBundleOnApple())
|
||||
{
|
||||
os << "SET_PROPERTY(TARGET " << targetName
|
||||
os << "set_property(TARGET " << targetName
|
||||
<< " PROPERTY BUNDLE 1)\n";
|
||||
}
|
||||
os << "\n";
|
||||
|
@ -652,7 +789,7 @@ cmExportFileGenerator
|
|||
// Set the import properties.
|
||||
os << "# Import target \"" << targetName << "\" for configuration \""
|
||||
<< config << "\"\n";
|
||||
os << "SET_PROPERTY(TARGET " << targetName
|
||||
os << "set_property(TARGET " << targetName
|
||||
<< " APPEND PROPERTY IMPORTED_CONFIGURATIONS ";
|
||||
if(config && *config)
|
||||
{
|
||||
|
@ -663,7 +800,7 @@ cmExportFileGenerator
|
|||
os << "NOCONFIG";
|
||||
}
|
||||
os << ")\n";
|
||||
os << "SET_TARGET_PROPERTIES(" << targetName << " PROPERTIES\n";
|
||||
os << "set_target_properties(" << targetName << " PROPERTIES\n";
|
||||
for(ImportPropertyMap::const_iterator pi = properties.begin();
|
||||
pi != properties.end(); ++pi)
|
||||
{
|
||||
|
@ -689,17 +826,17 @@ void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os,
|
|||
{
|
||||
if (emitted.insert(missingTargets[i]).second)
|
||||
{
|
||||
os << "IF(NOT TARGET \"" << missingTargets[i] << "\" )\n"
|
||||
<< " IF(CMAKE_FIND_PACKAGE_NAME)\n"
|
||||
<< " SET( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n"
|
||||
<< " SET( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "
|
||||
os << "if(NOT TARGET \"" << missingTargets[i] << "\" )\n"
|
||||
<< " if(CMAKE_FIND_PACKAGE_NAME)\n"
|
||||
<< " set( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n"
|
||||
<< " set( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "
|
||||
<< "\"Required imported target \\\"" << missingTargets[i]
|
||||
<< "\\\" not found ! \")\n"
|
||||
<< " ELSE()\n"
|
||||
<< " MESSAGE(FATAL_ERROR \"Required imported target \\\""
|
||||
<< " else()\n"
|
||||
<< " message(FATAL_ERROR \"Required imported target \\\""
|
||||
<< missingTargets[i] << "\\\" not found ! \")\n"
|
||||
<< " ENDIF()\n"
|
||||
<< "ENDIF()\n";
|
||||
<< " endif()\n"
|
||||
<< "endif()\n";
|
||||
}
|
||||
}
|
||||
os << "\n";
|
||||
|
@ -718,10 +855,10 @@ cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
|
|||
// on SUSE with a mysql pkg-config file, which claimed everything is fine,
|
||||
// but the development package was not installed.).
|
||||
os << "# Loop over all imported files and verify that they actually exist\n"
|
||||
"FOREACH(target ${_IMPORT_CHECK_TARGETS} )\n"
|
||||
" FOREACH(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n"
|
||||
" IF(NOT EXISTS \"${file}\" )\n"
|
||||
" MESSAGE(FATAL_ERROR \"The imported target \\\"${target}\\\""
|
||||
"foreach(target ${_IMPORT_CHECK_TARGETS} )\n"
|
||||
" foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n"
|
||||
" if(NOT EXISTS \"${file}\" )\n"
|
||||
" message(FATAL_ERROR \"The imported target \\\"${target}\\\""
|
||||
" references the file\n"
|
||||
" \\\"${file}\\\"\n"
|
||||
"but this file does not exist. Possible reasons include:\n"
|
||||
|
@ -731,11 +868,11 @@ cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
|
|||
" \\\"${CMAKE_CURRENT_LIST_FILE}\\\"\n"
|
||||
"but not all the files it references.\n"
|
||||
"\")\n"
|
||||
" ENDIF()\n"
|
||||
" ENDFOREACH()\n"
|
||||
" UNSET(_IMPORT_CHECK_FILES_FOR_${target})\n"
|
||||
"ENDFOREACH()\n"
|
||||
"UNSET(_IMPORT_CHECK_TARGETS)\n"
|
||||
" endif()\n"
|
||||
" endforeach()\n"
|
||||
" unset(_IMPORT_CHECK_FILES_FOR_${target})\n"
|
||||
"endforeach()\n"
|
||||
"unset(_IMPORT_CHECK_TARGETS)\n"
|
||||
"\n";
|
||||
}
|
||||
|
||||
|
@ -751,8 +888,8 @@ cmExportFileGenerator
|
|||
std::string targetName = this->Namespace;
|
||||
targetName += target->GetName();
|
||||
|
||||
os << "LIST(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n"
|
||||
"LIST(APPEND _IMPORT_CHECK_FILES_FOR_" << targetName << " ";
|
||||
os << "list(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n"
|
||||
"list(APPEND _IMPORT_CHECK_FILES_FOR_" << targetName << " ";
|
||||
|
||||
for(std::set<std::string>::const_iterator li = importedLocations.begin();
|
||||
li != importedLocations.end();
|
||||
|
|
|
@ -103,6 +103,8 @@ protected:
|
|||
std::vector<std::string> &missingTargets);
|
||||
void PopulateInterfaceProperty(const char *propName, cmTarget *target,
|
||||
ImportPropertyMap &properties);
|
||||
void PopulateCompatibleInterfaceProperties(cmTarget *target,
|
||||
ImportPropertyMap &properties);
|
||||
void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
|
||||
const ImportPropertyMap &properties);
|
||||
|
||||
|
@ -117,7 +119,7 @@ protected:
|
|||
};
|
||||
|
||||
void ResolveTargetsInGeneratorExpressions(std::string &input,
|
||||
cmTarget* target,
|
||||
cmTarget* target, const char *propName,
|
||||
std::vector<std::string> &missingTargets,
|
||||
FreeTargetsReplace replace = NoReplaceFreeTargets);
|
||||
|
||||
|
@ -148,8 +150,10 @@ private:
|
|||
std::vector<std::string> &missingTargets);
|
||||
|
||||
void ResolveTargetsInGeneratorExpression(std::string &input,
|
||||
cmTarget* target,
|
||||
cmTarget* target, const char *propName,
|
||||
std::vector<std::string> &missingTargets);
|
||||
|
||||
virtual void ReplaceInstallPrefix(std::string &input);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,7 +57,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
else
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "INSTALL(EXPORT \""
|
||||
e << "install(EXPORT \""
|
||||
<< this->IEGen->GetExportSet()->GetName()
|
||||
<< "\" ...) " << "includes target \"" << te->Target->GetName()
|
||||
<< "\" more than once in the export set.";
|
||||
|
@ -69,6 +69,27 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
this->GenerateExpectedTargetsCode(os, expectedTargets);
|
||||
}
|
||||
|
||||
// Add code to compute the installation prefix relative to the
|
||||
// import file location.
|
||||
const char* installDest = this->IEGen->GetDestination();
|
||||
if(!cmSystemTools::FileIsFullPath(installDest))
|
||||
{
|
||||
std::string dest = installDest;
|
||||
os << "# Compute the installation prefix relative to this file.\n"
|
||||
<< "get_filename_component(_IMPORT_PREFIX "
|
||||
<< "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
|
||||
while(!dest.empty())
|
||||
{
|
||||
os <<
|
||||
"get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
|
||||
dest = cmSystemTools::GetFilenamePath(dest);
|
||||
}
|
||||
os << "\n";
|
||||
|
||||
// Import location properties may reference this variable.
|
||||
this->ImportPrefix = "${_IMPORT_PREFIX}/";
|
||||
}
|
||||
|
||||
std::vector<std::string> missingTargets;
|
||||
|
||||
// Create all the imported targets.
|
||||
|
@ -91,6 +112,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
|
||||
te, properties);
|
||||
this->PopulateCompatibleInterfaceProperties(te, properties);
|
||||
|
||||
this->GenerateInterfaceProperties(te, os, properties);
|
||||
}
|
||||
|
@ -98,14 +120,21 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
|
||||
// Now load per-configuration properties for them.
|
||||
os << "# Load information for each installed configuration.\n"
|
||||
<< "GET_FILENAME_COMPONENT(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
|
||||
<< "FILE(GLOB CONFIG_FILES \"${_DIR}/"
|
||||
<< "get_filename_component(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
|
||||
<< "file(GLOB CONFIG_FILES \"${_DIR}/"
|
||||
<< this->GetConfigImportFileGlob() << "\")\n"
|
||||
<< "FOREACH(f ${CONFIG_FILES})\n"
|
||||
<< " INCLUDE(${f})\n"
|
||||
<< "ENDFOREACH(f)\n"
|
||||
<< "foreach(f ${CONFIG_FILES})\n"
|
||||
<< " include(${f})\n"
|
||||
<< "endforeach()\n"
|
||||
<< "\n";
|
||||
|
||||
// Cleanup the import prefix variable.
|
||||
if(!this->ImportPrefix.empty())
|
||||
{
|
||||
os << "# Cleanup temporary variables.\n"
|
||||
<< "set(_IMPORT_PREFIX)\n"
|
||||
<< "\n";
|
||||
}
|
||||
this->GenerateImportedFileCheckLoop(os);
|
||||
|
||||
// Generate an import file for each configuration.
|
||||
|
@ -125,6 +154,21 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmExportInstallFileGenerator::ReplaceInstallPrefix(std::string &input)
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type lastPos = pos;
|
||||
|
||||
while((pos = input.find("$<INSTALL_PREFIX>", lastPos)) != input.npos)
|
||||
{
|
||||
std::string::size_type endPos = pos + sizeof("$<INSTALL_PREFIX>") - 1;
|
||||
input.replace(pos, endPos - pos, "${_IMPORT_PREFIX}");
|
||||
lastPos = endPos;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config,
|
||||
|
@ -186,27 +230,6 @@ cmExportInstallFileGenerator
|
|||
const char* config, std::string const& suffix,
|
||||
std::vector<std::string> &missingTargets)
|
||||
{
|
||||
// Add code to compute the installation prefix relative to the
|
||||
// import file location.
|
||||
const char* installDest = this->IEGen->GetDestination();
|
||||
if(!cmSystemTools::FileIsFullPath(installDest))
|
||||
{
|
||||
std::string dest = installDest;
|
||||
os << "# Compute the installation prefix relative to this file.\n"
|
||||
<< "GET_FILENAME_COMPONENT(_IMPORT_PREFIX "
|
||||
<< "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
|
||||
while(!dest.empty())
|
||||
{
|
||||
os <<
|
||||
"GET_FILENAME_COMPONENT(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
|
||||
dest = cmSystemTools::GetFilenamePath(dest);
|
||||
}
|
||||
os << "\n";
|
||||
|
||||
// Import location properties may reference this variable.
|
||||
this->ImportPrefix = "${_IMPORT_PREFIX}/";
|
||||
}
|
||||
|
||||
// Add each target in the set to the export.
|
||||
for(std::vector<cmTargetExport*>::const_iterator
|
||||
tei = this->IEGen->GetExportSet()->GetTargetExports()->begin();
|
||||
|
@ -252,14 +275,6 @@ cmExportInstallFileGenerator
|
|||
importedLocations);
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup the import prefix variable.
|
||||
if(!this->ImportPrefix.empty())
|
||||
{
|
||||
os << "# Cleanup temporary variables.\n"
|
||||
<< "SET(_IMPORT_PREFIX)\n"
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -427,7 +442,7 @@ cmExportInstallFileGenerator
|
|||
{
|
||||
const char* installDest = this->IEGen->GetDestination();
|
||||
cmOStringStream e;
|
||||
e << "INSTALL(EXPORT \""
|
||||
e << "install(EXPORT \""
|
||||
<< this->IEGen->GetExportSet()->GetName()
|
||||
<< "\") given absolute "
|
||||
<< "DESTINATION \"" << installDest << "\" but the export "
|
||||
|
@ -445,7 +460,7 @@ cmExportInstallFileGenerator
|
|||
int occurrences)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "INSTALL(EXPORT \""
|
||||
e << "install(EXPORT \""
|
||||
<< this->IEGen->GetExportSet()->GetName()
|
||||
<< "\" ...) "
|
||||
<< "includes target \"" << depender->GetName()
|
||||
|
|
|
@ -64,6 +64,8 @@ protected:
|
|||
cmTarget* depender,
|
||||
cmTarget* dependee);
|
||||
|
||||
virtual void ReplaceInstallPrefix(std::string &input);
|
||||
|
||||
void ComplainAboutMissingTarget(cmTarget* depender,
|
||||
cmTarget* dependee,
|
||||
int occurrences);
|
||||
|
|
|
@ -621,7 +621,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
|
|||
->GetGeneratorTarget(target);
|
||||
|
||||
// the compilerdefines for this target
|
||||
std::string cdefs = gtgt->GetCompileDefinitions();
|
||||
std::string cdefs = target->GetCompileDefinitions();
|
||||
|
||||
if(!cdefs.empty())
|
||||
{
|
||||
|
|
|
@ -37,9 +37,13 @@ bool cmFLTKWrapUICommand
|
|||
// get the list of GUI files from which .cxx and .h will be generated
|
||||
std::string outputDirectory = this->Makefile->GetCurrentOutputDirectory();
|
||||
|
||||
{
|
||||
// Some of the generated files are *.h so the directory "GUI"
|
||||
// where they are created have to be added to the include path
|
||||
this->Makefile->AddIncludeDirectory( outputDirectory.c_str() );
|
||||
std::vector<std::string> outputDirectories;
|
||||
outputDirectories.push_back(outputDirectory);
|
||||
this->Makefile->AddIncludeDirectories( outputDirectories );
|
||||
}
|
||||
|
||||
for(std::vector<std::string>::iterator i = (newArgs.begin() + 1);
|
||||
i != newArgs.end(); i++)
|
||||
|
|
|
@ -376,6 +376,26 @@ void cmFindPackageCommand::GenerateDocumentation()
|
|||
"The package configuration file may set <package>_FOUND to false "
|
||||
"to tell find_package that component requirements are not satisfied."
|
||||
"\n"
|
||||
"A package configuration file may include() a <package>Targets.cmake "
|
||||
"file, created by install(EXPORT) in the upstream source, to import "
|
||||
"targets into the downstream consumer. "
|
||||
"When a new version of the upstream adds INTERFACE properties not "
|
||||
"present in a previous version it can change behavior for existing "
|
||||
"downstreams. "
|
||||
"In order to remain source compatible the upstream package configuration "
|
||||
"file may set <package>_NO_INTERFACES to disable INTERFACE properties. "
|
||||
"For example, code of the form:\n"
|
||||
" if(<package>_FIND_VERSION VERSION_LESS <new-version>\n"
|
||||
" AND NOT <package>_INTERFACES)\n"
|
||||
" set(<package>_NO_INTERFACES 1)\n"
|
||||
" endif()\n"
|
||||
" include(\"${CMAKE_CURRENT_LIST_DIR}/<package>Targets.cmake\")\n"
|
||||
"tells <package>Targets.cmake not to provide the INTERFACE properties "
|
||||
"unless the downstream requests at least <new-version> or sets "
|
||||
"<package>_INTERFACES to explicitly request them. "
|
||||
"This allows consumers to decide when to enable the new interfaces when "
|
||||
"upgrading."
|
||||
"\n"
|
||||
"See the cmake_policy() command documentation for discussion of the "
|
||||
"NO_POLICY_SCOPE option."
|
||||
;
|
||||
|
|
|
@ -88,6 +88,7 @@ const char *cmCompiledGeneratorExpression::Evaluate(
|
|||
context.Config = config;
|
||||
context.Quiet = quiet;
|
||||
context.HadError = false;
|
||||
context.HadContextSensitiveCondition = false;
|
||||
context.HeadTarget = headTarget;
|
||||
context.CurrentTarget = currentTarget ? currentTarget : headTarget;
|
||||
context.Backtrace = this->Backtrace;
|
||||
|
@ -109,6 +110,10 @@ const char *cmCompiledGeneratorExpression::Evaluate(
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!context.HadError)
|
||||
{
|
||||
this->HadContextSensitiveCondition = context.HadContextSensitiveCondition;
|
||||
}
|
||||
|
||||
this->Targets = context.Targets;
|
||||
// TODO: Return a std::string from here instead?
|
||||
|
@ -118,7 +123,8 @@ const char *cmCompiledGeneratorExpression::Evaluate(
|
|||
cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
|
||||
cmListFileBacktrace const& backtrace,
|
||||
const char *input)
|
||||
: Backtrace(backtrace), Input(input ? input : "")
|
||||
: Backtrace(backtrace), Input(input ? input : ""),
|
||||
HadContextSensitiveCondition(false)
|
||||
{
|
||||
cmGeneratorExpressionLexer l;
|
||||
std::vector<cmGeneratorExpressionToken> tokens =
|
||||
|
|
|
@ -100,6 +100,10 @@ public:
|
|||
{
|
||||
return this->Backtrace;
|
||||
}
|
||||
bool GetHadContextSensitiveCondition() const
|
||||
{
|
||||
return this->HadContextSensitiveCondition;
|
||||
}
|
||||
|
||||
private:
|
||||
cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace,
|
||||
|
@ -118,6 +122,7 @@ private:
|
|||
mutable std::set<cmTarget*> Targets;
|
||||
mutable std::map<cmStdString, cmStdString> SeenTargetProperties;
|
||||
mutable std::string Output;
|
||||
mutable bool HadContextSensitiveCondition;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,7 +24,33 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
|
|||
: Parent(parent), Target(target), Property(property),
|
||||
Content(content), Backtrace(backtrace)
|
||||
{
|
||||
const cmGeneratorExpressionDAGChecker *top = this;
|
||||
const cmGeneratorExpressionDAGChecker *p = this->Parent;
|
||||
while (p)
|
||||
{
|
||||
top = p;
|
||||
p = p->Parent;
|
||||
}
|
||||
this->CheckResult = this->checkGraph();
|
||||
|
||||
if (CheckResult == DAG && (top->Property == "INCLUDE_DIRECTORIES"
|
||||
|| top->Property == "COMPILE_DEFINITIONS") )
|
||||
{
|
||||
std::map<cmStdString, std::set<cmStdString> >::const_iterator it
|
||||
= top->Seen.find(target);
|
||||
if (it != top->Seen.end())
|
||||
{
|
||||
const std::set<cmStdString> &propSet = it->second;
|
||||
const std::set<cmStdString>::const_iterator i = propSet.find(property);
|
||||
if (i != propSet.end())
|
||||
{
|
||||
this->CheckResult = ALREADY_SEEN;
|
||||
return;
|
||||
}
|
||||
}
|
||||
const_cast<cmGeneratorExpressionDAGChecker *>(top)
|
||||
->Seen[target].insert(property);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -106,3 +132,38 @@ cmGeneratorExpressionDAGChecker::checkGraph() const
|
|||
}
|
||||
return DAG;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries()
|
||||
{
|
||||
const cmGeneratorExpressionDAGChecker *top = this;
|
||||
const cmGeneratorExpressionDAGChecker *parent = this->Parent;
|
||||
while (parent)
|
||||
{
|
||||
top = parent;
|
||||
parent = parent->Parent;
|
||||
}
|
||||
|
||||
const char *prop = top->Property.c_str();
|
||||
return (strcmp(prop, "LINK_LIBRARIES") == 0
|
||||
|| strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0
|
||||
|| strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0
|
||||
|| strncmp(prop, "LINK_INTERFACE_LIBRARIES_", 26) == 0
|
||||
|| strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 35) == 0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmGeneratorExpressionDAGChecker::EvaluatingIncludeDirectories()
|
||||
{
|
||||
const char *prop = this->Property.c_str();
|
||||
return (strcmp(prop, "INCLUDE_DIRECTORIES") == 0
|
||||
|| strcmp(prop, "INTERFACE_INCLUDE_DIRECTORIES") == 0 );
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmGeneratorExpressionDAGChecker::EvaluatingCompileDefinitions()
|
||||
{
|
||||
const char *prop = this->Property.c_str();
|
||||
return (strcmp(prop, "COMPILE_DEFINITIONS") == 0
|
||||
|| strcmp(prop, "INTERFACE_COMPILE_DEFINITIONS") == 0 );
|
||||
}
|
||||
|
|
|
@ -28,13 +28,19 @@ struct cmGeneratorExpressionDAGChecker
|
|||
enum Result {
|
||||
DAG,
|
||||
SELF_REFERENCE,
|
||||
CYCLIC_REFERENCE
|
||||
CYCLIC_REFERENCE,
|
||||
ALREADY_SEEN
|
||||
};
|
||||
|
||||
Result check() const;
|
||||
|
||||
void reportError(cmGeneratorExpressionContext *context,
|
||||
const std::string &expr);
|
||||
|
||||
bool EvaluatingLinkLibraries();
|
||||
bool EvaluatingIncludeDirectories();
|
||||
bool EvaluatingCompileDefinitions();
|
||||
|
||||
private:
|
||||
Result checkGraph() const;
|
||||
|
||||
|
@ -42,6 +48,7 @@ private:
|
|||
const cmGeneratorExpressionDAGChecker * const Parent;
|
||||
const std::string Target;
|
||||
const std::string Property;
|
||||
std::map<cmStdString, std::set<cmStdString> > Seen;
|
||||
const GeneratorExpressionContent * const Content;
|
||||
const cmListFileBacktrace Backtrace;
|
||||
Result CheckResult;
|
||||
|
|
|
@ -238,6 +238,7 @@ static const struct ConfigurationNode : public cmGeneratorExpressionNode
|
|||
const GeneratorExpressionContent *,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
context->HadContextSensitiveCondition = true;
|
||||
return context->Config ? context->Config : "";
|
||||
}
|
||||
} configurationNode;
|
||||
|
@ -262,6 +263,7 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
|
|||
"Expression syntax not recognized.");
|
||||
return std::string();
|
||||
}
|
||||
context->HadContextSensitiveCondition = true;
|
||||
if (!context->Config)
|
||||
{
|
||||
return parameters.front().empty() ? "1" : "0";
|
||||
|
@ -435,6 +437,9 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|||
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
|
||||
// No error. We just skip cyclic references.
|
||||
return std::string();
|
||||
case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
|
||||
// No error. We're not going to find anything new here.
|
||||
return std::string();
|
||||
case cmGeneratorExpressionDAGChecker::DAG:
|
||||
break;
|
||||
}
|
||||
|
@ -442,6 +447,39 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|||
const char *prop = target->GetProperty(propertyName.c_str());
|
||||
if (!prop)
|
||||
{
|
||||
if (target->IsImported())
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
if (dagCheckerParent && dagCheckerParent->EvaluatingLinkLibraries())
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
if (propertyName == "POSITION_INDEPENDENT_CODE")
|
||||
{
|
||||
context->HadContextSensitiveCondition = true;
|
||||
return target->GetLinkInterfaceDependentBoolProperty(
|
||||
"POSITION_INDEPENDENT_CODE", context->Config) ? "1" : "0";
|
||||
}
|
||||
if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
|
||||
context->Config))
|
||||
{
|
||||
context->HadContextSensitiveCondition = true;
|
||||
return target->GetLinkInterfaceDependentBoolProperty(
|
||||
propertyName,
|
||||
context->Config) ? "1" : "0";
|
||||
}
|
||||
if (target->IsLinkInterfaceDependentStringProperty(propertyName,
|
||||
context->Config))
|
||||
{
|
||||
context->HadContextSensitiveCondition = true;
|
||||
const char *propContent =
|
||||
target->GetLinkInterfaceDependentStringProperty(
|
||||
propertyName,
|
||||
context->Config);
|
||||
return propContent ? propContent : "";
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
@ -453,12 +491,19 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|||
if (targetPropertyTransitiveWhitelist[i] == propertyName)
|
||||
{
|
||||
cmGeneratorExpression ge(context->Backtrace);
|
||||
return ge.Parse(prop)->Evaluate(context->Makefile,
|
||||
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
|
||||
std::string result = cge->Evaluate(context->Makefile,
|
||||
context->Config,
|
||||
context->Quiet,
|
||||
context->HeadTarget,
|
||||
target,
|
||||
&dagChecker);
|
||||
|
||||
if (cge->GetHadContextSensitiveCondition())
|
||||
{
|
||||
context->HadContextSensitiveCondition = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return prop;
|
||||
|
@ -487,6 +532,221 @@ static const struct TargetNameNode : public cmGeneratorExpressionNode
|
|||
|
||||
} targetNameNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const char* targetPolicyWhitelist[] = {
|
||||
"CMP0003"
|
||||
, "CMP0004"
|
||||
, "CMP0008"
|
||||
, "CMP0020"
|
||||
};
|
||||
|
||||
cmPolicies::PolicyStatus statusForTarget(cmTarget *tgt, const char *policy)
|
||||
{
|
||||
#define RETURN_POLICY(POLICY) \
|
||||
if (strcmp(policy, #POLICY) == 0) \
|
||||
{ \
|
||||
return tgt->GetPolicyStatus ## POLICY (); \
|
||||
} \
|
||||
|
||||
RETURN_POLICY(CMP0003)
|
||||
RETURN_POLICY(CMP0004)
|
||||
RETURN_POLICY(CMP0008)
|
||||
RETURN_POLICY(CMP0020)
|
||||
|
||||
#undef RETURN_POLICY
|
||||
|
||||
assert("!Unreachable code. Not a valid policy");
|
||||
return cmPolicies::WARN;
|
||||
}
|
||||
|
||||
cmPolicies::PolicyID policyForString(const char *policy_id)
|
||||
{
|
||||
#define RETURN_POLICY_ID(POLICY_ID) \
|
||||
if (strcmp(policy_id, #POLICY_ID) == 0) \
|
||||
{ \
|
||||
return cmPolicies:: POLICY_ID; \
|
||||
} \
|
||||
|
||||
RETURN_POLICY_ID(CMP0003)
|
||||
RETURN_POLICY_ID(CMP0004)
|
||||
RETURN_POLICY_ID(CMP0008)
|
||||
RETURN_POLICY_ID(CMP0020)
|
||||
|
||||
#undef RETURN_POLICY_ID
|
||||
|
||||
assert("!Unreachable code. Not a valid policy");
|
||||
return cmPolicies::CMP0002;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct TargetPolicyNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
TargetPolicyNode() {}
|
||||
|
||||
virtual int NumExpectedParameters() const { return 1; }
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *context ,
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
if (!context->HeadTarget)
|
||||
{
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
"$<TARGET_POLICY:prop> may only be used with targets. It may not "
|
||||
"be used with add_custom_command.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
context->HadContextSensitiveCondition = true;
|
||||
|
||||
for (size_t i = 0;
|
||||
i < (sizeof(targetPolicyWhitelist) /
|
||||
sizeof(*targetPolicyWhitelist));
|
||||
++i)
|
||||
{
|
||||
const char *policy = targetPolicyWhitelist[i];
|
||||
if (parameters.front() == policy)
|
||||
{
|
||||
cmMakefile *mf = context->HeadTarget->GetMakefile();
|
||||
switch(statusForTarget(context->HeadTarget, policy))
|
||||
{
|
||||
case cmPolicies::WARN:
|
||||
mf->IssueMessage(cmake::AUTHOR_WARNING,
|
||||
mf->GetPolicies()->
|
||||
GetPolicyWarning(policyForString(policy)));
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::OLD:
|
||||
return "0";
|
||||
case cmPolicies::NEW:
|
||||
return "1";
|
||||
}
|
||||
}
|
||||
}
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
"$<TARGET_POLICY:prop> may only be used with a limited number of "
|
||||
"policies. Currently it may be used with policies CMP0003, CMP0004, "
|
||||
"CMP0008 and CMP0020."
|
||||
);
|
||||
return std::string();
|
||||
}
|
||||
|
||||
} targetPolicyNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct InstallPrefixNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
InstallPrefixNode() {}
|
||||
|
||||
virtual bool GeneratesContent() const { return true; }
|
||||
virtual int NumExpectedParameters() const { return 0; }
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> &,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
"INSTALL_PREFIX is a marker for install(EXPORT) only. It "
|
||||
"should never be evaluated.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
} installPrefixNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct LinkedNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
LinkedNode() {}
|
||||
|
||||
virtual bool GeneratesContent() const { return true; }
|
||||
virtual int NumExpectedParameters() const { return 1; }
|
||||
virtual bool RequiresLiteralInput() const { return true; }
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *dagChecker) const
|
||||
{
|
||||
if (dagChecker->EvaluatingIncludeDirectories())
|
||||
{
|
||||
return this->GetInterfaceProperty(parameters.front(),
|
||||
"INCLUDE_DIRECTORIES",
|
||||
context, content, dagChecker);
|
||||
}
|
||||
if (dagChecker->EvaluatingCompileDefinitions())
|
||||
{
|
||||
return this->GetInterfaceProperty(parameters.front(),
|
||||
"COMPILE_DEFINITIONS",
|
||||
context, content, dagChecker);
|
||||
}
|
||||
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
"$<LINKED:...> may only be used in INCLUDE_DIRECTORIES and "
|
||||
"COMPILE_DEFINITIONS properties.");
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string GetInterfaceProperty(const std::string &item,
|
||||
const std::string &prop,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *dagCheckerParent) const
|
||||
{
|
||||
cmTarget *target = context->CurrentTarget
|
||||
->GetMakefile()->FindTargetToUse(item.c_str());
|
||||
if (!target)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
std::string propertyName = "INTERFACE_" + prop;
|
||||
const char *propContent = target->GetProperty(propertyName.c_str());
|
||||
if (!propContent)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace,
|
||||
target->GetName(),
|
||||
propertyName,
|
||||
content,
|
||||
dagCheckerParent);
|
||||
|
||||
switch (dagChecker.check())
|
||||
{
|
||||
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
|
||||
dagChecker.reportError(context, content->GetOriginalExpression());
|
||||
return std::string();
|
||||
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
|
||||
// No error. We just skip cyclic references.
|
||||
return std::string();
|
||||
case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
|
||||
// No error. We're not going to find anything new here.
|
||||
return std::string();
|
||||
case cmGeneratorExpressionDAGChecker::DAG:
|
||||
break;
|
||||
}
|
||||
|
||||
cmGeneratorExpression ge(context->Backtrace);
|
||||
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(propContent);
|
||||
std::string result = cge->Evaluate(context->Makefile,
|
||||
context->Config,
|
||||
context->Quiet,
|
||||
context->HeadTarget,
|
||||
target,
|
||||
&dagChecker);
|
||||
if (cge->GetHadContextSensitiveCondition())
|
||||
{
|
||||
context->HadContextSensitiveCondition = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} linkedNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<bool linker, bool soname>
|
||||
struct TargetFilesystemArtifactResultCreator
|
||||
|
@ -714,12 +974,18 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
|
|||
return &targetPropertyNode;
|
||||
else if (identifier == "TARGET_NAME")
|
||||
return &targetNameNode;
|
||||
else if (identifier == "TARGET_POLICY")
|
||||
return &targetPolicyNode;
|
||||
else if (identifier == "BUILD_INTERFACE")
|
||||
return &buildInterfaceNode;
|
||||
else if (identifier == "INSTALL_INTERFACE")
|
||||
return &installInterfaceNode;
|
||||
else if (identifier == "TARGET_DEFINED")
|
||||
return &targetDefinedNode;
|
||||
else if (identifier == "INSTALL_PREFIX")
|
||||
return &installPrefixNode;
|
||||
else if (identifier == "LINKED")
|
||||
return &linkedNode;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ struct cmGeneratorExpressionContext
|
|||
// directly or indirectly in the property.
|
||||
bool Quiet;
|
||||
bool HadError;
|
||||
bool HadContextSensitiveCondition;
|
||||
};
|
||||
|
||||
struct cmGeneratorExpressionDAGChecker;
|
||||
|
|
|
@ -254,32 +254,3 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
|
|||
{
|
||||
return this->Target->GetIncludeDirectories(config);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmGeneratorTarget::GetCompileDefinitions(const char *config)
|
||||
{
|
||||
std::string defPropName = "COMPILE_DEFINITIONS";
|
||||
if (config)
|
||||
{
|
||||
defPropName += "_" + cmSystemTools::UpperCase(config);
|
||||
}
|
||||
|
||||
const char *prop = this->Target->GetProperty(defPropName.c_str());
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
cmListFileBacktrace lfbt;
|
||||
cmGeneratorExpression ge(lfbt);
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
|
||||
this->GetName(),
|
||||
defPropName, 0, 0);
|
||||
return ge.Parse(prop)->Evaluate(this->Makefile,
|
||||
config,
|
||||
false,
|
||||
this->Target,
|
||||
&dagChecker);
|
||||
}
|
||||
|
|
|
@ -68,8 +68,6 @@ public:
|
|||
/** Get the include directories for this target. */
|
||||
std::vector<std::string> GetIncludeDirectories(const char *config);
|
||||
|
||||
std::string GetCompileDefinitions(const char *config = 0);
|
||||
|
||||
private:
|
||||
void ClassifySources();
|
||||
void LookupObjectLibraries();
|
||||
|
|
|
@ -994,6 +994,7 @@ void cmGlobalGenerator::Generate()
|
|||
// Generate project files
|
||||
for (i = 0; i < this->LocalGenerators.size(); ++i)
|
||||
{
|
||||
this->LocalGenerators[i]->GetMakefile()->SetGeneratingBuildSystem();
|
||||
this->SetCurrentLocalGenerator(this->LocalGenerators[i]);
|
||||
this->LocalGenerators[i]->Generate();
|
||||
this->LocalGenerators[i]->GenerateInstallRules();
|
||||
|
@ -1077,7 +1078,8 @@ void cmGlobalGenerator::CreateAutomocTargets()
|
|||
if(target.GetType() == cmTarget::EXECUTABLE ||
|
||||
target.GetType() == cmTarget::STATIC_LIBRARY ||
|
||||
target.GetType() == cmTarget::SHARED_LIBRARY ||
|
||||
target.GetType() == cmTarget::MODULE_LIBRARY)
|
||||
target.GetType() == cmTarget::MODULE_LIBRARY ||
|
||||
target.GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported())
|
||||
{
|
||||
|
|
|
@ -1700,11 +1700,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||
this->AppendDefines(ppDefs, exportMacro);
|
||||
}
|
||||
cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
|
||||
this->AppendDefines(ppDefs, gtgt->GetCompileDefinitions().c_str());
|
||||
this->AppendDefines(ppDefs, target.GetCompileDefinitions().c_str());
|
||||
if(configName)
|
||||
{
|
||||
this->AppendDefines(ppDefs,
|
||||
gtgt->GetCompileDefinitions(configName).c_str());
|
||||
target.GetCompileDefinitions(configName).c_str());
|
||||
}
|
||||
buildSettings->AddAttribute
|
||||
("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList());
|
||||
|
|
|
@ -36,6 +36,10 @@ bool cmIncludeDirectoryCommand
|
|||
++i;
|
||||
}
|
||||
|
||||
std::vector<std::string> beforeIncludes;
|
||||
std::vector<std::string> afterIncludes;
|
||||
std::set<cmStdString> systemIncludes;
|
||||
|
||||
for(; i != args.end(); ++i)
|
||||
{
|
||||
if(*i == "SYSTEM")
|
||||
|
@ -49,9 +53,37 @@ bool cmIncludeDirectoryCommand
|
|||
return false;
|
||||
}
|
||||
|
||||
this->AddDirectory(i->c_str(),before,system);
|
||||
std::vector<std::string> includes;
|
||||
|
||||
GetIncludes(*i, includes);
|
||||
|
||||
if (before)
|
||||
{
|
||||
beforeIncludes.insert(beforeIncludes.end(),
|
||||
includes.begin(),
|
||||
includes.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
afterIncludes.insert(afterIncludes.end(),
|
||||
includes.begin(),
|
||||
includes.end());
|
||||
}
|
||||
if (system)
|
||||
{
|
||||
for (std::vector<std::string>::const_iterator li = includes.begin();
|
||||
li != includes.end(); ++li)
|
||||
{
|
||||
systemIncludes.insert(*li);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::reverse(beforeIncludes.begin(), beforeIncludes.end());
|
||||
|
||||
this->Makefile->AddIncludeDirectories(afterIncludes);
|
||||
this->Makefile->AddIncludeDirectories(beforeIncludes, before);
|
||||
this->Makefile->AddSystemIncludeDirectories(systemIncludes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -72,57 +104,49 @@ static bool StartsWithGeneratorExpression(const std::string &input)
|
|||
// output from a program and passing it into a command the cleanup doesn't
|
||||
// always happen
|
||||
//
|
||||
void cmIncludeDirectoryCommand::AddDirectory(const char *i,
|
||||
bool before,
|
||||
bool system)
|
||||
void cmIncludeDirectoryCommand::GetIncludes(const std::string &arg,
|
||||
std::vector<std::string> &incs)
|
||||
{
|
||||
// break apart any line feed arguments
|
||||
std::string ret = i;
|
||||
std::string::size_type pos = 0;
|
||||
if((pos = ret.find('\n', pos)) != std::string::npos)
|
||||
std::string::size_type lastPos = 0;
|
||||
while((pos = arg.find('\n', lastPos)) != std::string::npos)
|
||||
{
|
||||
if (pos)
|
||||
{
|
||||
this->AddDirectory(ret.substr(0,pos).c_str(), before, system);
|
||||
std::string inc = arg.substr(lastPos,pos);
|
||||
NormalizeInclude(inc);
|
||||
incs.push_back(inc);
|
||||
}
|
||||
if (ret.size()-pos-1)
|
||||
{
|
||||
this->AddDirectory(ret.substr(pos+1,ret.size()-pos-1).c_str(),
|
||||
before, system);
|
||||
}
|
||||
return;
|
||||
lastPos = pos + 1;
|
||||
}
|
||||
std::string inc = arg.substr(lastPos);
|
||||
NormalizeInclude(inc);
|
||||
incs.push_back(inc);
|
||||
}
|
||||
|
||||
void cmIncludeDirectoryCommand::NormalizeInclude(std::string &inc)
|
||||
{
|
||||
std::string::size_type b = inc.find_first_not_of(" \r");
|
||||
std::string::size_type e = inc.find_last_not_of(" \r");
|
||||
if ((b!=inc.npos) && (e!=inc.npos))
|
||||
{
|
||||
inc.assign(inc, b, 1+e-b); // copy the remaining substring
|
||||
}
|
||||
|
||||
// remove any leading or trailing spaces and \r
|
||||
std::string::size_type b = ret.find_first_not_of(" \r");
|
||||
std::string::size_type e = ret.find_last_not_of(" \r");
|
||||
if ((b!=ret.npos) && (e!=ret.npos))
|
||||
if (!cmSystemTools::IsOff(inc.c_str()))
|
||||
{
|
||||
ret.assign(ret, b, 1+e-b); // copy the remaining substring
|
||||
}
|
||||
else
|
||||
{
|
||||
return; // if we get here, we had only whitespace in the string
|
||||
}
|
||||
cmSystemTools::ConvertToUnixSlashes(inc);
|
||||
|
||||
if (!cmSystemTools::IsOff(ret.c_str()))
|
||||
{
|
||||
cmSystemTools::ConvertToUnixSlashes(ret);
|
||||
if(!cmSystemTools::FileIsFullPath(ret.c_str()))
|
||||
if(!cmSystemTools::FileIsFullPath(inc.c_str()))
|
||||
{
|
||||
if(!StartsWithGeneratorExpression(ret))
|
||||
if(!StartsWithGeneratorExpression(inc))
|
||||
{
|
||||
std::string tmp = this->Makefile->GetStartDirectory();
|
||||
tmp += "/";
|
||||
tmp += ret;
|
||||
ret = tmp;
|
||||
tmp += inc;
|
||||
inc = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
this->Makefile->AddIncludeDirectory(ret.c_str(), before);
|
||||
if(system)
|
||||
{
|
||||
this->Makefile->AddSystemIncludeDirectory(ret.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,8 +59,9 @@ public:
|
|||
return
|
||||
" include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)\n"
|
||||
"Add the given directories to those the compiler uses to search "
|
||||
"for include files. "
|
||||
"These directories are added to the directory property "
|
||||
"for include files. Relative paths are interpreted as relative to "
|
||||
"the current source directory. \n"
|
||||
"The include directories are added to the directory property "
|
||||
"INCLUDE_DIRECTORIES for the current CMakeLists file. "
|
||||
"They are also added to the target property INCLUDE_DIRECTORIES "
|
||||
"for each target in the current CMakeLists file. "
|
||||
|
@ -84,7 +85,8 @@ public:
|
|||
|
||||
protected:
|
||||
// used internally
|
||||
void AddDirectory(const char *arg, bool before, bool system);
|
||||
void GetIncludes(const std::string &arg, std::vector<std::string> &incs);
|
||||
void NormalizeInclude(std::string &inc);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -62,10 +62,8 @@ public:
|
|||
" link_directories(directory1 directory2 ...)\n"
|
||||
"Specify the paths in which the linker should search for libraries. "
|
||||
"The command will apply only to targets created after it is called. "
|
||||
"For historical reasons, relative paths given to this command are "
|
||||
"passed to the linker unchanged "
|
||||
"(unlike many CMake commands which interpret them relative to the "
|
||||
"current source directory).\n"
|
||||
"Relative paths given to this command are interpreted as relative to "
|
||||
"the current source directory, see CMP0015. \n"
|
||||
"Note that this command is rarely necessary. Library locations "
|
||||
"returned by find_package() and find_library() are absolute paths. "
|
||||
"Pass these absolute library file paths directly to the "
|
||||
|
|
|
@ -325,6 +325,9 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
|
|||
if(!cmSystemTools::FileExists(source.c_str()))
|
||||
{
|
||||
cmSystemTools::ReplaceString(source, "$(IntDir)/", "");
|
||||
// Make sure the path exists for the file
|
||||
std::string path = cmSystemTools::GetFilenamePath(source);
|
||||
cmSystemTools::MakeDirectory(path.c_str());
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
std::ofstream sourceFout(source.c_str(),
|
||||
std::ios::binary | std::ios::out
|
||||
|
@ -1697,25 +1700,21 @@ void cmLocalVisualStudio6Generator
|
|||
std::set<std::string> minsizeDefinesSet;
|
||||
std::set<std::string> debugrelDefinesSet;
|
||||
|
||||
|
||||
cmGeneratorTarget* gt =
|
||||
this->GlobalGenerator->GetGeneratorTarget(&target);
|
||||
|
||||
this->AppendDefines(
|
||||
definesSet,
|
||||
gt->GetCompileDefinitions());
|
||||
target.GetCompileDefinitions());
|
||||
this->AppendDefines(
|
||||
debugDefinesSet,
|
||||
gt->GetCompileDefinitions("DEBUG"));
|
||||
target.GetCompileDefinitions("DEBUG"));
|
||||
this->AppendDefines(
|
||||
releaseDefinesSet,
|
||||
gt->GetCompileDefinitions("RELEASE"));
|
||||
target.GetCompileDefinitions("RELEASE"));
|
||||
this->AppendDefines(
|
||||
minsizeDefinesSet,
|
||||
gt->GetCompileDefinitions("MINSIZEREL"));
|
||||
target.GetCompileDefinitions("MINSIZEREL"));
|
||||
this->AppendDefines(
|
||||
debugrelDefinesSet,
|
||||
gt->GetCompileDefinitions("RELWITHDEBINFO"));
|
||||
target.GetCompileDefinitions("RELWITHDEBINFO"));
|
||||
|
||||
std::string defines = " ";
|
||||
std::string debugDefines = " ";
|
||||
|
|
|
@ -745,8 +745,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
|
|||
targetOptions.ParseFinish();
|
||||
cmGeneratorTarget* gt =
|
||||
this->GlobalGenerator->GetGeneratorTarget(&target);
|
||||
targetOptions.AddDefines(gt->GetCompileDefinitions().c_str());
|
||||
targetOptions.AddDefines(gt->GetCompileDefinitions(configName).c_str());
|
||||
targetOptions.AddDefines(target.GetCompileDefinitions().c_str());
|
||||
targetOptions.AddDefines(target.GetCompileDefinitions(configName).c_str());
|
||||
targetOptions.SetVerboseMakefile(
|
||||
this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
|
||||
|
||||
|
|
|
@ -99,6 +99,7 @@ cmMakefile::cmMakefile(): Internal(new Internals)
|
|||
this->AddDefaultDefinitions();
|
||||
this->Initialize();
|
||||
this->PreOrder = false;
|
||||
this->GeneratingBuildSystem = false;
|
||||
}
|
||||
|
||||
cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals)
|
||||
|
@ -1616,20 +1617,31 @@ void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
|
||||
void cmMakefile::AddIncludeDirectories(const std::vector<std::string> &incs,
|
||||
bool before)
|
||||
{
|
||||
if (!inc)
|
||||
if (incs.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::string incString;
|
||||
std::string sep;
|
||||
|
||||
for(std::vector<std::string>::const_iterator li = incs.begin();
|
||||
li != incs.end(); ++li)
|
||||
{
|
||||
incString += sep + *li;
|
||||
sep = ";";
|
||||
}
|
||||
|
||||
std::vector<IncludeDirectoriesEntry>::iterator position =
|
||||
before ? this->IncludeDirectoriesEntries.begin()
|
||||
: this->IncludeDirectoriesEntries.end();
|
||||
before ? this->IncludeDirectoriesEntries.begin()
|
||||
: this->IncludeDirectoriesEntries.end();
|
||||
|
||||
cmListFileBacktrace lfbt;
|
||||
this->GetBacktrace(lfbt);
|
||||
IncludeDirectoriesEntry entry(inc, lfbt);
|
||||
IncludeDirectoriesEntry entry(incString, lfbt);
|
||||
this->IncludeDirectoriesEntries.insert(position, entry);
|
||||
|
||||
// Property on each target:
|
||||
|
@ -1642,9 +1654,14 @@ void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmMakefile::AddSystemIncludeDirectory(const char* dir)
|
||||
void
|
||||
cmMakefile::AddSystemIncludeDirectories(const std::set<cmStdString> &incs)
|
||||
{
|
||||
this->SystemIncludeDirectories.insert(dir);
|
||||
for(std::set<cmStdString>::const_iterator li = incs.begin();
|
||||
li != incs.end(); ++li)
|
||||
{
|
||||
this->SystemIncludeDirectories.insert(*li);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -2243,7 +2260,7 @@ bool cmMakefile::CanIWriteThisFile(const char* fileName)
|
|||
{
|
||||
return true;
|
||||
}
|
||||
// If we are doing an in-source build, than the test will always fail
|
||||
// If we are doing an in-source build, then the test will always fail
|
||||
if ( cmSystemTools::SameFile(this->GetHomeDirectory(),
|
||||
this->GetHomeOutputDirectory()) )
|
||||
{
|
||||
|
@ -2254,8 +2271,8 @@ bool cmMakefile::CanIWriteThisFile(const char* fileName)
|
|||
return true;
|
||||
}
|
||||
|
||||
// Check if this is subdirectory of the source tree but not a
|
||||
// subdirectory of a build tree
|
||||
// Check if this is a subdirectory of the source tree but not a
|
||||
// subdirectory of the build tree
|
||||
if ( cmSystemTools::IsSubDirectory(fileName,
|
||||
this->GetHomeDirectory()) &&
|
||||
!cmSystemTools::IsSubDirectory(fileName,
|
||||
|
|
|
@ -287,7 +287,8 @@ public:
|
|||
/**
|
||||
* Add an include directory to the build.
|
||||
*/
|
||||
void AddIncludeDirectory(const char*, bool before = false);
|
||||
void AddIncludeDirectories(const std::vector<std::string> &incs,
|
||||
bool before = false);
|
||||
|
||||
/**
|
||||
* Add a variable definition to the build. This variable
|
||||
|
@ -545,7 +546,7 @@ public:
|
|||
/**
|
||||
* Mark include directories as system directories.
|
||||
*/
|
||||
void AddSystemIncludeDirectory(const char* dir);
|
||||
void AddSystemIncludeDirectories(const std::set<cmStdString> &incs);
|
||||
bool IsSystemIncludeDirectory(const char* dir);
|
||||
|
||||
/** Expand out any arguements in the vector that have ; separated
|
||||
|
@ -869,6 +870,9 @@ public:
|
|||
return this->IncludeDirectoriesEntries;
|
||||
}
|
||||
|
||||
bool IsGeneratingBuildSystem(){ return this->GeneratingBuildSystem; }
|
||||
void SetGeneratingBuildSystem(){ this->GeneratingBuildSystem = true; }
|
||||
|
||||
protected:
|
||||
// add link libraries and directories to the target
|
||||
void AddGlobalLinkInformation(const char* name, cmTarget& target);
|
||||
|
@ -1018,6 +1022,9 @@ private:
|
|||
|
||||
// Enforce rules about CMakeLists.txt files.
|
||||
void EnforceDirectoryLevelRules();
|
||||
|
||||
bool GeneratingBuildSystem;
|
||||
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -303,10 +303,10 @@ std::string cmMakefileTargetGenerator::GetDefines(const std::string &l)
|
|||
|
||||
// Add preprocessor definitions for this target and configuration.
|
||||
this->LocalGenerator->AppendDefines
|
||||
(defines, this->GeneratorTarget->GetCompileDefinitions());
|
||||
(defines, this->Target->GetCompileDefinitions());
|
||||
|
||||
this->LocalGenerator->AppendDefines
|
||||
(defines, this->GeneratorTarget->GetCompileDefinitions(
|
||||
(defines, this->Target->GetCompileDefinitions(
|
||||
this->LocalGenerator->ConfigurationName.c_str()));
|
||||
|
||||
std::string definesString;
|
||||
|
|
|
@ -190,7 +190,7 @@ cmNinjaNormalTargetGenerator
|
|||
linkOptionVar += cmTarget::GetTargetTypeName(targetType);
|
||||
const std::string linkOption =
|
||||
GetMakefile()->GetSafeDefinition(linkOptionVar.c_str());
|
||||
rspcontent = "$in " + linkOption + " $LINK_PATH $LINK_LIBRARIES";
|
||||
rspcontent = "$in_newline "+linkOption+" $LINK_PATH $LINK_LIBRARIES";
|
||||
vars.Objects = responseFlag.c_str();
|
||||
vars.LinkLibraries = "";
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@ ComputeDefines(cmSourceFile *source, const std::string& language)
|
|||
// Add preprocessor definitions for this target and configuration.
|
||||
this->LocalGenerator->AppendDefines
|
||||
(defines,
|
||||
this->GeneratorTarget->GetCompileDefinitions());
|
||||
this->Target->GetCompileDefinitions());
|
||||
this->LocalGenerator->AppendDefines
|
||||
(defines,
|
||||
source->GetProperty("COMPILE_DEFINITIONS"));
|
||||
|
@ -237,7 +237,7 @@ ComputeDefines(cmSourceFile *source, const std::string& language)
|
|||
defPropName += cmSystemTools::UpperCase(this->GetConfigName());
|
||||
this->LocalGenerator->AppendDefines
|
||||
(defines,
|
||||
this->GeneratorTarget->GetCompileDefinitions(this->GetConfigName()));
|
||||
this->Target->GetCompileDefinitions(this->GetConfigName()));
|
||||
this->LocalGenerator->AppendDefines
|
||||
(defines,
|
||||
source->GetProperty(defPropName.c_str()));
|
||||
|
|
|
@ -508,6 +508,27 @@ cmPolicies::cmPolicies()
|
|||
"for strict compatibility. "
|
||||
"The NEW behavior for this policy is to leave the values untouched.",
|
||||
2,8,11,0, cmPolicies::WARN);
|
||||
|
||||
this->DefinePolicy(
|
||||
CMP0020, "CMP0020",
|
||||
"Automatically link Qt executables to qtmain target on Windows.",
|
||||
"CMake 2.8.10 and lower required users of Qt to always specify a link "
|
||||
"dependency to the qtmain.lib static library manually on Windows. CMake "
|
||||
"2.8.11 gained the ability to evaluate generator expressions while "
|
||||
"determining the link dependencies from IMPORTED targets. This allows "
|
||||
"CMake itself to automatically link executables which link to Qt to the "
|
||||
"qtmain.lib library when using IMPORTED Qt targets. For applications "
|
||||
"already linking to qtmain.lib, this should have little impact. For "
|
||||
"applications which supply their own alternative WinMain implementation "
|
||||
"and for applications which use the QAxServer library, this automatic "
|
||||
"linking will need to be disabled as per the documentation."
|
||||
"\n"
|
||||
"The OLD behavior for this policy is not to link executables to "
|
||||
"qtmain.lib automatically when they link to the QtCore IMPORTED"
|
||||
"target. "
|
||||
"The NEW behavior for this policy is to link executables to "
|
||||
"qtmain.lib automatically when they link to QtCore IMPORTED target.",
|
||||
2,8,11,0, cmPolicies::WARN);
|
||||
}
|
||||
|
||||
cmPolicies::~cmPolicies()
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
/// POSITION_INDEPENDENT_CODE property and *_COMPILE_OPTIONS_PI{E,C}
|
||||
/// instead.
|
||||
CMP0019, ///< No variable re-expansion in include and link info
|
||||
CMP0020, ///< Automatically link Qt executables to qtmain target
|
||||
|
||||
/** \brief Always the last entry.
|
||||
*
|
||||
|
|
|
@ -229,7 +229,11 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
|
|||
}
|
||||
|
||||
const char* tmp = target->GetProperty("COMPILE_DEFINITIONS");
|
||||
std::string _moc_compile_defs = (tmp!=0 ? tmp : "");
|
||||
std::string _moc_compile_defs;
|
||||
if (tmp)
|
||||
{
|
||||
_moc_compile_defs = target->GetCompileDefinitions();
|
||||
}
|
||||
tmp = makefile->GetProperty("COMPILE_DEFINITIONS");
|
||||
if (tmp)
|
||||
{
|
||||
|
|
|
@ -1180,46 +1180,35 @@ bool cmSystemTools::CopyFileIfDifferent(const char* source,
|
|||
bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
/* On Windows the move functions will not replace existing files.
|
||||
Check if the destination exists. */
|
||||
struct stat newFile;
|
||||
if(stat(newname, &newFile) == 0)
|
||||
# ifndef INVALID_FILE_ATTRIBUTES
|
||||
# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
|
||||
# endif
|
||||
/* Windows MoveFileEx may not replace read-only or in-use files. If it
|
||||
fails then remove the read-only attribute from any existing destination.
|
||||
Try multiple times since we may be racing against another process
|
||||
creating/opening the destination file just before our MoveFileEx. */
|
||||
int tries = 5;
|
||||
while(!MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) && --tries)
|
||||
{
|
||||
/* The destination exists. We have to replace it carefully. The
|
||||
MoveFileEx function does what we need but is not available on
|
||||
Win9x. */
|
||||
OSVERSIONINFO osv;
|
||||
DWORD attrs;
|
||||
|
||||
/* Make sure the destination is not read only. */
|
||||
attrs = GetFileAttributes(newname);
|
||||
if(attrs & FILE_ATTRIBUTE_READONLY)
|
||||
// Try again only if failure was due to access permissions.
|
||||
if(GetLastError() != ERROR_ACCESS_DENIED)
|
||||
{
|
||||
SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check the windows version number. */
|
||||
osv.dwOSVersionInfoSize = sizeof(osv);
|
||||
GetVersionEx(&osv);
|
||||
if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
|
||||
DWORD attrs = GetFileAttributes(newname);
|
||||
if((attrs != INVALID_FILE_ATTRIBUTES) &&
|
||||
(attrs & FILE_ATTRIBUTE_READONLY))
|
||||
{
|
||||
/* This is Win9x. There is no MoveFileEx implementation. We
|
||||
cannot quite rename the file atomically. Just delete the
|
||||
destination and then move the file. */
|
||||
DeleteFile(newname);
|
||||
return MoveFile(oldname, newname) != 0;
|
||||
// Remove the read-only attribute from the destination file.
|
||||
SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is not Win9x. Use the MoveFileEx implementation. */
|
||||
return MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) != 0;
|
||||
// The file may be temporarily in use so wait a bit.
|
||||
cmSystemTools::Delay(100);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The destination does not exist. Just move the file. */
|
||||
return MoveFile(oldname, newname) != 0;
|
||||
}
|
||||
return tries > 0;
|
||||
#else
|
||||
/* On UNIX we have an OS-provided call to do this atomically. */
|
||||
return rename(oldname, newname) == 0;
|
||||
|
|
|
@ -134,6 +134,7 @@ public:
|
|||
: ge(cge)
|
||||
{}
|
||||
const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
|
||||
std::vector<std::string> CachedIncludes;
|
||||
};
|
||||
std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries;
|
||||
};
|
||||
|
@ -145,12 +146,14 @@ cmTarget::cmTarget()
|
|||
this->PolicyStatusCMP0003 = cmPolicies::WARN;
|
||||
this->PolicyStatusCMP0004 = cmPolicies::WARN;
|
||||
this->PolicyStatusCMP0008 = cmPolicies::WARN;
|
||||
this->PolicyStatusCMP0020 = cmPolicies::WARN;
|
||||
this->LinkLibrariesAnalyzed = false;
|
||||
this->HaveInstallRule = false;
|
||||
this->DLLPlatform = false;
|
||||
this->IsApple = false;
|
||||
this->IsImportedTarget = false;
|
||||
this->BuildInterfaceIncludesAppended = false;
|
||||
this->DebugIncludesDone = false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -905,6 +908,17 @@ void cmTarget::DefineProperties(cmake *cm)
|
|||
"then it must have the same boolean value as all others, and if the "
|
||||
"property is not set, then it is ignored.");
|
||||
|
||||
cm->DefineProperty
|
||||
("COMPATIBLE_INTERFACE_STRING", cmProperty::TARGET,
|
||||
"Properties which must be string-compatible with their link interface",
|
||||
"The COMPATIBLE_INTERFACE_STRING property may contain a list of "
|
||||
"properties for this target which must be the same when evaluated as "
|
||||
"a string in the INTERFACE of all linked dependencies. For example, "
|
||||
"if a property \"FOO\" appears in the list, then the \"INTERFACE_FOO\" "
|
||||
"property content in all dependencies must be equal with each "
|
||||
"other, and with the \"FOO\" property in this target. If the "
|
||||
"property is not set, then it is ignored.");
|
||||
|
||||
cm->DefineProperty
|
||||
("POST_INSTALL_SCRIPT", cmProperty::TARGET,
|
||||
"Deprecated install support.",
|
||||
|
@ -1499,6 +1513,8 @@ void cmTarget::SetMakefile(cmMakefile* mf)
|
|||
this->Makefile->GetPolicyStatus(cmPolicies::CMP0004);
|
||||
this->PolicyStatusCMP0008 =
|
||||
this->Makefile->GetPolicyStatus(cmPolicies::CMP0008);
|
||||
this->PolicyStatusCMP0020 =
|
||||
this->Makefile->GetPolicyStatus(cmPolicies::CMP0020);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -1520,6 +1536,13 @@ void cmTarget::ClearLinkMaps()
|
|||
this->Internal->LinkImplMap.clear();
|
||||
this->Internal->LinkInterfaceMap.clear();
|
||||
this->Internal->LinkClosureMap.clear();
|
||||
for (cmTargetLinkInformationMap::const_iterator it
|
||||
= this->LinkInformation.begin();
|
||||
it != this->LinkInformation.end(); ++it)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
this->LinkInformation.clear();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -2269,8 +2292,9 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
|
|||
cmTarget *tgt = this->Makefile->FindTargetToUse(lib);
|
||||
const bool isNonImportedTarget = tgt && !tgt->IsImported();
|
||||
|
||||
std::string libName = isNonImportedTarget ? targetNameGenex(lib)
|
||||
: std::string(lib);
|
||||
const std::string libName = (isNonImportedTarget && llt != GENERAL)
|
||||
? targetNameGenex(lib)
|
||||
: std::string(lib);
|
||||
this->AppendProperty("LINK_LIBRARIES",
|
||||
this->GetDebugGeneratorExpressions(libName,
|
||||
llt).c_str());
|
||||
|
@ -2739,52 +2763,105 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
|
|||
cmSystemTools::ExpandListArgument(debugProp, debugProperties);
|
||||
}
|
||||
|
||||
bool debugIncludes = std::find(debugProperties.begin(),
|
||||
bool debugIncludes = !this->DebugIncludesDone
|
||||
&& std::find(debugProperties.begin(),
|
||||
debugProperties.end(),
|
||||
"INCLUDE_DIRECTORIES")
|
||||
!= debugProperties.end();
|
||||
|
||||
if (this->Makefile->IsGeneratingBuildSystem())
|
||||
{
|
||||
this->DebugIncludesDone = true;
|
||||
}
|
||||
|
||||
for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator
|
||||
it = this->Internal->IncludeDirectoriesEntries.begin(),
|
||||
end = this->Internal->IncludeDirectoriesEntries.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
std::vector<std::string> entryIncludes;
|
||||
cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile,
|
||||
config,
|
||||
false,
|
||||
this,
|
||||
&dagChecker),
|
||||
entryIncludes);
|
||||
|
||||
bool testIsOff = true;
|
||||
bool cacheIncludes = false;
|
||||
std::vector<std::string> entryIncludes = (*it)->CachedIncludes;
|
||||
if(!entryIncludes.empty())
|
||||
{
|
||||
testIsOff = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile,
|
||||
config,
|
||||
false,
|
||||
this,
|
||||
&dagChecker),
|
||||
entryIncludes);
|
||||
if (!(*it)->ge->GetHadContextSensitiveCondition())
|
||||
{
|
||||
cacheIncludes = true;
|
||||
}
|
||||
}
|
||||
std::string usedIncludes;
|
||||
for(std::vector<std::string>::const_iterator
|
||||
for(std::vector<std::string>::iterator
|
||||
li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
|
||||
{
|
||||
std::string inc = *li;
|
||||
if (!cmSystemTools::IsOff(inc.c_str()))
|
||||
if (testIsOff && !cmSystemTools::IsOff(li->c_str()))
|
||||
{
|
||||
cmSystemTools::ConvertToUnixSlashes(inc);
|
||||
cmSystemTools::ConvertToUnixSlashes(*li);
|
||||
}
|
||||
std::string inc = *li;
|
||||
|
||||
if(uniqueIncludes.insert(inc).second)
|
||||
{
|
||||
includes.push_back(*li);
|
||||
includes.push_back(inc);
|
||||
if (debugIncludes)
|
||||
{
|
||||
usedIncludes += " * " + *li + "\n";
|
||||
usedIncludes += " * " + inc + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cacheIncludes)
|
||||
{
|
||||
(*it)->CachedIncludes = entryIncludes;
|
||||
}
|
||||
if (!usedIncludes.empty())
|
||||
{
|
||||
this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG,
|
||||
"Used includes:\n" + usedIncludes,
|
||||
(*it)->ge->GetBacktrace());
|
||||
"Used includes for target " + this->Name + ":\n"
|
||||
+ usedIncludes, (*it)->ge->GetBacktrace());
|
||||
}
|
||||
}
|
||||
return includes;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmTarget::GetCompileDefinitions(const char *config)
|
||||
{
|
||||
std::string defPropName = "COMPILE_DEFINITIONS";
|
||||
if (config)
|
||||
{
|
||||
defPropName += "_" + cmSystemTools::UpperCase(config);
|
||||
}
|
||||
|
||||
const char *prop = this->GetProperty(defPropName.c_str());
|
||||
|
||||
if (!prop)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
cmListFileBacktrace lfbt;
|
||||
cmGeneratorExpression ge(lfbt);
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
|
||||
this->GetName(),
|
||||
defPropName, 0, 0);
|
||||
return ge.Parse(prop)->Evaluate(this->Makefile,
|
||||
config,
|
||||
false,
|
||||
this,
|
||||
&dagChecker);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::MaybeInvalidatePropertyCache(const char* prop)
|
||||
{
|
||||
|
@ -4482,22 +4559,69 @@ void cmTarget::AddLinkDependentTargetsForProperties(
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||
const char *config)
|
||||
template<typename PropertyType>
|
||||
PropertyType getTypedProperty(cmTarget *tgt, const char *prop,
|
||||
PropertyType *);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<>
|
||||
bool getTypedProperty<bool>(cmTarget *tgt, const char *prop, bool *)
|
||||
{
|
||||
bool propContent = this->GetPropertyAsBool(p.c_str());
|
||||
const bool explicitlySet = this->GetProperties()
|
||||
return tgt->GetPropertyAsBool(prop);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<>
|
||||
const char *getTypedProperty<const char *>(cmTarget *tgt, const char *prop,
|
||||
const char **)
|
||||
{
|
||||
return tgt->GetProperty(prop);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename PropertyType>
|
||||
bool consistentProperty(PropertyType lhs, PropertyType rhs);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<>
|
||||
bool consistentProperty(bool lhs, bool rhs)
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<>
|
||||
bool consistentProperty(const char *lhs, const char *rhs)
|
||||
{
|
||||
if (!lhs && !rhs)
|
||||
return true;
|
||||
if (!lhs || !rhs)
|
||||
return false;
|
||||
return strcmp(lhs, rhs) == 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename PropertyType>
|
||||
PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
|
||||
const std::string &p,
|
||||
const char *config,
|
||||
const char *defaultValue,
|
||||
PropertyType *)
|
||||
{
|
||||
PropertyType propContent = getTypedProperty<PropertyType>(tgt, p.c_str(),
|
||||
0);
|
||||
const bool explicitlySet = tgt->GetProperties()
|
||||
.find(p.c_str())
|
||||
!= this->GetProperties().end();
|
||||
!= tgt->GetProperties().end();
|
||||
std::set<std::string> dependentTargets;
|
||||
this->GetLinkDependentTargetsForProperty(p,
|
||||
tgt->GetLinkDependentTargetsForProperty(p,
|
||||
dependentTargets);
|
||||
const bool impliedByUse =
|
||||
this->IsNullImpliedByLinkLibraries(p);
|
||||
tgt->IsNullImpliedByLinkLibraries(p);
|
||||
assert((impliedByUse ^ explicitlySet)
|
||||
|| (!impliedByUse && !explicitlySet));
|
||||
|
||||
cmComputeLinkInformation *info = this->GetLinkInformation(config);
|
||||
cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
|
||||
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
||||
bool propInitialized = explicitlySet;
|
||||
|
||||
|
@ -4519,20 +4643,22 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
|||
const bool ifaceIsSet = li->Target->GetProperties()
|
||||
.find("INTERFACE_" + p)
|
||||
!= li->Target->GetProperties().end();
|
||||
const bool ifacePropContent = li->Target->GetPropertyAsBool(
|
||||
("INTERFACE_" + p).c_str());
|
||||
PropertyType ifacePropContent =
|
||||
getTypedProperty<PropertyType>(li->Target,
|
||||
("INTERFACE_" + p).c_str(), 0);
|
||||
if (explicitlySet)
|
||||
{
|
||||
if (ifaceIsSet)
|
||||
{
|
||||
if (propContent != ifacePropContent)
|
||||
if (!consistentProperty(propContent, ifacePropContent))
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Property " << p << " on target \""
|
||||
<< this->GetName() << "\" does\nnot match the "
|
||||
<< tgt->GetName() << "\" does\nnot match the "
|
||||
"INTERFACE_" << p << " property requirement\nof "
|
||||
"dependency \"" << li->Target->GetName() << "\".\n";
|
||||
cmSystemTools::Error(e.str().c_str());
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4550,15 +4676,16 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
|||
{
|
||||
if (ifaceIsSet)
|
||||
{
|
||||
if (propContent != ifacePropContent)
|
||||
if (!consistentProperty(propContent, ifacePropContent))
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Property " << p << " on target \""
|
||||
<< this->GetName() << "\" is\nimplied to be FALSE because it "
|
||||
"was used to determine the link libraries\nalready. The "
|
||||
"INTERFACE_" << p << " property on\ndependency \""
|
||||
<< tgt->GetName() << "\" is\nimplied to be " << defaultValue
|
||||
<< " because it was used to determine the link libraries\n"
|
||||
"already. The INTERFACE_" << p << " property on\ndependency \""
|
||||
<< li->Target->GetName() << "\" is in conflict.\n";
|
||||
cmSystemTools::Error(e.str().c_str());
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4578,14 +4705,15 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
|||
{
|
||||
if (propInitialized)
|
||||
{
|
||||
if (propContent != ifacePropContent)
|
||||
if (!consistentProperty(propContent, ifacePropContent))
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "The INTERFACE_" << p << " property of \""
|
||||
<< li->Target->GetName() << "\" does\nnot agree with the value "
|
||||
"of " << p << " already determined\nfor \""
|
||||
<< this->GetName() << "\".\n";
|
||||
<< tgt->GetName() << "\".\n";
|
||||
cmSystemTools::Error(e.str().c_str());
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4609,6 +4737,80 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
|||
return propContent;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||
const char *config)
|
||||
{
|
||||
return checkInterfacePropertyCompatibility<bool>(this, p, config, "FALSE",
|
||||
0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char * cmTarget::GetLinkInterfaceDependentStringProperty(
|
||||
const std::string &p,
|
||||
const char *config)
|
||||
{
|
||||
return checkInterfacePropertyCompatibility<const char *>(this,
|
||||
p,
|
||||
config,
|
||||
"empty", 0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool isLinkDependentProperty(cmTarget *tgt, const std::string &p,
|
||||
const char *interfaceProperty,
|
||||
const char *config)
|
||||
{
|
||||
cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
|
||||
|
||||
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
||||
|
||||
for(cmComputeLinkInformation::ItemVector::const_iterator li =
|
||||
deps.begin();
|
||||
li != deps.end(); ++li)
|
||||
{
|
||||
if (!li->Target)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const char *prop = li->Target->GetProperty(interfaceProperty);
|
||||
if (!prop)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<std::string> props;
|
||||
cmSystemTools::ExpandListArgument(prop, props);
|
||||
|
||||
for(std::vector<std::string>::iterator pi = props.begin();
|
||||
pi != props.end(); ++pi)
|
||||
{
|
||||
if (*pi == p)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||
const char *config)
|
||||
{
|
||||
return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_BOOL",
|
||||
config);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
|
||||
const char *config)
|
||||
{
|
||||
return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_STRING",
|
||||
config);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
|
||||
{
|
||||
|
@ -5349,6 +5551,73 @@ std::string cmTarget::CheckCMP0004(std::string const& item)
|
|||
return lib;
|
||||
}
|
||||
|
||||
template<typename PropertyType>
|
||||
PropertyType getLinkInterfaceDependentProperty(cmTarget *tgt,
|
||||
const std::string prop,
|
||||
const char *config,
|
||||
PropertyType *);
|
||||
|
||||
template<>
|
||||
bool getLinkInterfaceDependentProperty(cmTarget *tgt,
|
||||
const std::string prop,
|
||||
const char *config, bool *)
|
||||
{
|
||||
return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
|
||||
}
|
||||
|
||||
template<>
|
||||
const char * getLinkInterfaceDependentProperty(cmTarget *tgt,
|
||||
const std::string prop,
|
||||
const char *config,
|
||||
const char **)
|
||||
{
|
||||
return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename PropertyType>
|
||||
void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee,
|
||||
const char *propName,
|
||||
std::set<cmStdString> &emitted,
|
||||
const char *config,
|
||||
PropertyType *)
|
||||
{
|
||||
const char *prop = dependee->GetProperty(propName);
|
||||
if (!prop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> props;
|
||||
cmSystemTools::ExpandListArgument(prop, props);
|
||||
|
||||
for(std::vector<std::string>::iterator pi = props.begin();
|
||||
pi != props.end(); ++pi)
|
||||
{
|
||||
if (depender->GetMakefile()->GetCMakeInstance()
|
||||
->GetIsPropertyDefined(pi->c_str(),
|
||||
cmProperty::TARGET))
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Target \"" << dependee->GetName() << "\" has property \""
|
||||
<< *pi << "\" listed in its " << propName << " property. "
|
||||
"This is not allowed. Only user-defined properties may appear "
|
||||
"listed in the " << propName << " property.";
|
||||
depender->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
return;
|
||||
}
|
||||
if(emitted.insert(*pi).second)
|
||||
{
|
||||
getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
|
||||
0);
|
||||
if (cmSystemTools::GetErrorOccuredFlag())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
|
||||
const char* config)
|
||||
|
@ -5365,38 +5634,20 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
|
|||
{
|
||||
continue;
|
||||
}
|
||||
const char *prop = li->Target->GetProperty("COMPATIBLE_INTERFACE_BOOL");
|
||||
if (!prop)
|
||||
|
||||
checkPropertyConsistency<bool>(this, li->Target,
|
||||
"COMPATIBLE_INTERFACE_BOOL",
|
||||
emitted, config, 0);
|
||||
if (cmSystemTools::GetErrorOccuredFlag())
|
||||
{
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> props;
|
||||
cmSystemTools::ExpandListArgument(prop, props);
|
||||
|
||||
for(std::vector<std::string>::iterator pi = props.begin();
|
||||
pi != props.end(); ++pi)
|
||||
checkPropertyConsistency<const char *>(this, li->Target,
|
||||
"COMPATIBLE_INTERFACE_STRING",
|
||||
emitted, config, 0);
|
||||
if (cmSystemTools::GetErrorOccuredFlag())
|
||||
{
|
||||
if (this->Makefile->GetCMakeInstance()
|
||||
->GetIsPropertyDefined(pi->c_str(),
|
||||
cmProperty::TARGET))
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Target \"" << li->Target->GetName() << "\" has property \""
|
||||
<< *pi << "\" listed in its COMPATIBLE_INTERFACE_BOOL property. "
|
||||
"This is not allowed. Only user-defined properties may appear "
|
||||
"listed in the COMPATIBLE_INTERFACE_BOOL property.";
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
return;
|
||||
}
|
||||
if(emitted.insert(*pi).second)
|
||||
{
|
||||
this->GetLinkInterfaceDependentBoolProperty(*pi, config);
|
||||
if (cmSystemTools::GetErrorOccuredFlag())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5422,14 +5673,14 @@ cmTarget::GetLinkInformation(const char* config, cmTarget *head)
|
|||
info = 0;
|
||||
}
|
||||
|
||||
// Store the information for this configuration.
|
||||
cmTargetLinkInformationMap::value_type entry(key, info);
|
||||
i = this->LinkInformation.insert(entry).first;
|
||||
|
||||
if (info)
|
||||
{
|
||||
this->CheckPropertyCompatibility(info, config);
|
||||
}
|
||||
|
||||
// Store the information for this configuration.
|
||||
cmTargetLinkInformationMap::value_type entry(key, info);
|
||||
i = this->LinkInformation.insert(entry).first;
|
||||
}
|
||||
return i->second;
|
||||
}
|
||||
|
|
|
@ -102,6 +102,10 @@ public:
|
|||
cmPolicies::PolicyStatus GetPolicyStatusCMP0008() const
|
||||
{ return this->PolicyStatusCMP0008; }
|
||||
|
||||
/** Get the status of policy CMP0020 when the target was created. */
|
||||
cmPolicies::PolicyStatus GetPolicyStatusCMP0020() const
|
||||
{ return this->PolicyStatusCMP0020; }
|
||||
|
||||
/**
|
||||
* Get the list of the custom commands for this target
|
||||
*/
|
||||
|
@ -426,6 +430,8 @@ public:
|
|||
If no macro should be defined null is returned. */
|
||||
const char* GetExportMacro();
|
||||
|
||||
std::string GetCompileDefinitions(const char *config = 0);
|
||||
|
||||
// Compute the set of languages compiled by the target. This is
|
||||
// computed every time it is called because the languages can change
|
||||
// when source file properties are changed and we do not have enough
|
||||
|
@ -495,12 +501,22 @@ public:
|
|||
void GetLinkDependentTargetsForProperty(const std::string &p,
|
||||
std::set<std::string> &targets);
|
||||
bool IsNullImpliedByLinkLibraries(const std::string &p);
|
||||
bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||
const char *config);
|
||||
bool IsLinkInterfaceDependentStringProperty(const std::string &p,
|
||||
const char *config);
|
||||
|
||||
void AddLinkDependentTargetsForProperties(
|
||||
const std::map<cmStdString, cmStdString> &map);
|
||||
|
||||
bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||
const char *config);
|
||||
|
||||
const char *GetLinkInterfaceDependentStringProperty(const std::string &p,
|
||||
const char *config);
|
||||
|
||||
std::string GetDebugGeneratorExpressions(const std::string &value,
|
||||
cmTarget::LinkLibraryType llt);
|
||||
private:
|
||||
/**
|
||||
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
||||
|
@ -610,6 +626,7 @@ private:
|
|||
bool DLLPlatform;
|
||||
bool IsApple;
|
||||
bool IsImportedTarget;
|
||||
bool DebugIncludesDone;
|
||||
mutable std::map<cmStdString, std::set<std::string> >
|
||||
LinkDependentProperties;
|
||||
mutable std::set<std::string> LinkImplicitNullProperties;
|
||||
|
@ -645,9 +662,6 @@ private:
|
|||
|
||||
void ProcessSourceExpression(std::string const& expr);
|
||||
|
||||
std::string GetDebugGeneratorExpressions(const std::string &value,
|
||||
cmTarget::LinkLibraryType llt);
|
||||
|
||||
// The cmMakefile instance that owns this target. This should
|
||||
// always be set.
|
||||
cmMakefile* Makefile;
|
||||
|
@ -656,6 +670,7 @@ private:
|
|||
cmPolicies::PolicyStatus PolicyStatusCMP0003;
|
||||
cmPolicies::PolicyStatus PolicyStatusCMP0004;
|
||||
cmPolicies::PolicyStatus PolicyStatusCMP0008;
|
||||
cmPolicies::PolicyStatus PolicyStatusCMP0020;
|
||||
|
||||
// Internal representation details.
|
||||
friend class cmTargetInternals;
|
||||
|
|
|
@ -20,13 +20,11 @@ bool cmTargetCompileDefinitionsCommand
|
|||
}
|
||||
|
||||
void cmTargetCompileDefinitionsCommand
|
||||
::HandleImportedTargetInvalidScope(const std::string &scope,
|
||||
const std::string &tgt)
|
||||
::HandleImportedTarget(const std::string &tgt)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Cannot specify " << scope << " compile definitions for imported "
|
||||
"target \"" << tgt << "\". Compile definitions can only be "
|
||||
"specified for an imported target in the INTERFACE mode.";
|
||||
e << "Cannot specify compile definitions for imported target \""
|
||||
<< tgt << "\".";
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
}
|
||||
|
||||
|
@ -39,19 +37,32 @@ void cmTargetCompileDefinitionsCommand
|
|||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
}
|
||||
|
||||
bool cmTargetCompileDefinitionsCommand
|
||||
::HandleNonTargetArg(std::string &content,
|
||||
const std::string &sep,
|
||||
const std::string &entry,
|
||||
const std::string &)
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmTargetCompileDefinitionsCommand
|
||||
::Join(const std::vector<std::string> &content)
|
||||
{
|
||||
content += sep + entry;
|
||||
return true;
|
||||
std::string defs;
|
||||
std::string sep;
|
||||
for(std::vector<std::string>::const_iterator it = content.begin();
|
||||
it != content.end(); ++it)
|
||||
{
|
||||
if (strncmp(it->c_str(), "-D", 2) == 0)
|
||||
{
|
||||
defs += sep + it->substr(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
defs += sep + *it;
|
||||
}
|
||||
sep = ";";
|
||||
}
|
||||
return defs;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTargetCompileDefinitionsCommand
|
||||
::HandleDirectContent(cmTarget *tgt, const std::string &content,
|
||||
::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
|
||||
bool)
|
||||
{
|
||||
tgt->AppendProperty("COMPILE_DEFINITIONS", content.c_str());
|
||||
tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str());
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
"Specify compile definitions or targets to use when compiling a given "
|
||||
"target. "
|
||||
"The named <target> must have been created by a command such as "
|
||||
"add_executable or add_library. "
|
||||
"add_executable or add_library and must not be an IMPORTED target. "
|
||||
"The INTERFACE, PUBLIC and PRIVATE keywords are required to specify "
|
||||
"the scope of the following arguments. PRIVATE and PUBLIC items will "
|
||||
"populate the COMPILE_DEFINITIONS property of <target>. PUBLIC and "
|
||||
|
@ -75,20 +75,16 @@ public:
|
|||
;
|
||||
}
|
||||
|
||||
cmTypeMacro(cmTargetCompileDefinitionsCommand, cmCommand);
|
||||
cmTypeMacro(cmTargetCompileDefinitionsCommand, cmTargetPropCommandBase);
|
||||
|
||||
private:
|
||||
virtual void HandleImportedTargetInvalidScope(const std::string &scope,
|
||||
const std::string &tgt);
|
||||
virtual void HandleImportedTarget(const std::string &tgt);
|
||||
virtual void HandleMissingTarget(const std::string &name);
|
||||
|
||||
virtual bool HandleNonTargetArg(std::string &content,
|
||||
const std::string &sep,
|
||||
const std::string &entry,
|
||||
const std::string &tgt);
|
||||
|
||||
virtual void HandleDirectContent(cmTarget *tgt, const std::string &content,
|
||||
virtual void HandleDirectContent(cmTarget *tgt,
|
||||
const std::vector<std::string> &content,
|
||||
bool prepend);
|
||||
virtual std::string Join(const std::vector<std::string> &content);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,13 +22,11 @@ bool cmTargetIncludeDirectoriesCommand
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTargetIncludeDirectoriesCommand
|
||||
::HandleImportedTargetInvalidScope(const std::string &tgt,
|
||||
const std::string &scope)
|
||||
::HandleImportedTarget(const std::string &tgt)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Cannot specify " << scope << " include directories for imported "
|
||||
"target \"" << tgt << "\". Include directories can only be "
|
||||
"specified for an imported target in the INTERFACE mode.";
|
||||
e << "Cannot specify include directories for imported target \""
|
||||
<< tgt << "\".";
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
}
|
||||
|
||||
|
@ -43,32 +41,44 @@ void cmTargetIncludeDirectoriesCommand
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTargetIncludeDirectoriesCommand
|
||||
::HandleNonTargetArg(std::string &content,
|
||||
const std::string &sep,
|
||||
const std::string &entry,
|
||||
const std::string &tgt)
|
||||
static bool isGeneratorExpression(const std::string &lib)
|
||||
{
|
||||
if (!cmSystemTools::FileIsFullPath(entry.c_str()))
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Cannot specify relative include directory \"" << entry << "\" for "
|
||||
"target \"" << tgt << "\". Only absolute paths are permitted";
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
return false;
|
||||
}
|
||||
const std::string::size_type openpos = lib.find("$<");
|
||||
return (openpos != std::string::npos)
|
||||
&& (lib.find(">", openpos) != std::string::npos);
|
||||
}
|
||||
|
||||
content += sep + entry;
|
||||
return true;
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmTargetIncludeDirectoriesCommand
|
||||
::Join(const std::vector<std::string> &content)
|
||||
{
|
||||
std::string dirs;
|
||||
std::string sep;
|
||||
std::string prefix = this->Makefile->GetStartDirectory() + std::string("/");
|
||||
for(std::vector<std::string>::const_iterator it = content.begin();
|
||||
it != content.end(); ++it)
|
||||
{
|
||||
if (cmSystemTools::FileIsFullPath(it->c_str())
|
||||
|| isGeneratorExpression(*it))
|
||||
{
|
||||
dirs += sep + *it;
|
||||
}
|
||||
else
|
||||
{
|
||||
dirs += sep + prefix + *it;
|
||||
}
|
||||
sep = ";";
|
||||
}
|
||||
return dirs;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTargetIncludeDirectoriesCommand
|
||||
::HandleDirectContent(cmTarget *tgt, const std::string &content,
|
||||
::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
|
||||
bool prepend)
|
||||
{
|
||||
cmListFileBacktrace lfbt;
|
||||
this->Makefile->GetBacktrace(lfbt);
|
||||
cmMakefileIncludeDirectoriesEntry entry(content, lfbt);
|
||||
cmMakefileIncludeDirectoriesEntry entry(this->Join(content), lfbt);
|
||||
tgt->InsertInclude(entry, prepend);
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
"Specify include directories or targets to use when compiling a given "
|
||||
"target. "
|
||||
"The named <target> must have been created by a command such as "
|
||||
"add_executable or add_library.\n"
|
||||
"add_executable or add_library and must not be an IMPORTED target.\n"
|
||||
"If BEFORE is specified, the content will be prepended to the property "
|
||||
"instead of being appended.\n"
|
||||
"The INTERFACE, PUBLIC and PRIVATE keywords are required to specify "
|
||||
|
@ -79,20 +79,16 @@ public:
|
|||
;
|
||||
}
|
||||
|
||||
cmTypeMacro(cmTargetIncludeDirectoriesCommand, cmCommand);
|
||||
cmTypeMacro(cmTargetIncludeDirectoriesCommand, cmTargetPropCommandBase);
|
||||
|
||||
private:
|
||||
virtual void HandleImportedTargetInvalidScope(const std::string &tgt,
|
||||
const std::string &scope);
|
||||
virtual void HandleImportedTarget(const std::string &tgt);
|
||||
virtual void HandleMissingTarget(const std::string &name);
|
||||
|
||||
virtual bool HandleNonTargetArg(std::string &content,
|
||||
const std::string &sep,
|
||||
const std::string &entry,
|
||||
const std::string &tgt);
|
||||
|
||||
virtual void HandleDirectContent(cmTarget *tgt, const std::string &content,
|
||||
virtual void HandleDirectContent(cmTarget *tgt,
|
||||
const std::vector<std::string> &content,
|
||||
bool prepend);
|
||||
virtual std::string Join(const std::vector<std::string> &content);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,10 +33,6 @@ bool cmTargetLinkLibrariesCommand
|
|||
this->Target =
|
||||
this->Makefile->GetCMakeInstance()
|
||||
->GetGlobalGenerator()->FindTarget(0, args[0].c_str());
|
||||
if(!this->Target)
|
||||
{
|
||||
this->Target = this->Makefile->FindTargetToUse(args[0].c_str());
|
||||
}
|
||||
if(!this->Target)
|
||||
{
|
||||
cmake::MessageType t = cmake::FATAL_ERROR; // fail by default
|
||||
|
@ -253,24 +249,55 @@ cmTargetLinkLibrariesCommand
|
|||
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static std::string compileProperty(cmTarget *tgt, const std::string &lib,
|
||||
bool isGenex,
|
||||
const std::string &property,
|
||||
cmTarget::LinkLibraryType llt)
|
||||
{
|
||||
std::string value = !isGenex ? "$<LINKED:" + lib + ">"
|
||||
: "$<$<TARGET_DEFINED:" + lib + ">:" +
|
||||
"$<TARGET_PROPERTY:" + lib +
|
||||
",INTERFACE_" + property + ">"
|
||||
">";
|
||||
|
||||
return tgt->GetDebugGeneratorExpressions(value, llt);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool isGeneratorExpression(const std::string &lib)
|
||||
{
|
||||
const std::string::size_type openpos = lib.find("$<");
|
||||
return (openpos != std::string::npos)
|
||||
&& (lib.find(">", openpos) != std::string::npos);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
|
||||
cmTarget::LinkLibraryType llt)
|
||||
{
|
||||
const bool isGenex = isGeneratorExpression(lib);
|
||||
|
||||
cmsys::RegularExpression targetNameValidator;
|
||||
targetNameValidator.compile("^[A-Za-z0-9_.:-]+$");
|
||||
const bool potentialTargetName = targetNameValidator.find(lib);
|
||||
|
||||
if (potentialTargetName || isGenex)
|
||||
{
|
||||
this->Target->AppendProperty("INCLUDE_DIRECTORIES",
|
||||
compileProperty(this->Target, lib,
|
||||
isGenex,
|
||||
"INCLUDE_DIRECTORIES", llt).c_str());
|
||||
this->Target->AppendProperty("COMPILE_DEFINITIONS",
|
||||
compileProperty(this->Target, lib,
|
||||
isGenex,
|
||||
"COMPILE_DEFINITIONS", llt).c_str());
|
||||
}
|
||||
|
||||
// Handle normal case first.
|
||||
if(this->CurrentProcessingState != ProcessingLinkInterface)
|
||||
{
|
||||
if (this->Target->IsImported())
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Imported targets may only be used with the "
|
||||
"LINK_INTERFACE_LIBRARIES specifier to target_link_libraries.";
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this->Makefile
|
||||
->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt);
|
||||
if (this->CurrentProcessingState != ProcessingPublicInterface)
|
||||
|
@ -280,6 +307,18 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
|
|||
}
|
||||
}
|
||||
|
||||
if (potentialTargetName || isGenex)
|
||||
{
|
||||
this->Target->AppendProperty("INTERFACE_COMPILE_DEFINITIONS",
|
||||
compileProperty(this->Target, lib,
|
||||
isGenex,
|
||||
"COMPILE_DEFINITIONS", llt).c_str());
|
||||
this->Target->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
|
||||
compileProperty(this->Target, lib,
|
||||
isGenex,
|
||||
"INCLUDE_DIRECTORIES", llt).c_str());
|
||||
}
|
||||
|
||||
// Get the list of configurations considered to be DEBUG.
|
||||
std::vector<std::string> const& debugConfigs =
|
||||
this->Makefile->GetCMakeInstance()->GetDebugConfigs();
|
||||
|
|
|
@ -93,7 +93,18 @@ public:
|
|||
"linked to this target will appear on the link line for the other "
|
||||
"target too. "
|
||||
"See the LINK_INTERFACE_LIBRARIES target property to override the "
|
||||
"set of transitive link dependencies for a target."
|
||||
"set of transitive link dependencies for a target. "
|
||||
"Calls to other signatures of this command may set the property "
|
||||
"making any libraries linked exclusively by this signature private."
|
||||
"\n"
|
||||
"Target usage requirements are also consumed by this command. If the "
|
||||
"<target> is linked to another target which has "
|
||||
"a populated INTERFACE_INCLUDE_DIRECTORIES, the content of it is "
|
||||
"appended to the INCLUDE_DIRECTORIES of <target>. Similarly, the "
|
||||
"INTERFACE_COMPILE_DEFINITONS of a dependee are added to the "
|
||||
"COMPILE_DEFINITONS of <target>, and the "
|
||||
"INTERFACE_POSITION_INDEPENDENT_CODE property is used to determine the "
|
||||
"POSITION_INDEPENDENT_CODE property of <target>."
|
||||
"\n"
|
||||
" target_link_libraries(<target> LINK_INTERFACE_LIBRARIES\n"
|
||||
" [[debug|optimized|general] <lib>] ...)\n"
|
||||
|
|
|
@ -80,17 +80,16 @@ bool cmTargetPropCommandBase
|
|||
return false;
|
||||
}
|
||||
|
||||
if(this->Target->IsImported() && scope != "INTERFACE")
|
||||
if(this->Target->IsImported())
|
||||
{
|
||||
this->HandleImportedTargetInvalidScope(args[0], scope);
|
||||
this->HandleImportedTarget(args[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
++argIndex;
|
||||
|
||||
std::string content;
|
||||
std::vector<std::string> content;
|
||||
|
||||
std::string sep;
|
||||
for(unsigned int i=argIndex; i < args.size(); ++i, ++argIndex)
|
||||
{
|
||||
if(args[i] == "PUBLIC"
|
||||
|
@ -100,16 +99,7 @@ bool cmTargetPropCommandBase
|
|||
this->PopulateTargetProperies(scope, content, prepend);
|
||||
return true;
|
||||
}
|
||||
if (this->Makefile->FindTargetToUse(args[i].c_str()))
|
||||
{
|
||||
content += sep + "$<TARGET_PROPERTY:" + args[i]
|
||||
+ ",INTERFACE_" + this->Property + ">";
|
||||
}
|
||||
else if (!this->HandleNonTargetArg(content, sep, args[i], args[0]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
sep = ";";
|
||||
content.push_back(args[i]);
|
||||
}
|
||||
this->PopulateTargetProperies(scope, content, prepend);
|
||||
return true;
|
||||
|
@ -118,7 +108,8 @@ bool cmTargetPropCommandBase
|
|||
//----------------------------------------------------------------------------
|
||||
void cmTargetPropCommandBase
|
||||
::PopulateTargetProperies(const std::string &scope,
|
||||
const std::string &content, bool prepend)
|
||||
const std::vector<std::string> &content,
|
||||
bool prepend)
|
||||
{
|
||||
if (scope == "PRIVATE" || scope == "PUBLIC")
|
||||
{
|
||||
|
@ -130,7 +121,7 @@ void cmTargetPropCommandBase
|
|||
{
|
||||
const std::string propName = std::string("INTERFACE_") + this->Property;
|
||||
const char *propValue = this->Target->GetProperty(propName.c_str());
|
||||
const std::string totalContent = content + (propValue
|
||||
const std::string totalContent = this->Join(content) + (propValue
|
||||
? std::string(";") + propValue
|
||||
: std::string());
|
||||
this->Target->SetProperty(propName.c_str(), totalContent.c_str());
|
||||
|
@ -138,7 +129,7 @@ void cmTargetPropCommandBase
|
|||
else
|
||||
{
|
||||
this->Target->AppendProperty(("INTERFACE_" + this->Property).c_str(),
|
||||
content.c_str());
|
||||
this->Join(content).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,28 +31,25 @@ public:
|
|||
bool HandleArguments(std::vector<std::string> const& args,
|
||||
const char *prop, ArgumentFlags flags = NO_FLAGS);
|
||||
|
||||
cmTypeMacro(cmTargetPropCommandBase, cmCommand);
|
||||
protected:
|
||||
std::string Property;
|
||||
cmTarget *Target;
|
||||
|
||||
private:
|
||||
virtual void HandleImportedTargetInvalidScope(const std::string &tgt,
|
||||
const std::string &scope) = 0;
|
||||
virtual void HandleImportedTarget(const std::string &tgt) = 0;
|
||||
virtual void HandleMissingTarget(const std::string &name) = 0;
|
||||
|
||||
virtual bool HandleNonTargetArg(std::string &content,
|
||||
const std::string &sep,
|
||||
const std::string &entry,
|
||||
const std::string &tgt) = 0;
|
||||
|
||||
virtual void HandleDirectContent(cmTarget *tgt,
|
||||
const std::string &content,
|
||||
const std::vector<std::string> &content,
|
||||
bool prepend) = 0;
|
||||
virtual std::string Join(const std::vector<std::string> &content) = 0;
|
||||
|
||||
bool ProcessContentArgs(std::vector<std::string> const& args,
|
||||
unsigned int &argIndex, bool prepend);
|
||||
void PopulateTargetProperies(const std::string &scope,
|
||||
const std::string &content, bool prepend);
|
||||
|
||||
private:
|
||||
cmTarget *Target;
|
||||
std::string Property;
|
||||
const std::vector<std::string> &content,
|
||||
bool prepend);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1221,8 +1221,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
|
|||
clOptions.Parse(flags.c_str());
|
||||
clOptions.Parse(defineFlags.c_str());
|
||||
clOptions.AddDefines(
|
||||
this->GeneratorTarget->GetCompileDefinitions().c_str());
|
||||
clOptions.AddDefines(this->GeneratorTarget->GetCompileDefinitions(
|
||||
this->Target->GetCompileDefinitions().c_str());
|
||||
clOptions.AddDefines(this->Target->GetCompileDefinitions(
|
||||
configName.c_str()).c_str());
|
||||
clOptions.SetVerboseMakefile(
|
||||
this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
|
||||
|
|
|
@ -4449,6 +4449,10 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
|
|||
isError = true;
|
||||
msg << "CMake Internal Error (please report a bug)";
|
||||
}
|
||||
else if(t == cmake::LOG)
|
||||
{
|
||||
msg << "CMake Debug Log";
|
||||
}
|
||||
else
|
||||
{
|
||||
msg << "CMake Warning";
|
||||
|
|
|
@ -428,6 +428,58 @@ const char* DynamicLoader::LastError()
|
|||
} // namespace KWSYS_NAMESPACE
|
||||
#endif
|
||||
|
||||
#ifdef __MINT__
|
||||
#define DYNAMICLOADER_DEFINED 1
|
||||
#define _GNU_SOURCE /* for program_invocation_name */
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <errno.h>
|
||||
#include <dld.h>
|
||||
|
||||
namespace KWSYS_NAMESPACE
|
||||
{
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
|
||||
{
|
||||
char *name = (char *)calloc(1, strlen(libname) + 1);
|
||||
dld_init(program_invocation_name);
|
||||
strncpy(name, libname, strlen(libname));
|
||||
dld_link(libname);
|
||||
return (void *)name;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
|
||||
{
|
||||
dld_unlink_by_file((char *)lib, 0);
|
||||
free(lib);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
|
||||
DynamicLoader::LibraryHandle lib, const char* sym)
|
||||
{
|
||||
// Hack to cast pointer-to-data to pointer-to-function.
|
||||
union
|
||||
{
|
||||
void* pvoid;
|
||||
DynamicLoader::SymbolPointer psym;
|
||||
} result;
|
||||
result.pvoid = dld_get_symbol(sym);
|
||||
return result.psym;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char* DynamicLoader::LastError()
|
||||
{
|
||||
return dld_strerror(dld_errno);
|
||||
}
|
||||
|
||||
} // namespace KWSYS_NAMESPACE
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// 6. Implementation for default UNIX machines.
|
||||
// if nothing has been defined then use this
|
||||
|
|
|
@ -399,7 +399,7 @@ bool Glob::FindFiles(const kwsys_stl::string& inexpr)
|
|||
if ( last_slash > 0 )
|
||||
{
|
||||
//kwsys_ios::cout << "I can skip: " << fexpr.substr(0, last_slash)
|
||||
//<< kwsys_ios::endl;
|
||||
// << kwsys_ios::endl;
|
||||
skip = last_slash;
|
||||
}
|
||||
if ( skip == 0 )
|
||||
|
|
|
@ -272,6 +272,7 @@ namespace KWSYS_NAMESPACE
|
|||
|
||||
// Create one public symbol in this object file to avoid warnings from
|
||||
// archivers.
|
||||
void IOStreamSymbolToAvoidWarning();
|
||||
void IOStreamSymbolToAvoidWarning()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ static inline void kwsysProcess_usleep(unsigned int msec)
|
|||
* pipes' file handles to be non-blocking and just poll them directly
|
||||
* without select().
|
||||
*/
|
||||
#if !defined(__BEOS__) && !defined(__VMS)
|
||||
#if !defined(__BEOS__) && !defined(__VMS) && !defined(__MINT__)
|
||||
# define KWSYSPE_USE_SELECT 1
|
||||
#endif
|
||||
|
||||
|
|
|
@ -2466,7 +2466,9 @@ bool SystemInformationImplementation::RetrieveCPUPowerManagement()
|
|||
#endif
|
||||
}
|
||||
|
||||
void SystemInformationStripLeadingSpace(kwsys_stl::string& str)
|
||||
#if USE_CPUID
|
||||
// Used only in USE_CPUID implementation below.
|
||||
static void SystemInformationStripLeadingSpace(kwsys_stl::string& str)
|
||||
{
|
||||
// Because some manufacturers have leading white space - we have to post-process the name.
|
||||
kwsys_stl::string::size_type pos = str.find_first_not_of(" ");
|
||||
|
@ -2475,6 +2477,7 @@ void SystemInformationStripLeadingSpace(kwsys_stl::string& str)
|
|||
str = str.substr(pos);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** */
|
||||
bool SystemInformationImplementation::RetrieveExtendedCPUIdentity()
|
||||
|
|
|
@ -3037,7 +3037,7 @@ void SystemTools::CheckTranslationPath(kwsys_stl::string & path)
|
|||
path.erase(path.end()-1, path.end());
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SystemToolsAppendComponents(
|
||||
kwsys_stl::vector<kwsys_stl::string>& out_components,
|
||||
kwsys_stl::vector<kwsys_stl::string>::const_iterator first,
|
||||
|
@ -4704,7 +4704,7 @@ bool SystemTools::ParseURL( const kwsys_stl::string& URL,
|
|||
// ----------------------------------------------------------------------
|
||||
// These must NOT be initialized. Default initialization to zero is
|
||||
// necessary.
|
||||
unsigned int SystemToolsManagerCount;
|
||||
static unsigned int SystemToolsManagerCount;
|
||||
SystemToolsTranslationMap *SystemTools::TranslationMap;
|
||||
SystemToolsTranslationMap *SystemTools::LongPathMap;
|
||||
#ifdef __CYGWIN__
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
#include <stddef.h> /* size_t */
|
||||
#include <string.h> /* strcmp */
|
||||
|
||||
void* random_ptr = reinterpret_cast<void*>(0x123);
|
||||
static void* random_ptr = reinterpret_cast<void*>(0x123);
|
||||
|
||||
int argument(const char* arg, const char* value, void* call_data)
|
||||
static int argument(const char* arg, const char* value, void* call_data)
|
||||
{
|
||||
kwsys_ios::cout << "Got argument: \"" << arg << "\" value: \"" << (value?value:"(null)") << "\"" << kwsys_ios::endl;
|
||||
if ( call_data != random_ptr )
|
||||
|
@ -37,7 +37,7 @@ int argument(const char* arg, const char* value, void* call_data)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int unknown_argument(const char* argument, void* call_data)
|
||||
static int unknown_argument(const char* argument, void* call_data)
|
||||
{
|
||||
kwsys_ios::cout << "Got unknown argument: \"" << argument << "\"" << kwsys_ios::endl;
|
||||
if ( call_data != random_ptr )
|
||||
|
@ -48,12 +48,12 @@ int unknown_argument(const char* argument, void* call_data)
|
|||
return 1;
|
||||
}
|
||||
|
||||
bool CompareTwoItemsOnList(bool i1, bool i2) { return i1 == i2; }
|
||||
bool CompareTwoItemsOnList(int i1, int i2) { return i1 == i2; }
|
||||
bool CompareTwoItemsOnList(double i1, double i2) { return i1 == i2; }
|
||||
bool CompareTwoItemsOnList(const char* i1,
|
||||
static bool CompareTwoItemsOnList(bool i1, bool i2) { return i1 == i2; }
|
||||
static bool CompareTwoItemsOnList(int i1, int i2) { return i1 == i2; }
|
||||
static bool CompareTwoItemsOnList(double i1, double i2) { return i1 == i2; }
|
||||
static bool CompareTwoItemsOnList(const char* i1,
|
||||
const char* i2) { return strcmp(i1, i2) == 0; }
|
||||
bool CompareTwoItemsOnList(const kwsys_stl::string& i1,
|
||||
static bool CompareTwoItemsOnList(const kwsys_stl::string& i1,
|
||||
const kwsys_stl::string& i2) { return i1 == i2; }
|
||||
|
||||
int testCommandLineArguments(int argc, char* argv[])
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
// left on disk.
|
||||
#include <testSystemTools.h>
|
||||
|
||||
kwsys_stl::string GetLibName(const char* lname)
|
||||
static kwsys_stl::string GetLibName(const char* lname)
|
||||
{
|
||||
// Construct proper name of lib
|
||||
kwsys_stl::string slname;
|
||||
|
|
|
@ -47,7 +47,7 @@ int runChild(const char* cmd[], int state, int exception, int value,
|
|||
int share, int output, int delay, double timeout, int poll,
|
||||
int repeat, int disown);
|
||||
|
||||
int test1(int argc, const char* argv[])
|
||||
static int test1(int argc, const char* argv[])
|
||||
{
|
||||
(void)argc; (void)argv;
|
||||
fprintf(stdout, "Output on stdout from test returning 0.\n");
|
||||
|
@ -55,7 +55,7 @@ int test1(int argc, const char* argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
int test2(int argc, const char* argv[])
|
||||
static int test2(int argc, const char* argv[])
|
||||
{
|
||||
(void)argc; (void)argv;
|
||||
fprintf(stdout, "Output on stdout from test returning 123.\n");
|
||||
|
@ -63,7 +63,7 @@ int test2(int argc, const char* argv[])
|
|||
return 123;
|
||||
}
|
||||
|
||||
int test3(int argc, const char* argv[])
|
||||
static int test3(int argc, const char* argv[])
|
||||
{
|
||||
(void)argc; (void)argv;
|
||||
fprintf(stdout, "Output before sleep on stdout from timeout test.\n");
|
||||
|
@ -80,7 +80,7 @@ int test3(int argc, const char* argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
int test4(int argc, const char* argv[])
|
||||
static int test4(int argc, const char* argv[])
|
||||
{
|
||||
/* Prepare a pointer to an invalid address. Don't use null, because
|
||||
dereferencing null is undefined behaviour and compilers are free to
|
||||
|
@ -109,7 +109,7 @@ int test4(int argc, const char* argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
int test5(int argc, const char* argv[])
|
||||
static int test5(int argc, const char* argv[])
|
||||
{
|
||||
int r;
|
||||
const char* cmd[4];
|
||||
|
@ -132,7 +132,7 @@ int test5(int argc, const char* argv[])
|
|||
}
|
||||
|
||||
#define TEST6_SIZE (4096*2)
|
||||
void test6(int argc, const char* argv[])
|
||||
static void test6(int argc, const char* argv[])
|
||||
{
|
||||
int i;
|
||||
char runaway[TEST6_SIZE+1];
|
||||
|
@ -156,7 +156,7 @@ void test6(int argc, const char* argv[])
|
|||
delaying 1/10th of a second should ever have to poll. */
|
||||
#define MINPOLL 5
|
||||
#define MAXPOLL 20
|
||||
int test7(int argc, const char* argv[])
|
||||
static int test7(int argc, const char* argv[])
|
||||
{
|
||||
(void)argc; (void)argv;
|
||||
fprintf(stdout, "Output on stdout before sleep.\n");
|
||||
|
@ -176,7 +176,7 @@ int test7(int argc, const char* argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
int test8(int argc, const char* argv[])
|
||||
static int test8(int argc, const char* argv[])
|
||||
{
|
||||
/* Create a disowned grandchild to test handling of processes
|
||||
that exit before their children. */
|
||||
|
@ -200,7 +200,7 @@ int test8(int argc, const char* argv[])
|
|||
return r;
|
||||
}
|
||||
|
||||
int test8_grandchild(int argc, const char* argv[])
|
||||
static int test8_grandchild(int argc, const char* argv[])
|
||||
{
|
||||
(void)argc; (void)argv;
|
||||
fprintf(stdout, "Output on stdout from grandchild before sleep.\n");
|
||||
|
@ -221,7 +221,7 @@ int test8_grandchild(int argc, const char* argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
int runChild2(kwsysProcess* kp,
|
||||
static int runChild2(kwsysProcess* kp,
|
||||
const char* cmd[], int state, int exception, int value,
|
||||
int share, int output, int delay, double timeout,
|
||||
int poll, int disown)
|
||||
|
@ -505,7 +505,7 @@ int main(int argc, const char* argv[])
|
|||
fprintf(stderr, "Output on stderr after test %d.\n", n);
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
#if _WIN32
|
||||
#if defined(_WIN32)
|
||||
if(argv0) { free(argv0); }
|
||||
#endif
|
||||
return r;
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include <string.h> /* strcmp */
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char* toUnixPaths[][2] =
|
||||
static const char* toUnixPaths[][2] =
|
||||
{
|
||||
{ "/usr/local/bin/passwd", "/usr/local/bin/passwd" },
|
||||
{ "/usr/lo cal/bin/pa sswd", "/usr/lo cal/bin/pa sswd" },
|
||||
|
@ -52,8 +52,8 @@ const char* toUnixPaths[][2] =
|
|||
{0, 0}
|
||||
};
|
||||
|
||||
bool CheckConvertToUnixSlashes(kwsys_stl::string input,
|
||||
kwsys_stl::string output)
|
||||
static bool CheckConvertToUnixSlashes(kwsys_stl::string input,
|
||||
kwsys_stl::string output)
|
||||
{
|
||||
kwsys_stl::string result = input;
|
||||
kwsys::SystemTools::ConvertToUnixSlashes(result);
|
||||
|
@ -69,17 +69,17 @@ bool CheckConvertToUnixSlashes(kwsys_stl::string input,
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char* checkEscapeChars[][4] =
|
||||
static const char* checkEscapeChars[][4] =
|
||||
{
|
||||
{ "1 foo 2 bar 2", "12", "\\", "\\1 foo \\2 bar \\2"},
|
||||
{ " {} ", "{}", "#", " #{#} "},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
bool CheckEscapeChars(kwsys_stl::string input,
|
||||
const char *chars_to_escape,
|
||||
char escape_char,
|
||||
kwsys_stl::string output)
|
||||
static bool CheckEscapeChars(kwsys_stl::string input,
|
||||
const char *chars_to_escape,
|
||||
char escape_char,
|
||||
kwsys_stl::string output)
|
||||
{
|
||||
kwsys_stl::string result = kwsys::SystemTools::EscapeChars(
|
||||
input.c_str(), chars_to_escape, escape_char);
|
||||
|
@ -95,7 +95,7 @@ bool CheckEscapeChars(kwsys_stl::string input,
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool CheckFileOperations()
|
||||
static bool CheckFileOperations()
|
||||
{
|
||||
bool res = true;
|
||||
|
||||
|
@ -129,7 +129,7 @@ bool CheckFileOperations()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool CheckStringOperations()
|
||||
static bool CheckStringOperations()
|
||||
{
|
||||
bool res = true;
|
||||
|
||||
|
@ -329,7 +329,7 @@ bool CheckStringOperations()
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
bool CheckPutEnv(const char* env, const char* name, const char* value)
|
||||
static bool CheckPutEnv(const char* env, const char* name, const char* value)
|
||||
{
|
||||
if(!kwsys::SystemTools::PutEnv(env))
|
||||
{
|
||||
|
@ -348,7 +348,7 @@ bool CheckPutEnv(const char* env, const char* name, const char* value)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CheckUnPutEnv(const char* env, const char* name)
|
||||
static bool CheckUnPutEnv(const char* env, const char* name)
|
||||
{
|
||||
if(!kwsys::SystemTools::UnPutEnv(env))
|
||||
{
|
||||
|
@ -365,7 +365,7 @@ bool CheckUnPutEnv(const char* env, const char* name)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CheckEnvironmentOperations()
|
||||
static bool CheckEnvironmentOperations()
|
||||
{
|
||||
bool res = true;
|
||||
res &= CheckPutEnv("A=B", "A", "B");
|
||||
|
|
|
@ -12,17 +12,19 @@ target_compile_definitions(target_compile_definitions
|
|||
INTERFACE MY_INTERFACE_DEFINE
|
||||
)
|
||||
|
||||
add_library(importedlib UNKNOWN IMPORTED)
|
||||
target_compile_definitions(importedlib
|
||||
INTERFACE MY_IMPORTEDINTERFACE_DEFINE
|
||||
)
|
||||
|
||||
add_executable(consumer
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp"
|
||||
)
|
||||
|
||||
add_library(linked UNKNOWN IMPORTED)
|
||||
set_property(TARGET linked PROPERTY
|
||||
INTERFACE_COMPILE_DEFINITIONS "MY_LINKED_DEFINE")
|
||||
|
||||
|
||||
target_compile_definitions(consumer
|
||||
PRIVATE target_compile_definitions importedlib
|
||||
PRIVATE $<TARGET_PROPERTY:target_compile_definitions,INTERFACE_COMPILE_DEFINITIONS>
|
||||
$<$<TARGET_DEFINED:notdefined>:SHOULD_NOT_BE_DEFINED>
|
||||
$<$<TARGET_DEFINED:importedlib>:SHOULD_BE_DEFINED>
|
||||
$<$<TARGET_DEFINED:target_compile_definitions>:SHOULD_BE_DEFINED>
|
||||
$<LINKED:linked>
|
||||
-DDASH_D_DEFINE
|
||||
)
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
#error Expected MY_INTERFACE_DEFINE
|
||||
#endif
|
||||
|
||||
#ifndef MY_IMPORTEDINTERFACE_DEFINE
|
||||
#error Expected MY_IMPORTEDINTERFACE_DEFINE
|
||||
#endif
|
||||
|
||||
#ifdef SHOULD_NOT_BE_DEFINED
|
||||
#error Unexpected SHOULD_NOT_BE_DEFINED
|
||||
#endif
|
||||
|
@ -23,4 +19,12 @@
|
|||
#error Expected SHOULD_BE_DEFINED
|
||||
#endif
|
||||
|
||||
#ifndef DASH_D_DEFINE
|
||||
#error Expected DASH_D_DEFINE
|
||||
#endif
|
||||
|
||||
#ifndef MY_LINKED_DEFINE
|
||||
#error Expected MY_LINKED_DEFINE
|
||||
#endif
|
||||
|
||||
int main() { return 0; }
|
||||
|
|
|
@ -11,15 +11,15 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/publicinclude/publicinclude.h" "#define
|
|||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/interfaceinclude")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/interfaceinclude/interfaceinclude.h" "#define INTERFACEINCLUDE_DEFINE\n")
|
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/importedinterfaceinclude")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/importedinterfaceinclude/importedinterfaceinclude.h" "#define IMPORTEDINTERFACEINCLUDE_DEFINE\n")
|
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/poison")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/poison/common.h" "#error Should not be included\n")
|
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/cure")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cure/common.h" "#define CURE_DEFINE\n")
|
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/linkedinclude")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/linkedinclude/linkedinclude.h" "#define LINKEDINCLUDE_DEFINE\n")
|
||||
|
||||
add_executable(target_include_directories
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/main.cpp"
|
||||
)
|
||||
|
@ -33,18 +33,25 @@ target_include_directories(target_include_directories
|
|||
PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/poison"
|
||||
)
|
||||
target_include_directories(target_include_directories
|
||||
BEFORE PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/cure"
|
||||
BEFORE PUBLIC "$<$<TARGET_DEFINED:target_include_directories>:${CMAKE_CURRENT_BINARY_DIR}/cure>"
|
||||
)
|
||||
|
||||
add_library(importedlib UNKNOWN IMPORTED)
|
||||
target_include_directories(importedlib
|
||||
INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/importedinterfaceinclude"
|
||||
# Has no effect because the target is not defined:
|
||||
target_include_directories(target_include_directories
|
||||
BEFORE PUBLIC "$<$<TARGET_DEFINED:notdefined>:${CMAKE_CURRENT_BINARY_DIR}/poison>"
|
||||
)
|
||||
|
||||
add_executable(consumer
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp"
|
||||
)
|
||||
|
||||
add_library(linked UNKNOWN IMPORTED)
|
||||
set_property(TARGET linked PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/linkedinclude")
|
||||
|
||||
target_include_directories(consumer
|
||||
PRIVATE target_include_directories importedlib
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:target_include_directories,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<LINKED:linked>
|
||||
relative_dir
|
||||
)
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
#include "common.h"
|
||||
#include "publicinclude.h"
|
||||
#include "interfaceinclude.h"
|
||||
#include "importedinterfaceinclude.h"
|
||||
#include "relative_dir.h"
|
||||
#include "linkedinclude.h"
|
||||
|
||||
#ifdef PRIVATEINCLUDE_DEFINE
|
||||
#error Unexpected PRIVATEINCLUDE_DEFINE
|
||||
|
@ -16,12 +17,16 @@
|
|||
#error Expected INTERFACEINCLUDE_DEFINE
|
||||
#endif
|
||||
|
||||
#ifndef IMPORTEDINTERFACEINCLUDE_DEFINE
|
||||
#error Expected IMPORTEDINTERFACEINCLUDE_DEFINE
|
||||
#endif
|
||||
|
||||
#ifndef CURE_DEFINE
|
||||
#error Expected CURE_DEFINE
|
||||
#endif
|
||||
|
||||
#ifndef RELATIVE_DIR_DEFINE
|
||||
#error Expected RELATIVE_DIR_DEFINE
|
||||
#endif
|
||||
|
||||
#ifndef LINKEDINCLUDE_DEFINE
|
||||
#error Expected LINKEDINCLUDE_DEFINE
|
||||
#endif
|
||||
|
||||
int main() { return 0; }
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
#define RELATIVE_DIR_DEFINE
|
|
@ -29,9 +29,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
|||
add_library(depA SHARED depA.cpp)
|
||||
generate_export_header(depA)
|
||||
|
||||
add_library(importedlib UNKNOWN IMPORTED)
|
||||
target_link_libraries(importedlib LINK_INTERFACE_LIBRARIES depA)
|
||||
|
||||
add_library(depB SHARED depB.cpp)
|
||||
generate_export_header(depB)
|
||||
|
||||
|
@ -65,10 +62,6 @@ assert_property(targetA LINK_INTERFACE_LIBRARIES "")
|
|||
|
||||
add_subdirectory(subdir)
|
||||
target_link_libraries(targetA subdirlib)
|
||||
set_property(TARGET targetA APPEND PROPERTY
|
||||
INCLUDE_DIRECTORIES
|
||||
$<TARGET_PROPERTY:subdirlib,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
|
||||
target_link_libraries(targetA depB depC)
|
||||
|
||||
|
@ -90,3 +83,24 @@ set_property(TARGET depD APPEND PROPERTY
|
|||
|
||||
add_executable(targetB targetB.cpp)
|
||||
target_link_libraries(targetB depD)
|
||||
|
||||
macro(create_header _name)
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_name}")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_name}/${_name}.h" "//${_name}.h\n")
|
||||
endmacro()
|
||||
|
||||
create_header(foo)
|
||||
create_header(bar)
|
||||
|
||||
add_library(depG SHARED depG.cpp)
|
||||
generate_export_header(depG)
|
||||
target_include_directories(depG INTERFACE
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/foo"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/bar"
|
||||
)
|
||||
target_compile_definitions(depG INTERFACE
|
||||
TEST_DEF
|
||||
)
|
||||
|
||||
add_executable(targetC targetC.cpp)
|
||||
target_link_libraries(targetC depG)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "depG.h"
|
||||
|
||||
int DepG::foo()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "depg_export.h"
|
||||
|
||||
struct DEPG_EXPORT DepG
|
||||
{
|
||||
int foo();
|
||||
};
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
#include "depG.h"
|
||||
|
||||
#include "foo.h"
|
||||
#include "bar.h"
|
||||
|
||||
#ifndef TEST_DEF
|
||||
#error Expected TEST_DEF definition
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
DepG g;
|
||||
|
||||
return g.foo();
|
||||
}
|
|
@ -216,6 +216,7 @@ if(BUILD_TESTING)
|
|||
ADD_TEST_MACRO(PolicyScope PolicyScope)
|
||||
ADD_TEST_MACRO(EmptyLibrary EmptyLibrary)
|
||||
ADD_TEST_MACRO(CompileDefinitions CompileDefinitions)
|
||||
ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
|
||||
set_tests_properties(EmptyLibrary PROPERTIES
|
||||
PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target:test")
|
||||
ADD_TEST_MACRO(CrossCompile CrossCompile)
|
||||
|
@ -311,6 +312,19 @@ if(BUILD_TESTING)
|
|||
|
||||
ADD_TEST_MACRO(Module.CheckTypeSize CheckTypeSize)
|
||||
|
||||
add_test(Module.ExternalData ${CMAKE_CTEST_COMMAND}
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/Module/ExternalData"
|
||||
"${CMake_BINARY_DIR}/Tests/Module/ExternalData"
|
||||
--build-generator ${CMAKE_TEST_GENERATOR}
|
||||
--build-project ExternalDataTest
|
||||
--build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
|
||||
--build-noclean
|
||||
--force-new-ctest-process
|
||||
--test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} -V
|
||||
)
|
||||
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Module/ExternalData")
|
||||
|
||||
ADD_TEST_MACRO(Module.GenerateExportHeader GenerateExportHeader)
|
||||
|
||||
if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
|
@ -1976,6 +1990,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
|
|||
--output-log "${CMake_BINARY_DIR}/Tests/CTestTestParallel/testOutput.log"
|
||||
)
|
||||
|
||||
set(CTestLimitDashJ_EXTRA_OPTIONS --force-new-ctest-process)
|
||||
add_test_macro(CTestLimitDashJ ${CMAKE_CTEST_COMMAND} -j 4
|
||||
--output-on-failure -C "\${CTestTest_CONFIG}")
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@ set(CMAKE_EXECUTABLE "${CMake_BIN_DIR}/cmake")
|
|||
macro(AddCMakeTest TestName PreArgs)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${TestName}Test.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${TestName}Test.cmake" @ONLY IMMEDIATE)
|
||||
add_test(CMake.${TestName} ${CMAKE_EXECUTABLE} ${PreArgs}
|
||||
add_test(NAME CMake.${TestName}
|
||||
COMMAND ${CMAKE_EXECUTABLE} ${PreArgs}
|
||||
-P "${CMAKE_CURRENT_BINARY_DIR}/${TestName}Test.cmake" ${ARGN})
|
||||
endmacro()
|
||||
|
||||
|
@ -28,7 +29,7 @@ AddCMakeTest(String "")
|
|||
AddCMakeTest(Math "")
|
||||
AddCMakeTest(CMakeMinimumRequired "")
|
||||
AddCMakeTest(CompilerIdVendor "")
|
||||
AddCMakeTest(ProcessorCount "")
|
||||
AddCMakeTest(ProcessorCount "-DKWSYS_TEST_EXE=$<TARGET_FILE:cmsysTestsCxx>")
|
||||
AddCMakeTest(PushCheckState "")
|
||||
AddCMakeTest(While "")
|
||||
|
||||
|
|
|
@ -9,10 +9,17 @@ message("### 3. ProcessorCount(...) function call is emitting output that it sho
|
|||
message("processor_count='${processor_count}'")
|
||||
|
||||
execute_process(
|
||||
COMMAND "@CMAKE_BINARY_DIR@/Source/kwsys/$ENV{CMAKE_CONFIG_TYPE}/cmsysTestsCxx"
|
||||
COMMAND "${KWSYS_TEST_EXE}"
|
||||
testSystemInformation
|
||||
OUTPUT_VARIABLE tsi_out
|
||||
ERROR_VARIABLE tsi_err)
|
||||
ERROR_VARIABLE tsi_err
|
||||
RESULT_VARIABLE tsi_res
|
||||
)
|
||||
if (tsi_res)
|
||||
message("executing \"${KWSYS_TEST_EXE}\" failed")
|
||||
message(FATAL_ERROR "output: ${tsi_res}")
|
||||
endif ()
|
||||
|
||||
string(REGEX REPLACE "(.*)GetNumberOfPhysicalCPU:.([0-9]*)(.*)" "\\2"
|
||||
system_info_processor_count "${tsi_out}")
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(CompatibleInterface)
|
||||
|
||||
include(GenerateExportHeader)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
add_library(iface1 empty.cpp)
|
||||
set_property(TARGET iface1 APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_BOOL
|
||||
BOOL_PROP1
|
||||
BOOL_PROP2
|
||||
BOOL_PROP3
|
||||
BOOL_PROP4
|
||||
)
|
||||
set_property(TARGET iface1 APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_STRING
|
||||
STRING_PROP1
|
||||
STRING_PROP2
|
||||
STRING_PROP3
|
||||
)
|
||||
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON)
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON)
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1)
|
||||
set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP2 prop2)
|
||||
|
||||
add_executable(CompatibleInterface main.cpp)
|
||||
target_link_libraries(CompatibleInterface iface1)
|
||||
|
||||
set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP2 ON)
|
||||
set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP3 ON)
|
||||
set_property(TARGET CompatibleInterface PROPERTY STRING_PROP2 prop2)
|
||||
set_property(TARGET CompatibleInterface PROPERTY STRING_PROP3 prop3)
|
||||
|
||||
target_compile_definitions(CompatibleInterface
|
||||
PRIVATE
|
||||
$<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP1>>:BOOL_PROP1>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP2>>:BOOL_PROP2>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP3>>:BOOL_PROP3>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP1>,prop1>:STRING_PROP1>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP2>,prop2>:STRING_PROP2>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP3>,prop3>:STRING_PROP3>
|
||||
)
|
||||
|
||||
|
||||
add_library(iface2 SHARED iface2.cpp)
|
||||
generate_export_header(iface2)
|
||||
|
||||
set_property(TARGET iface2 APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_STRING
|
||||
Iface2_PROP
|
||||
)
|
||||
|
||||
# For the LINK_LIBRARIES and related properties, we should not evaluate
|
||||
# properties defined only in the interface - they should be implicitly zero
|
||||
set_property(TARGET iface2
|
||||
APPEND PROPERTY
|
||||
LINK_INTERFACE_LIBRARIES $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP4>>:nonexistant>
|
||||
)
|
||||
target_link_libraries(CompatibleInterface iface2
|
||||
$<$<BOOL:$<TARGET_PROPERTY:Iface2_PROP>>:nonexistant>
|
||||
)
|
||||
# Test that this does not segfault:
|
||||
target_compile_definitions(CompatibleInterface
|
||||
PRIVATE
|
||||
$<$<BOOL:$<TARGET_PROPERTY:Iface2_PROP>>:SOME_DEFINE>
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
// no content
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "iface2.h"
|
||||
|
||||
int Iface2::foo()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#ifndef IFACE2_H
|
||||
#define IFACE2_H
|
||||
|
||||
#include "iface2_export.h"
|
||||
|
||||
class IFACE2_EXPORT Iface2
|
||||
{
|
||||
public:
|
||||
int foo();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
#ifndef BOOL_PROP1
|
||||
#error Expected BOOL_PROP1
|
||||
#endif
|
||||
|
||||
#ifndef BOOL_PROP2
|
||||
#error Expected BOOL_PROP2
|
||||
#endif
|
||||
|
||||
#ifndef BOOL_PROP3
|
||||
#error Expected BOOL_PROP3
|
||||
#endif
|
||||
|
||||
#ifndef STRING_PROP1
|
||||
#error Expected STRING_PROP1
|
||||
#endif
|
||||
|
||||
#ifndef STRING_PROP2
|
||||
#error Expected STRING_PROP2
|
||||
#endif
|
||||
|
||||
#ifndef STRING_PROP3
|
||||
#error Expected STRING_PROP3
|
||||
#endif
|
||||
|
||||
#include "iface2.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Iface2 if2;
|
||||
return if2.foo();
|
||||
}
|
|
@ -90,32 +90,23 @@ set_property(TARGET testLibCycleA PROPERTY LINK_INTERFACE_MULTIPLICITY 3)
|
|||
# Test exporting dependent libraries into different exports
|
||||
add_library(testLibRequired testLibRequired.c)
|
||||
add_library(testLibDepends testLibDepends.c)
|
||||
set_property(TARGET testLibDepends APPEND PROPERTY
|
||||
INCLUDE_DIRECTORIES
|
||||
$<TARGET_PROPERTY:testLibRequired,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
set_property(TARGET testLibDepends APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS
|
||||
$<TARGET_PROPERTY:testLibRequired,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
set_property(TARGET testLibDepends APPEND PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES
|
||||
$<TARGET_PROPERTY:testLibRequired,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
set_property(TARGET testLibDepends APPEND PROPERTY
|
||||
INTERFACE_COMPILE_DEFINITIONS
|
||||
$<TARGET_PROPERTY:testLibRequired,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
target_link_libraries(testLibDepends testLibRequired)
|
||||
target_link_libraries(testLibDepends LINK_PUBLIC testLibRequired)
|
||||
|
||||
macro(add_include_lib _libName)
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c" "// no content\n")
|
||||
add_library(${_libName} "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c")
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_libName}")
|
||||
set_property(TARGET ${_libName} APPEND PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/${_libName}")
|
||||
INTERFACE_INCLUDE_DIRECTORIES
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/${_libName}>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/${_libName}>"
|
||||
)
|
||||
if (NOT "${ARGV1}" STREQUAL "NO_HEADER")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h" "// no content\n")
|
||||
install(FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h"
|
||||
DESTINATION include/${_libName}
|
||||
)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
@ -129,6 +120,10 @@ add_include_lib(testLibIncludeRequired3 NO_HEADER)
|
|||
# but we are testing that the INSTALL_INTERFACE causes it not to be used
|
||||
# at build time.
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired3/testLibIncludeRequired4.h" "#error Should not be included\n")
|
||||
install(FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired3/testLibIncludeRequired4.h"
|
||||
DESTINATION include/testLibIncludeRequired3
|
||||
)
|
||||
add_include_lib(testLibIncludeRequired4)
|
||||
add_include_lib(testLibIncludeRequired5 NO_HEADER)
|
||||
# Generate testLibIncludeRequired6 in the testLibIncludeRequired5 directory
|
||||
|
@ -139,6 +134,10 @@ add_include_lib(testLibIncludeRequired5 NO_HEADER)
|
|||
# the Import side of this unit test, the '6' include from the '5' directory
|
||||
# will not be used because it is in the BUILD_INTERFACE only.
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired5/testLibIncludeRequired6.h" "#error Should not be included\n")
|
||||
install(FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired5/testLibIncludeRequired6.h"
|
||||
DESTINATION include/testLibIncludeRequired5
|
||||
)
|
||||
add_include_lib(testLibIncludeRequired6)
|
||||
|
||||
set_property(TARGET testLibRequired APPEND PROPERTY
|
||||
|
@ -149,6 +148,8 @@ set_property(TARGET testLibRequired APPEND PROPERTY
|
|||
$<BUILD_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired4,INTERFACE_INCLUDE_DIRECTORIES>>
|
||||
$<BUILD_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired5,INTERFACE_INCLUDE_DIRECTORIES>>
|
||||
$<INSTALL_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired6,INTERFACE_INCLUDE_DIRECTORIES>>
|
||||
# Test that the below is non-fatal
|
||||
$<$<TARGET_DEFINED:not_a_target>:$<TARGET_PROPERTY:not_a_target,INTERFACE_INCLUDE_DIRECTORIES>>
|
||||
)
|
||||
|
||||
set_property(TARGET testLibRequired APPEND PROPERTY
|
||||
|
@ -173,6 +174,22 @@ set_property(TARGET testSharedLibRequired APPEND PROPERTY
|
|||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
)
|
||||
set_property(TARGET testSharedLibRequired
|
||||
APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_BOOL CUSTOM_PROP
|
||||
)
|
||||
set_property(TARGET testSharedLibRequired
|
||||
PROPERTY
|
||||
INTERFACE_CUSTOM_PROP ON
|
||||
)
|
||||
set_property(TARGET testSharedLibRequired
|
||||
APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_STRING CUSTOM_STRING
|
||||
)
|
||||
set_property(TARGET testSharedLibRequired
|
||||
PROPERTY
|
||||
INTERFACE_CUSTOM_STRING testcontent
|
||||
)
|
||||
|
||||
add_library(testSharedLibDepends SHARED testSharedLibDepends.cpp)
|
||||
set_property(TARGET testSharedLibDepends APPEND PROPERTY
|
||||
|
@ -201,11 +218,30 @@ install(TARGETS testLibRequired
|
|||
testLibIncludeRequired6
|
||||
testSharedLibRequired
|
||||
EXPORT RequiredExp DESTINATION lib )
|
||||
install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredConfig.cmake DESTINATION lib/cmake/testLibRequired)
|
||||
install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredTargets.cmake DESTINATION lib/cmake/testLibRequired)
|
||||
|
||||
install(TARGETS testLibDepends testSharedLibDepends EXPORT DependsExp DESTINATION lib )
|
||||
install(EXPORT DependsExp FILE testLibDependsConfig.cmake DESTINATION lib/cmake/testLibDepends)
|
||||
install(EXPORT DependsExp FILE testLibDependsTargets.cmake DESTINATION lib/cmake/testLibDepends)
|
||||
|
||||
file(WRITE
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/testLibRequiredConfig.cmake"
|
||||
"
|
||||
if(\${CMAKE_FIND_PACKAGE_NAME}_FIND_VERSION VERSION_LESS 2.3 AND NOT \${CMAKE_FIND_PACKAGE_NAME}_INTERFACES)
|
||||
set(\${CMAKE_FIND_PACKAGE_NAME}_NO_INTERFACES 1)
|
||||
endif()
|
||||
include(\"\${CMAKE_CURRENT_LIST_DIR}/testLibRequiredTargets.cmake\")
|
||||
set(\${CMAKE_FIND_PACKAGE_NAME}_INCLUDE_DIRS \"${CMAKE_CURRENT_BINARY_DIR}\" \"${CMAKE_CURRENT_SOURCE_DIR}\" )
|
||||
"
|
||||
)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file( testLibRequiredConfigVersion.cmake VERSION 2.5 COMPATIBILITY AnyNewerVersion)
|
||||
|
||||
install(FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/testLibRequiredConfig.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/testLibRequiredConfigVersion.cmake"
|
||||
DESTINATION lib/cmake/testLibRequired
|
||||
)
|
||||
|
||||
# Install and export from install tree.
|
||||
install(
|
||||
|
|
|
@ -5,8 +5,8 @@ include(${Import_BINARY_DIR}/../Export/ExportBuildTree.cmake)
|
|||
include(${CMAKE_INSTALL_PREFIX}/lib/exp/exp.cmake)
|
||||
|
||||
# Import two exports, where the Depends one depends on an exported target from the Required one:
|
||||
include(${CMAKE_INSTALL_PREFIX}/lib/cmake/testLibRequired/testLibRequiredConfig.cmake)
|
||||
include(${CMAKE_INSTALL_PREFIX}/lib/cmake/testLibDepends/testLibDependsConfig.cmake)
|
||||
include(${CMAKE_INSTALL_PREFIX}/lib/cmake/testLibRequired/testLibRequiredTargets.cmake)
|
||||
include(${CMAKE_INSTALL_PREFIX}/lib/cmake/testLibDepends/testLibDependsTargets.cmake)
|
||||
|
||||
# Try referencing an executable imported from the install tree.
|
||||
add_custom_command(
|
||||
|
@ -159,13 +159,15 @@ endif()
|
|||
|
||||
add_executable(deps_iface deps_iface.c)
|
||||
target_link_libraries(deps_iface testLibDepends)
|
||||
target_include_directories(deps_iface PRIVATE testLibDepends)
|
||||
target_compile_definitions(deps_iface PRIVATE testLibDepends)
|
||||
|
||||
add_executable(deps_shared_iface deps_shared_iface.cpp)
|
||||
target_link_libraries(deps_shared_iface testSharedLibDepends)
|
||||
target_include_directories(deps_shared_iface PRIVATE testSharedLibDepends)
|
||||
target_compile_definitions(deps_shared_iface PRIVATE testSharedLibDepends)
|
||||
target_compile_definitions(deps_shared_iface
|
||||
PRIVATE
|
||||
$<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:CUSTOM_PROP>>:CUSTOM_PROPERTY_IS_ON>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH>
|
||||
)
|
||||
|
||||
if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
@ -191,7 +193,9 @@ endif()
|
|||
|
||||
add_executable(deps_shared_iface2 deps_shared_iface.cpp)
|
||||
target_link_libraries(deps_shared_iface2 bld_testSharedLibDepends bld_subdirlib)
|
||||
target_include_directories(deps_shared_iface2 PRIVATE bld_testSharedLibDepends bld_subdirlib)
|
||||
target_compile_definitions(deps_shared_iface2
|
||||
PRIVATE bld_testSharedLibDepends TEST_SUBDIR_LIB
|
||||
PRIVATE TEST_SUBDIR_LIB
|
||||
$<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:CUSTOM_PROP>>:CUSTOM_PROPERTY_IS_ON>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH>
|
||||
)
|
||||
|
|
|
@ -8,6 +8,18 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef PIC_PROPERTY_IS_ON
|
||||
#error Expected PIC_PROPERTY_IS_ON
|
||||
#endif
|
||||
|
||||
#ifndef CUSTOM_PROPERTY_IS_ON
|
||||
#error Expected CUSTOM_PROPERTY_IS_ON
|
||||
#endif
|
||||
|
||||
#ifndef CUSTOM_STRING_IS_MATCH
|
||||
#error Expected CUSTOM_STRING_IS_MATCH
|
||||
#endif
|
||||
|
||||
#ifdef TEST_SUBDIR_LIB
|
||||
#include "subdir.h"
|
||||
#endif
|
||||
|
|
|
@ -17,3 +17,8 @@ add_executable(imp_testTransExe1 imp_testTransExe1.c)
|
|||
target_link_libraries(imp_testTransExe1 imp_lib1)
|
||||
add_executable(imp_testTransExe1b imp_testTransExe1.c)
|
||||
target_link_libraries(imp_testTransExe1b imp_lib1b)
|
||||
|
||||
# Test package INTERFACE controls
|
||||
add_subdirectory(package_old_old)
|
||||
add_subdirectory(package_new_old)
|
||||
add_subdirectory(package_new_new)
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
find_package(testLibRequired 2.5 REQUIRED)
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
|
||||
"
|
||||
#include \"testSharedLibRequired.h\"
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
TestSharedLibRequired req;
|
||||
return req.foo();
|
||||
}
|
||||
"
|
||||
)
|
||||
|
||||
get_target_property(prop Req::testSharedLibRequired INTERFACE_INCLUDE_DIRECTORIES)
|
||||
if (NOT prop)
|
||||
message(SEND_ERROR "Interface of Req::testSharedLibRequired should not be empty")
|
||||
endif()
|
||||
|
||||
add_executable(new_new_test "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
|
||||
target_link_libraries(new_new_test Req::testSharedLibRequired)
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
find_package(testLibRequired 2.5 REQUIRED)
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
|
||||
"
|
||||
#include \"testSharedLibRequired.h\"
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
TestSharedLibRequired req;
|
||||
return req.foo();
|
||||
}
|
||||
"
|
||||
)
|
||||
|
||||
get_target_property(prop Req::testSharedLibRequired INTERFACE_INCLUDE_DIRECTORIES)
|
||||
if ("${prop}" STREQUAL "")
|
||||
message(SEND_ERROR "Interface of Req::testSharedLibRequired should not be empty")
|
||||
endif()
|
||||
|
||||
add_executable(new_old_test "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
|
||||
target_link_libraries(new_old_test Req::testSharedLibRequired)
|
||||
include_directories(${testLibRequired_INCLUDE_DIRS})
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
find_package(testLibRequired 2.1 REQUIRED)
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
|
||||
"
|
||||
#include \"testSharedLibRequired.h\"
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
TestSharedLibRequired req;
|
||||
return req.foo();
|
||||
}
|
||||
"
|
||||
)
|
||||
|
||||
get_target_property(prop Req::testSharedLibRequired INTERFACE_INCLUDE_DIRECTORIES)
|
||||
if (prop)
|
||||
message(SEND_ERROR "Interface of Req::testSharedLibRequired should be empty, but is ${prop}")
|
||||
endif()
|
||||
|
||||
add_executable(old_old_test "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
|
||||
target_link_libraries(old_old_test Req::testSharedLibRequired)
|
||||
include_directories(${testLibRequired_INCLUDE_DIRS})
|
|
@ -50,6 +50,8 @@ if(NOT DEFINED can_build_tutorial_step5)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
add_custom_target(NonExternalProjectTarget
|
||||
COMMAND ${CMAKE_COMMAND} -E echo NonExternalProjectTarget)
|
||||
|
||||
# Empty projects that test all the known ExternalProject_Add argument key words:
|
||||
#
|
||||
|
@ -94,7 +96,7 @@ ExternalProject_Add(${proj}
|
|||
CVS_REPOSITORY ""
|
||||
CVS_MODULE ""
|
||||
CVS_TAG ""
|
||||
DEPENDS "MinimalNoOpProject"
|
||||
DEPENDS "MinimalNoOpProject" NonExternalProjectTarget
|
||||
DOWNLOAD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
PATCH_COMMAND ""
|
||||
|
|
|
@ -82,3 +82,44 @@ add_custom_target(test_custom_target
|
|||
$<TARGET_PROPERTY:TargetIncludeDirectories,COMPILE_DEFINITIONS>
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bad")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/bad/common.h" "#error Should not be included\n")
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/good")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/good/common.h" "#include \"othergood.h\"\n")
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/othergood")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/othergood/othergood.h" "// No error\n")
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libothergood.cpp" "// No content \n")
|
||||
add_library(libothergood "${CMAKE_CURRENT_BINARY_DIR}/libothergood.cpp")
|
||||
set_property(TARGET libothergood APPEND PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/othergood"
|
||||
)
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libgood.cpp" "// No content \n")
|
||||
add_library(libgood "${CMAKE_CURRENT_BINARY_DIR}/libgood.cpp")
|
||||
set_property(TARGET libgood APPEND PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/good;$<TARGET_PROPERTY:libothergood,INTERFACE_INCLUDE_DIRECTORIES>"
|
||||
)
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libbad.cpp" "// No content \n")
|
||||
add_library(libbad "${CMAKE_CURRENT_BINARY_DIR}/libbad.cpp")
|
||||
set_property(TARGET libbad APPEND PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/bad"
|
||||
)
|
||||
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib5.cpp" "#include \"common.h\"\n")
|
||||
add_library(lib5 "${CMAKE_CURRENT_BINARY_DIR}/lib5.cpp")
|
||||
|
||||
# Assuming the link order must be:
|
||||
target_link_libraries(lib5 libbad libgood)
|
||||
|
||||
# Oops!.
|
||||
# As include directory order and link order are the same when using target_link_libraries, we have to
|
||||
# get the libgood includes in before the libbad includes.
|
||||
# We do that with this command:
|
||||
target_include_directories(lib5
|
||||
BEFORE PRIVATE $<LINKED:libgood>
|
||||
)
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
cmake_minimum_required(VERSION 2.8.10.20130115)
|
||||
project(ExternalDataTest NONE)
|
||||
|
||||
include(CTest)
|
||||
|
||||
include(ExternalData)
|
||||
|
||||
if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" MATCHES "^/")
|
||||
set(slash /)
|
||||
endif()
|
||||
set(ExternalData_URL_TEMPLATES
|
||||
"file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/%(algo)/%(hash)"
|
||||
)
|
||||
set(ExternalData_BINARY_ROOT "${CMAKE_CURRENT_BINARY_DIR}/ExternalData")
|
||||
file(REMOVE_RECURSE ${ExternalData_BINARY_ROOT}) # clean test
|
||||
|
||||
ExternalData_Add_Test(Data1
|
||||
NAME Data1Check
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D Data=DATA{Data.dat}
|
||||
-D SeriesA=DATA{SeriesA.dat,:}
|
||||
-D SeriesB=DATA{SeriesB.dat,:}
|
||||
-D SeriesC=DATA{SeriesC.dat,:}
|
||||
-D SeriesD=DATA{SeriesD.dat,:}
|
||||
-D SeriesAn=DATA{SeriesAn1.dat,:}
|
||||
-D SeriesBn=DATA{SeriesBn_1.dat,:}
|
||||
-D SeriesCn=DATA{SeriesCn.1.dat,:}
|
||||
-D SeriesDn=DATA{SeriesDn-1.dat,:}
|
||||
-D SeriesMixed=DATA{SeriesMixed.1.dat,:}
|
||||
-D Paired=DATA{PairedA.dat,PairedB.dat}
|
||||
-D Meta=DATA{MetaTop.dat,REGEX:Meta[ABC].dat}
|
||||
-D Directory=DATA{Directory/,A.dat,REGEX:[BC].dat}
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/Data1Check.cmake
|
||||
)
|
||||
ExternalData_Add_Target(Data1)
|
||||
|
||||
add_subdirectory(Data2)
|
||||
add_subdirectory(Data3)
|
|
@ -0,0 +1 @@
|
|||
8c018830e3efa5caf3c7415028335a57
|
|
@ -0,0 +1,52 @@
|
|||
file(STRINGS "${Data}" lines LIMIT_INPUT 1024)
|
||||
if(NOT "x${lines}" STREQUAL "xInput file already transformed.")
|
||||
message(SEND_ERROR "Input file:\n ${Data}\ndoes not have expected content, but [[${lines}]]")
|
||||
endif()
|
||||
set(SeriesAn1 "1\\.dat")
|
||||
set(SeriesBn1 "_1\\.dat")
|
||||
set(SeriesCn1 "\\.1\\.dat")
|
||||
set(SeriesDn1 "-1\\.dat")
|
||||
set(SeriesAl 1 2 3)
|
||||
set(SeriesBl _1 _2 _3)
|
||||
set(SeriesCl .1 .2 .3)
|
||||
set(SeriesDl -1 -2 -3)
|
||||
foreach(s A B C D)
|
||||
foreach(n "" ${Series${s}l})
|
||||
string(REGEX REPLACE "\\.dat$" "${n}.dat" file "${Series${s}}")
|
||||
if(NOT EXISTS "${file}")
|
||||
message(SEND_ERROR "Input file:\n ${file}\ndoes not exist!")
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
foreach(s A B C D)
|
||||
foreach(n ${Series${s}l})
|
||||
string(REGEX REPLACE "${Series${s}n1}$" "${n}.dat" file "${Series${s}n}")
|
||||
if(NOT EXISTS "${file}")
|
||||
message(SEND_ERROR "Input file:\n ${file}\ndoes not exist!")
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
foreach(n .1 .2 .3 .4)
|
||||
string(REGEX REPLACE "\\.1\\.dat$" "${n}.dat" file "${SeriesMixed}")
|
||||
if(NOT EXISTS "${file}")
|
||||
message(SEND_ERROR "Input file:\n ${file}\ndoes not exist!")
|
||||
endif()
|
||||
endforeach()
|
||||
foreach(n A B)
|
||||
string(REGEX REPLACE "A\\.dat$" "${n}.dat" file "${Paired}")
|
||||
if(NOT EXISTS "${file}")
|
||||
message(SEND_ERROR "Input file:\n ${file}\ndoes not exist!")
|
||||
endif()
|
||||
endforeach()
|
||||
foreach(n Top A B C)
|
||||
string(REGEX REPLACE "Top\\.dat$" "${n}.dat" file "${Meta}")
|
||||
if(NOT EXISTS "${file}")
|
||||
message(SEND_ERROR "Input file:\n ${file}\ndoes not exist!")
|
||||
endif()
|
||||
endforeach()
|
||||
foreach(n A B C)
|
||||
set(file "${Directory}/${n}.dat")
|
||||
if(NOT EXISTS "${file}")
|
||||
message(SEND_ERROR "Input file:\n ${file}\ndoes not exist!")
|
||||
endif()
|
||||
endforeach()
|
|
@ -0,0 +1 @@
|
|||
8c018830e3efa5caf3c7415028335a57
|
|
@ -0,0 +1,11 @@
|
|||
set(ExternalData_SERIES_PARSE "([0-9]+)(_\\.my\\.dat)$")
|
||||
set(ExternalData_SERIES_MATCH "([0-9]+)")
|
||||
ExternalData_Add_Test(Data2
|
||||
NAME Data2Check
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D Data2=DATA{../Data2.dat}
|
||||
-D Data2b=DATA{${CMAKE_CURRENT_SOURCE_DIR}/../Data2b.dat}
|
||||
-D SeriesC=DATA{SeriesC_1_.my.dat,:}
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/Data2Check.cmake
|
||||
)
|
||||
ExternalData_Add_Target(Data2)
|
|
@ -0,0 +1,12 @@
|
|||
foreach(d "${Data2}" "${Data2b}")
|
||||
file(STRINGS "${d}" lines LIMIT_INPUT 1024)
|
||||
if(NOT "x${lines}" STREQUAL "xInput file already transformed.")
|
||||
message(SEND_ERROR "Input file:\n ${d}\ndoes not have expected content, but [[${lines}]]")
|
||||
endif()
|
||||
endforeach()
|
||||
foreach(n 1 2 3)
|
||||
string(REGEX REPLACE "_1_\\.my\\.dat$" "_${n}_.my.dat" SeriesCFile "${SeriesC}")
|
||||
if(NOT EXISTS "${SeriesCFile}")
|
||||
message(SEND_ERROR "Input file:\n ${SeriesCFile}\ndoes not exist!")
|
||||
endif()
|
||||
endforeach()
|
|
@ -0,0 +1 @@
|
|||
31eff09e84fca01415f8cd9d82ec432b
|
|
@ -0,0 +1 @@
|
|||
f7ab5a04aae9cb9a520e70b20b9c8ed7
|
|
@ -0,0 +1 @@
|
|||
30ba0acdee9096b3b9fc6c69362c6b42
|
|
@ -0,0 +1 @@
|
|||
8c018830e3efa5caf3c7415028335a57
|
|
@ -0,0 +1,14 @@
|
|||
set(Store0 ${CMAKE_BINARY_DIR}/ExternalData/Other)
|
||||
set(Store1 ${CMAKE_BINARY_DIR}/ExternalData/Objects)
|
||||
set(ExternalData_OBJECT_STORES ${Store0} ${Store1})
|
||||
ExternalData_Add_Test(Data3
|
||||
NAME Data3Check
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D Data=DATA{Data.dat}
|
||||
-D Other=DATA{Other.dat}
|
||||
-D Store0=${Store0}
|
||||
-D Store1=${Store1}
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/Data3Check.cmake
|
||||
)
|
||||
ExternalData_Add_Target(Data3)
|
||||
add_dependencies(Data3 Data1 Data2)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue