Merge branch 'xcode-duplicate-flags-13354' into generator-toolset
This commit is contained in:
commit
118c32f8f2
|
@ -234,8 +234,6 @@ macro (CMAKE_BUILD_UTILITIES)
|
|||
set(kwsys_folder "Utilities/KWSys")
|
||||
CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE} "${kwsys_folder}")
|
||||
CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}_c "${kwsys_folder}")
|
||||
CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}EncodeExecutable "${kwsys_folder}")
|
||||
CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}ProcessFwd9x "${kwsys_folder}")
|
||||
if(BUILD_TESTING)
|
||||
CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}TestDynload "${kwsys_folder}")
|
||||
CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}TestProcess "${kwsys_folder}")
|
||||
|
@ -590,10 +588,10 @@ if(NOT CMake_VERSION_IS_RELEASE)
|
|||
NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS 4.2)
|
||||
set(C_FLAGS_LIST -Wcast-align -Werror-implicit-function-declaration -Wchar-subscripts
|
||||
-Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security
|
||||
-Wmissing-format-attribute -fno-common
|
||||
-Wmissing-format-attribute -fno-common -Wundef
|
||||
)
|
||||
set(CXX_FLAGS_LIST -Wnon-virtual-dtor -Wcast-align -Wchar-subscripts -Wall -W
|
||||
-Wshadow -Wpointer-arith -Wformat-security
|
||||
-Wshadow -Wpointer-arith -Wformat-security -Wundef
|
||||
)
|
||||
|
||||
foreach(FLAG_LANG C CXX)
|
||||
|
|
|
@ -50,6 +50,7 @@ endif()
|
|||
|
||||
set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "@CMAKE_C_IMPLICIT_LINK_LIBRARIES@")
|
||||
set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_DIRECTORIES@")
|
||||
set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
|
||||
|
||||
@SET_CMAKE_CMCLDEPS_EXECUTABLE@
|
||||
@SET_CMAKE_CL_SHOWINCLUDE_PREFIX@
|
||||
|
|
|
@ -51,6 +51,7 @@ endif()
|
|||
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "@CMAKE_CXX_IMPLICIT_LINK_LIBRARIES@")
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES@")
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
|
||||
|
||||
@SET_CMAKE_CMCLDEPS_EXECUTABLE@
|
||||
@SET_CMAKE_CL_SHOWINCLUDE_PREFIX@
|
||||
|
|
|
@ -72,19 +72,9 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
|
|||
# Parse implicit linker information for this language, if available.
|
||||
set(implicit_dirs "")
|
||||
set(implicit_libs "")
|
||||
set(MULTI_ARCH FALSE)
|
||||
if(DEFINED CMAKE_OSX_ARCHITECTURES)
|
||||
if( "${CMAKE_OSX_ARCHITECTURES}" MATCHES ";" )
|
||||
set(MULTI_ARCH TRUE)
|
||||
endif()
|
||||
endif()
|
||||
if(CMAKE_${lang}_VERBOSE_FLAG
|
||||
# Implicit link information cannot be used explicitly for
|
||||
# multiple OS X architectures, so we skip it.
|
||||
AND NOT MULTI_ARCH
|
||||
# Skip this with Xcode for now.
|
||||
AND NOT "${CMAKE_GENERATOR}" MATCHES Xcode)
|
||||
CMAKE_PARSE_IMPLICIT_LINK_INFO("${OUTPUT}" implicit_libs implicit_dirs log
|
||||
set(implicit_fwks "")
|
||||
if(CMAKE_${lang}_VERBOSE_FLAG)
|
||||
CMAKE_PARSE_IMPLICIT_LINK_INFO("${OUTPUT}" implicit_libs implicit_dirs implicit_fwks log
|
||||
"${CMAKE_${lang}_IMPLICIT_OBJECT_REGEX}")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Parsed ${lang} implicit link information from above output:\n${log}\n\n")
|
||||
|
@ -112,8 +102,17 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
|
|||
message(STATUS "${_desc}")
|
||||
endif()
|
||||
|
||||
# Implicit link libraries cannot be used explicitly for multiple
|
||||
# OS X architectures, so we skip it.
|
||||
if(DEFINED CMAKE_OSX_ARCHITECTURES)
|
||||
if("${CMAKE_OSX_ARCHITECTURES}" MATCHES ";")
|
||||
set(implicit_libs "")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CMAKE_${lang}_IMPLICIT_LINK_LIBRARIES "${implicit_libs}" PARENT_SCOPE)
|
||||
set(CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES "${implicit_dirs}" PARENT_SCOPE)
|
||||
set(CMAKE_${lang}_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "${implicit_fwks}" PARENT_SCOPE)
|
||||
|
||||
# Detect library architecture directory name.
|
||||
if(CMAKE_LIBRARY_ARCHITECTURE_REGEX)
|
||||
|
|
|
@ -52,3 +52,4 @@ endif()
|
|||
|
||||
set(CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES "@CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES@")
|
||||
set(CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES "@CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES@")
|
||||
set(CMAKE_Fortran_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_Fortran_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
|
||||
|
|
|
@ -74,12 +74,8 @@
|
|||
PRINT *, 'INFO:platform[IRIX]'
|
||||
#elif defined(__hpux) || defined(__hpux__)
|
||||
PRINT *, 'INFO:platform[HP-UX]'
|
||||
#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU)
|
||||
#elif defined(__HAIKU__)
|
||||
PRINT *, 'INFO:platform[Haiku]'
|
||||
# if 0
|
||||
! Haiku also defines __BEOS__ so we must
|
||||
! put it prior to the check for __BEOS__
|
||||
# endif
|
||||
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
|
||||
PRINT *, 'INFO:platform[BeOS]'
|
||||
#elif defined(__QNX__) || defined(__QNXNTO__)
|
||||
|
|
|
@ -188,8 +188,13 @@ function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
|
|||
endif()
|
||||
endforeach()
|
||||
|
||||
get_filename_component(inputFileName "${_inputFile}" NAME)
|
||||
|
||||
set(PACKAGE_INIT "
|
||||
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
|
||||
####### Any changes to this file will be overwritten by the next CMake run ####
|
||||
####### The input file was ${inputFileName} ########
|
||||
|
||||
get_filename_component(PACKAGE_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/${PACKAGE_RELATIVE_PATH}\" ABSOLUTE)
|
||||
")
|
||||
|
||||
|
|
|
@ -16,9 +16,10 @@
|
|||
# This is used internally by CMake and should not be included by user
|
||||
# code.
|
||||
|
||||
function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex)
|
||||
function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj_regex)
|
||||
set(implicit_libs_tmp "")
|
||||
set(implicit_dirs_tmp)
|
||||
set(implicit_fwks_tmp)
|
||||
set(log "")
|
||||
|
||||
# Parse implicit linker arguments.
|
||||
|
@ -36,6 +37,16 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex)
|
|||
set(cmd)
|
||||
if("${line}" MATCHES "${linker_regex}" AND
|
||||
NOT "${line}" MATCHES "${linker_exclude_regex}")
|
||||
if(XCODE)
|
||||
# Xcode unconditionally adds a path under the project build tree and
|
||||
# on older versions it is not reported with proper quotes. Remove it.
|
||||
string(REGEX REPLACE "([][+.*()^])" "\\\\\\1" _dir_regex "${CMAKE_BINARY_DIR}")
|
||||
string(REGEX REPLACE " -[FL]${_dir_regex}/([^ ]| [^-])+( |$)" " " xline "${line}")
|
||||
if(NOT "x${xline}" STREQUAL "x${line}")
|
||||
set(log "${log} reduced line: [${line}]\n to: [${xline}]\n")
|
||||
set(line "${xline}")
|
||||
endif()
|
||||
endif()
|
||||
if(UNIX)
|
||||
separate_arguments(args UNIX_COMMAND "${line}")
|
||||
else()
|
||||
|
@ -97,6 +108,18 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex)
|
|||
endif()
|
||||
endforeach()
|
||||
|
||||
# Look for library search paths reported by linker.
|
||||
if("${output_lines}" MATCHES ";Library search paths:((;\t[^;]+)+)")
|
||||
string(REPLACE ";\t" ";" implicit_dirs_match "${CMAKE_MATCH_1}")
|
||||
set(log "${log} Library search paths: [${implicit_dirs_match}]\n")
|
||||
list(APPEND implicit_dirs_tmp ${implicit_dirs_match})
|
||||
endif()
|
||||
if("${output_lines}" MATCHES ";Framework search paths:((;\t[^;]+)+)")
|
||||
string(REPLACE ";\t" ";" implicit_fwks_match "${CMAKE_MATCH_1}")
|
||||
set(log "${log} Framework search paths: [${implicit_fwks_match}]\n")
|
||||
list(APPEND implicit_fwks_tmp ${implicit_fwks_match})
|
||||
endif()
|
||||
|
||||
# Cleanup list of libraries and flags.
|
||||
# We remove items that are not language-specific.
|
||||
set(implicit_libs "")
|
||||
|
@ -108,21 +131,33 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex)
|
|||
endif()
|
||||
endforeach()
|
||||
|
||||
# Cleanup list of directories.
|
||||
set(implicit_dirs "")
|
||||
foreach(d IN LISTS implicit_dirs_tmp)
|
||||
get_filename_component(dir "${d}" ABSOLUTE)
|
||||
list(APPEND implicit_dirs "${dir}")
|
||||
set(log "${log} collapse dir [${d}] ==> [${dir}]\n")
|
||||
# Cleanup list of library and framework directories.
|
||||
set(desc_dirs "library")
|
||||
set(desc_fwks "framework")
|
||||
foreach(t dirs fwks)
|
||||
set(implicit_${t} "")
|
||||
foreach(d IN LISTS implicit_${t}_tmp)
|
||||
get_filename_component(dir "${d}" ABSOLUTE)
|
||||
string(FIND "${dir}" "${CMAKE_FILES_DIRECTORY}/" pos)
|
||||
if(NOT pos LESS 0)
|
||||
set(msg ", skipping non-system directory")
|
||||
else()
|
||||
set(msg "")
|
||||
list(APPEND implicit_${t} "${dir}")
|
||||
endif()
|
||||
set(log "${log} collapse ${desc_${t}} dir [${d}] ==> [${dir}]${msg}\n")
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES implicit_${t})
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES implicit_dirs)
|
||||
|
||||
# Log results.
|
||||
set(log "${log} implicit libs: [${implicit_libs}]\n")
|
||||
set(log "${log} implicit dirs: [${implicit_dirs}]\n")
|
||||
set(log "${log} implicit fwks: [${implicit_fwks}]\n")
|
||||
|
||||
# Return results.
|
||||
set(${lib_var} "${implicit_libs}" PARENT_SCOPE)
|
||||
set(${dir_var} "${implicit_dirs}" PARENT_SCOPE)
|
||||
set(${fwk_var} "${implicit_fwks}" PARENT_SCOPE)
|
||||
set(${log_var} "${log}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
|
|
@ -35,11 +35,8 @@
|
|||
#elif defined(__hpux) || defined(__hpux__)
|
||||
# define PLATFORM_ID "HP-UX"
|
||||
|
||||
#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU)
|
||||
#elif defined(__HAIKU__)
|
||||
# define PLATFORM_ID "Haiku"
|
||||
/* Haiku also defines __BEOS__ so we must
|
||||
put it prior to the check for __BEOS__
|
||||
*/
|
||||
|
||||
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
|
||||
# define PLATFORM_ID "BeOS"
|
||||
|
|
|
@ -49,6 +49,32 @@
|
|||
# by the WiX Generator in case CPACK_RESOURCE_FILE_LICENSE
|
||||
# is in an unsupported format or the .txt -> .rtf
|
||||
# conversion does not work as expected.
|
||||
#
|
||||
##end
|
||||
#
|
||||
##variable
|
||||
# CPACK_WIX_PRODUCT_ICON - The Icon shown next to the program name in Add/Remove programs.
|
||||
#
|
||||
# If set, this icon is used in place of the default icon.
|
||||
#
|
||||
##end
|
||||
#
|
||||
##variable
|
||||
# CPACK_WIX_UI_BANNER - The bitmap will appear at the top of all installer pages other than the welcome and completion dialogs.
|
||||
#
|
||||
# If set, this image will replace the default banner image.
|
||||
#
|
||||
# This image must be 493 by 58 pixels.
|
||||
#
|
||||
##end
|
||||
#
|
||||
##variable
|
||||
# CPACK_WIX_UI_DIALOG - Background bitmap used on the welcome and completion dialogs.
|
||||
#
|
||||
# If this variable is set, the installer will replace the default dialog image.
|
||||
#
|
||||
# This image must be 493 by 312 pixels.
|
||||
#
|
||||
##end
|
||||
|
||||
#=============================================================================
|
||||
|
|
|
@ -16,7 +16,7 @@ int main(int ac, char*av[]){
|
|||
pthread_create(&tid[0], 0, runner, (void*)1);
|
||||
pthread_create(&tid[1], 0, runner, (void*)2);
|
||||
|
||||
#if defined(__BEOS__) && !defined(__ZETA__) && !defined(__HAIKU__) // (no usleep on BeOS 5.)
|
||||
#if defined(__BEOS__) && !defined(__ZETA__) // (no usleep on BeOS 5.)
|
||||
usleep(1); // for strange behavior on single-processor sun
|
||||
#endif
|
||||
|
||||
|
|
|
@ -40,25 +40,39 @@ else ()
|
|||
set(GLUT_cocoa_LIBRARY "-framework Cocoa" CACHE STRING "Cocoa framework for OSX")
|
||||
else ()
|
||||
|
||||
if (BEOS)
|
||||
|
||||
set(_GLUT_INC_DIR /boot/develop/headers/os/opengl)
|
||||
set(_GLUT_glut_LIB_DIR /boot/develop/lib/x86)
|
||||
|
||||
else()
|
||||
|
||||
find_library( GLUT_Xi_LIBRARY Xi
|
||||
/usr/openwin/lib
|
||||
)
|
||||
|
||||
find_library( GLUT_Xmu_LIBRARY Xmu
|
||||
/usr/openwin/lib
|
||||
)
|
||||
|
||||
endif ()
|
||||
|
||||
find_path( GLUT_INCLUDE_DIR GL/glut.h
|
||||
/usr/include/GL
|
||||
/usr/openwin/share/include
|
||||
/usr/openwin/include
|
||||
/opt/graphics/OpenGL/include
|
||||
/opt/graphics/OpenGL/contrib/libglut
|
||||
${_GLUT_INC_DIR}
|
||||
)
|
||||
|
||||
find_library( GLUT_glut_LIBRARY glut
|
||||
/usr/openwin/lib
|
||||
${_GLUT_glut_LIB_DIR}
|
||||
)
|
||||
|
||||
find_library( GLUT_Xi_LIBRARY Xi
|
||||
/usr/openwin/lib
|
||||
)
|
||||
|
||||
find_library( GLUT_Xmu_LIBRARY Xmu
|
||||
/usr/openwin/lib
|
||||
)
|
||||
unset(_GLUT_INC_DIR)
|
||||
unset(_GLUT_glut_LIB_DIR)
|
||||
|
||||
endif ()
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ find_library(LUA_LIBRARY
|
|||
|
||||
if(LUA_LIBRARY)
|
||||
# include the math library for Unix
|
||||
if(UNIX AND NOT APPLE)
|
||||
if(UNIX AND NOT APPLE AND NOT BEOS)
|
||||
find_library(LUA_MATH_LIBRARY m)
|
||||
set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
# For Windows and Mac, don't need to explicitly include the math library
|
||||
|
|
|
@ -58,14 +58,22 @@ else ()
|
|||
find_path(OPENGL_INCLUDE_DIR OpenGL/gl.h DOC "Include for OpenGL on OSX")
|
||||
|
||||
else()
|
||||
# Handle HP-UX cases where we only want to find OpenGL in either hpux64
|
||||
# or hpux32 depending on if we're doing a 64 bit build.
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(HPUX_IA_OPENGL_LIB_PATH /opt/graphics/OpenGL/lib/hpux32/)
|
||||
else()
|
||||
set(HPUX_IA_OPENGL_LIB_PATH
|
||||
/opt/graphics/OpenGL/lib/hpux64/
|
||||
/opt/graphics/OpenGL/lib/pa20_64)
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "HP-UX")
|
||||
# Handle HP-UX cases where we only want to find OpenGL in either hpux64
|
||||
# or hpux32 depending on if we're doing a 64 bit build.
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(_OPENGL_LIB_PATH
|
||||
/opt/graphics/OpenGL/lib/hpux32/)
|
||||
else()
|
||||
set(_OPENGL_LIB_PATH
|
||||
/opt/graphics/OpenGL/lib/hpux64/
|
||||
/opt/graphics/OpenGL/lib/pa20_64)
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL Haiku)
|
||||
set(_OPENGL_LIB_PATH
|
||||
/boot/develop/lib/x86)
|
||||
set(_OPENGL_INCLUDE_PATH
|
||||
/boot/develop/headers/os/opengl)
|
||||
endif()
|
||||
|
||||
# The first line below is to make sure that the proper headers
|
||||
|
@ -80,6 +88,7 @@ else ()
|
|||
/usr/share/doc/NVIDIA_GLX-1.0/include
|
||||
/usr/openwin/share/include
|
||||
/opt/graphics/OpenGL/include /usr/X11R6/include
|
||||
${_OPENGL_INCLUDE_PATH}
|
||||
)
|
||||
|
||||
find_path(OPENGL_xmesa_INCLUDE_DIR GL/xmesa.h
|
||||
|
@ -93,9 +102,12 @@ else ()
|
|||
PATHS /opt/graphics/OpenGL/lib
|
||||
/usr/openwin/lib
|
||||
/usr/shlib /usr/X11R6/lib
|
||||
${HPUX_IA_OPENGL_LIB_PATH}
|
||||
${_OPENGL_LIB_PATH}
|
||||
)
|
||||
|
||||
unset(_OPENGL_INCLUDE_PATH)
|
||||
unset(_OPENGL_LIB_PATH)
|
||||
|
||||
# On Unix OpenGL most certainly always requires X11.
|
||||
# Feel free to tighten up these conditions if you don't
|
||||
# think this is always true.
|
||||
|
|
|
@ -43,6 +43,12 @@ if(GLOB_TEMP_VAR)
|
|||
endif()
|
||||
set(GLOB_TEMP_VAR)
|
||||
|
||||
file(GLOB GLOB_TEMP_VAR /usr/local/lib/qt3/bin/qmake)
|
||||
if(GLOB_TEMP_VAR)
|
||||
set(QT3_INSTALLED TRUE)
|
||||
endif()
|
||||
set(GLOB_TEMP_VAR)
|
||||
|
||||
# look for qt4 installations
|
||||
file(GLOB GLOB_TEMP_VAR /usr/local/qt-x11-commercial-4*/bin/qmake)
|
||||
if(GLOB_TEMP_VAR)
|
||||
|
@ -56,6 +62,12 @@ if(GLOB_TEMP_VAR)
|
|||
endif()
|
||||
set(GLOB_TEMP_VAR)
|
||||
|
||||
file(GLOB GLOB_TEMP_VAR /usr/local/lib/qt4/bin/qmake)
|
||||
if(GLOB_TEMP_VAR)
|
||||
set(QT4_INSTALLED TRUE)
|
||||
endif()
|
||||
set(GLOB_TEMP_VAR)
|
||||
|
||||
if (Qt_FIND_VERSION)
|
||||
set(DESIRED_QT_VERSION "${Qt_FIND_VERSION}")
|
||||
endif ()
|
||||
|
@ -91,6 +103,7 @@ find_file( QT4_QGLOBAL_H_FILE qglobal.h
|
|||
/usr/lib/qt/include/Qt
|
||||
/usr/include/Qt
|
||||
/usr/share/qt4/include/Qt
|
||||
/usr/local/include/X11/qt4/Qt
|
||||
C:/Progra~1/qt/include/Qt )
|
||||
|
||||
if(QT4_QGLOBAL_H_FILE)
|
||||
|
@ -110,6 +123,7 @@ find_file( QT3_QGLOBAL_H_FILE qglobal.h
|
|||
/usr/lib/qt/include
|
||||
/usr/include
|
||||
/usr/share/qt3/include
|
||||
/usr/local/include/X11/qt3
|
||||
C:/Progra~1/qt/include
|
||||
/usr/include/qt3 )
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ find_path(QT_INCLUDE_DIR qt.h
|
|||
/usr/share/qt3/include
|
||||
C:/Progra~1/qt/include
|
||||
/usr/include/qt3
|
||||
/usr/local/include/X11/qt3
|
||||
)
|
||||
|
||||
# if qglobal.h is not in the qt_include_dir then set
|
||||
|
@ -146,7 +147,7 @@ find_library(QT_QASSISTANTCLIENT_LIBRARY
|
|||
|
||||
# Qt 3 should prefer QTDIR over the PATH
|
||||
find_program(QT_MOC_EXECUTABLE
|
||||
NAMES moc-qt3 moc
|
||||
NAMES moc-qt3 moc moc3 moc3-mt
|
||||
HINTS
|
||||
ENV QTDIR
|
||||
PATHS
|
||||
|
@ -154,6 +155,7 @@ find_program(QT_MOC_EXECUTABLE
|
|||
"[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.0;InstallDir]/include/Qt"
|
||||
"[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.1.0;InstallDir]/include/Qt"
|
||||
${GLOB_PATHS_BIN}
|
||||
/usr/local/lib/qt3
|
||||
/usr/local/qt
|
||||
/usr/lib/qt
|
||||
/usr/lib/qt3
|
||||
|
@ -170,7 +172,7 @@ endif()
|
|||
|
||||
# Qt 3 should prefer QTDIR over the PATH
|
||||
find_program(QT_UIC_EXECUTABLE
|
||||
NAMES uic-qt3 uic
|
||||
NAMES uic-qt3 uic uic3 uic3-mt
|
||||
HINTS
|
||||
ENV QTDIR
|
||||
PATHS
|
||||
|
|
|
@ -418,6 +418,15 @@ macro (_QT4_ADJUST_LIB_VARS _camelCaseBasename)
|
|||
set_property(TARGET Qt4::${_camelCaseBasename} PROPERTY IMPORTED_LOCATION_DEBUG "${QT_${basename}_LIBRARY_DEBUG}" )
|
||||
endif()
|
||||
endif ()
|
||||
set_property(TARGET Qt4::${_camelCaseBasename} PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES
|
||||
"${QT_${basename}_INCLUDE_DIR}"
|
||||
)
|
||||
string(REGEX REPLACE "^QT" "" _stemname ${basename})
|
||||
set_property(TARGET Qt4::${_camelCaseBasename} PROPERTY
|
||||
INTERFACE_COMPILE_DEFINITIONS
|
||||
"QT_${_stemname}_LIB"
|
||||
)
|
||||
endif()
|
||||
|
||||
# If QT_USE_IMPORTED_TARGETS is enabled, the QT_QTFOO_LIBRARY variables are set to point at these
|
||||
|
@ -538,6 +547,11 @@ endif ()
|
|||
|
||||
if (QT_QMAKE_EXECUTABLE AND QTVERSION)
|
||||
|
||||
# set version variables
|
||||
string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" QT_VERSION_MAJOR "${QTVERSION}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" QT_VERSION_MINOR "${QTVERSION}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" QT_VERSION_PATCH "${QTVERSION}")
|
||||
|
||||
# ask qmake for the mkspecs directory
|
||||
# we do this first because QT_LIBINFIX might be set
|
||||
if (NOT QT_MKSPECS_DIR OR QT_QMAKE_CHANGED)
|
||||
|
@ -942,12 +956,49 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
|
|||
############################################
|
||||
|
||||
|
||||
macro(_qt4_add_target_depends_internal _QT_MODULE _PROPERTY)
|
||||
if (TARGET Qt4::${_QT_MODULE})
|
||||
foreach(_DEPEND ${ARGN})
|
||||
if (NOT TARGET Qt4::Qt${_DEPEND})
|
||||
message(FATAL_ERROR "_qt4_add_target_depends invoked with invalid arguments")
|
||||
endif()
|
||||
set_property(TARGET Qt4::${_QT_MODULE} APPEND PROPERTY
|
||||
${_PROPERTY}
|
||||
"Qt4::Qt${_DEPEND}"
|
||||
)
|
||||
set_property(TARGET Qt4::${_QT_MODULE} APPEND PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES
|
||||
"$<TARGET_PROPERTY:Qt4::Qt${_DEPEND},INTERFACE_INCLUDE_DIRECTORIES>"
|
||||
)
|
||||
set_property(TARGET Qt4::${_QT_MODULE} APPEND PROPERTY
|
||||
INTERFACE_COMPILE_DEFINITIONS
|
||||
"$<TARGET_PROPERTY:Qt4::Qt${_DEPEND},INTERFACE_COMPILE_DEFINITIONS>"
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(_qt4_add_target_depends _QT_MODULE)
|
||||
_qt4_add_target_depends_internal(${_QT_MODULE} IMPORTED_LINK_INTERFACE_LIBRARIES ${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(_qt4_add_target_private_depends _QT_MODULE)
|
||||
_qt4_add_target_depends_internal(${_QT_MODULE} IMPORTED_LINK_DEPENDENT_LIBRARIES ${ARGN})
|
||||
endmacro()
|
||||
|
||||
|
||||
# Set QT_xyz_LIBRARY variable and add
|
||||
# library include path to QT_INCLUDES
|
||||
_QT4_ADJUST_LIB_VARS(QtCore)
|
||||
set_property(TARGET Qt4::QtCore APPEND PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES
|
||||
"${QT_MKSPECS_DIR}/default"
|
||||
${QT_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
foreach(QT_MODULE ${QT_MODULES})
|
||||
_QT4_ADJUST_LIB_VARS(${QT_MODULE})
|
||||
_qt4_add_target_depends(${QT_MODULE} Core)
|
||||
endforeach()
|
||||
|
||||
_QT4_ADJUST_LIB_VARS(QtAssistant)
|
||||
|
@ -962,6 +1013,41 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
|
|||
_QT4_ADJUST_LIB_VARS(QAxContainer)
|
||||
endif()
|
||||
|
||||
# Only public dependencies are listed here.
|
||||
# Eg, QtDBus links to QtXml, but users of QtDBus do not need to
|
||||
# link to QtXml because QtDBus only uses it internally, not in public
|
||||
# headers.
|
||||
# Everything depends on QtCore, but that is covered above already
|
||||
_qt4_add_target_depends(Qt3Support Sql Gui Network)
|
||||
if (TARGET Qt4::Qt3Support)
|
||||
# An additional define is required for QT3_SUPPORT
|
||||
set_property(TARGET Qt4::Qt3Support APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS QT3_SUPPORT)
|
||||
endif()
|
||||
_qt4_add_target_depends(QtDeclarative Script Gui)
|
||||
_qt4_add_target_depends(QtDesigner Gui)
|
||||
_qt4_add_target_depends(QtHelp Gui)
|
||||
_qt4_add_target_depends(QtMultimedia Gui)
|
||||
_qt4_add_target_depends(QtOpenGL Gui)
|
||||
_qt4_add_target_depends(QtSvg Gui)
|
||||
_qt4_add_target_depends(QtWebKit Gui Network)
|
||||
|
||||
_qt4_add_target_private_depends(Qt3Support Xml)
|
||||
_qt4_add_target_private_depends(QtSvg Xml)
|
||||
_qt4_add_target_private_depends(QtDBus Xml)
|
||||
_qt4_add_target_private_depends(QtUiTools Xml Gui)
|
||||
_qt4_add_target_private_depends(QtHelp Sql Xml Network)
|
||||
_qt4_add_target_private_depends(QtXmlPatterns Network)
|
||||
_qt4_add_target_private_depends(QtScriptTools Gui)
|
||||
_qt4_add_target_private_depends(QtWebKit XmlPatterns)
|
||||
_qt4_add_target_private_depends(QtDeclarative XmlPatterns Svg Sql Gui)
|
||||
_qt4_add_target_private_depends(QtMultimedia Gui)
|
||||
_qt4_add_target_private_depends(QtOpenGL Gui)
|
||||
_qt4_add_target_private_depends(QAxServer Gui)
|
||||
_qt4_add_target_private_depends(QAxContainer Gui)
|
||||
_qt4_add_target_private_depends(phonon Gui)
|
||||
if(QT_QTDBUS_FOUND)
|
||||
_qt4_add_target_private_depends(phonon DBus)
|
||||
endif()
|
||||
|
||||
#######################################
|
||||
#
|
||||
|
@ -986,13 +1072,13 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
|
|||
endif()
|
||||
|
||||
find_program(QT_MOC_EXECUTABLE
|
||||
NAMES moc-qt4 moc
|
||||
NAMES moc-qt4 moc moc4
|
||||
PATHS ${QT_BINARY_DIR}
|
||||
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
|
||||
find_program(QT_UIC_EXECUTABLE
|
||||
NAMES uic-qt4 uic
|
||||
NAMES uic-qt4 uic uic4
|
||||
PATHS ${QT_BINARY_DIR}
|
||||
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
|
@ -1022,13 +1108,13 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
|
|||
)
|
||||
|
||||
find_program(QT_LUPDATE_EXECUTABLE
|
||||
NAMES lupdate-qt4 lupdate
|
||||
NAMES lupdate-qt4 lupdate lupdate4
|
||||
PATHS ${QT_BINARY_DIR}
|
||||
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
|
||||
find_program(QT_LRELEASE_EXECUTABLE
|
||||
NAMES lrelease-qt4 lrelease
|
||||
NAMES lrelease-qt4 lrelease lrelease4
|
||||
PATHS ${QT_BINARY_DIR}
|
||||
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
|
@ -1040,13 +1126,13 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
|
|||
)
|
||||
|
||||
find_program(QT_DESIGNER_EXECUTABLE
|
||||
NAMES designer-qt4 designer
|
||||
NAMES designer-qt4 designer designer4
|
||||
PATHS ${QT_BINARY_DIR}
|
||||
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
|
||||
find_program(QT_LINGUIST_EXECUTABLE
|
||||
NAMES linguist-qt4 linguist
|
||||
NAMES linguist-qt4 linguist linguist4
|
||||
PATHS ${QT_BINARY_DIR}
|
||||
NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
|
@ -1174,11 +1260,6 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
|
|||
|
||||
include("${_qt4_current_dir}/Qt4Macros.cmake")
|
||||
|
||||
# set version variables
|
||||
string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" QT_VERSION_MAJOR "${QTVERSION}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" QT_VERSION_MINOR "${QTVERSION}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" QT_VERSION_PATCH "${QTVERSION}")
|
||||
|
||||
endif()
|
||||
|
||||
#support old QT_MIN_VERSION if set, but not if version is supplied by find_package()
|
||||
|
|
|
@ -40,7 +40,7 @@ find_path(SDL_IMAGE_INCLUDE_DIR SDL_image.h
|
|||
HINTS
|
||||
ENV SDLIMAGEDIR
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES SDL SDL12 SDL11
|
||||
PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
|
||||
)
|
||||
|
||||
if(NOT SDL_IMAGE_LIBRARY AND SDLIMAGE_LIBRARY)
|
||||
|
@ -52,6 +52,7 @@ find_library(SDL_IMAGE_LIBRARY
|
|||
HINTS
|
||||
ENV SDLIMAGEDIR
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
if(SDL_IMAGE_INCLUDE_DIR AND EXISTS "${SDL_IMAGE_INCLUDE_DIR}/SDL_image.h")
|
||||
|
|
|
@ -40,7 +40,7 @@ find_path(SDL_MIXER_INCLUDE_DIR SDL_mixer.h
|
|||
HINTS
|
||||
ENV SDLMIXERDIR
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES SDL SDL12 SDL11
|
||||
PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
|
||||
)
|
||||
|
||||
if(NOT SDL_MIXER_LIBRARY AND SDLMIXER_LIBRARY)
|
||||
|
@ -52,6 +52,7 @@ find_library(SDL_MIXER_LIBRARY
|
|||
HINTS
|
||||
ENV SDLMIXERDIR
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
if(SDL_MIXER_INCLUDE_DIR AND EXISTS "${SDL_MIXER_INCLUDE_DIR}/SDL_mixer.h")
|
||||
|
|
|
@ -40,7 +40,7 @@ find_path(SDL_NET_INCLUDE_DIR SDL_net.h
|
|||
HINTS
|
||||
ENV SDLNETDIR
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES SDL SDL12 SDL11
|
||||
PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
|
||||
)
|
||||
|
||||
if(NOT SDL_NET_LIBRARY AND SDLNET_LIBRARY)
|
||||
|
@ -52,6 +52,7 @@ find_library(SDL_NET_LIBRARY
|
|||
HINTS
|
||||
ENV SDLNETDIR
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
if(SDL_NET_INCLUDE_DIR AND EXISTS "${SDL_NET_INCLUDE_DIR}/SDL_net.h")
|
||||
|
|
|
@ -77,7 +77,7 @@ find_path(SDL_SOUND_INCLUDE_DIR SDL_sound.h
|
|||
HINTS
|
||||
ENV SDLSOUNDDIR
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES SDL SDL12 SDL11
|
||||
PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
|
||||
)
|
||||
|
||||
find_library(SDL_SOUND_LIBRARY
|
||||
|
@ -85,6 +85,7 @@ find_library(SDL_SOUND_LIBRARY
|
|||
HINTS
|
||||
ENV SDLSOUNDDIR
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY)
|
||||
|
|
|
@ -40,7 +40,7 @@ find_path(SDL_TTF_INCLUDE_DIR SDL_ttf.h
|
|||
HINTS
|
||||
ENV SDLTTFDIR
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES SDL SDL12 SDL11
|
||||
PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include
|
||||
)
|
||||
|
||||
if(NOT SDL_TTF_LIBRARY AND SDLTTF_LIBRARY)
|
||||
|
@ -52,6 +52,7 @@ find_library(SDL_TTF_LIBRARY
|
|||
HINTS
|
||||
ENV SDLTTFDIR
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
if(SDL_TTF_INCLUDE_DIR AND EXISTS "${SDL_TTF_INCLUDE_DIR}/SDL_ttf.h")
|
||||
|
|
|
@ -19,6 +19,7 @@ endif()
|
|||
set(__DARWIN_COMPILER_CLANG 1)
|
||||
|
||||
macro(__darwin_compiler_clang lang)
|
||||
set(CMAKE_${lang}_VERBOSE_FLAG "-v -Wl,-v") # also tell linker to print verbose output
|
||||
set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names")
|
||||
set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "-bundle -Wl,-headerpad_max_install_names")
|
||||
set(CMAKE_${lang}_SYSROOT_FLAG "-isysroot")
|
||||
|
|
|
@ -19,6 +19,7 @@ endif()
|
|||
set(__DARWIN_COMPILER_GNU 1)
|
||||
|
||||
macro(__darwin_compiler_gnu lang)
|
||||
set(CMAKE_${lang}_VERBOSE_FLAG "-v -Wl,-v") # also tell linker to print verbose output
|
||||
# GNU does not have -shared on OS X
|
||||
set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names")
|
||||
set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "-bundle -Wl,-headerpad_max_install_names")
|
||||
|
|
|
@ -256,6 +256,24 @@ set(CMAKE_CXX_CREATE_MACOSX_FRAMEWORK
|
|||
if(NOT DEFINED CMAKE_FIND_FRAMEWORK)
|
||||
set(CMAKE_FIND_FRAMEWORK FIRST)
|
||||
endif()
|
||||
|
||||
# Older OS X linkers do not report their framework search path
|
||||
# with -v but "man ld" documents the following locations.
|
||||
set(CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
|
||||
${_CMAKE_OSX_SYSROOT_PATH}/Library/Frameworks
|
||||
${_CMAKE_OSX_SYSROOT_PATH}/System/Library/Frameworks
|
||||
)
|
||||
if(_CMAKE_OSX_SYSROOT_PATH)
|
||||
# Treat some paths as implicit so we do not override the SDK versions.
|
||||
list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
|
||||
/System/Library/Frameworks)
|
||||
endif()
|
||||
if("${_CURRENT_OSX_VERSION}" VERSION_LESS "10.5")
|
||||
# Older OS X tools had more implicit paths.
|
||||
list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
|
||||
${_CMAKE_OSX_SYSROOT_PATH}/Network/Library/Frameworks)
|
||||
endif()
|
||||
|
||||
# set up the default search directories for frameworks
|
||||
set(CMAKE_SYSTEM_FRAMEWORK_PATH
|
||||
~/Library/Frameworks
|
||||
|
|
|
@ -24,6 +24,19 @@
|
|||
<WixVariable Id="WixUILicenseRtf" Value="$(var.CPACK_WIX_LICENSE_RTF)"/>
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALL_ROOT"/>
|
||||
|
||||
<?ifdef CPACK_WIX_PRODUCT_ICON?>
|
||||
<Property Id="ARPPRODUCTICON">ProductIcon.ico</Property>
|
||||
<Icon Id="ProductIcon.ico" SourceFile="$(var.CPACK_WIX_PRODUCT_ICON)"/>
|
||||
<?endif?>
|
||||
|
||||
<?ifdef CPACK_WIX_UI_BANNER?>
|
||||
<WixVariable Id="WixUIBannerBmp" Value="$(var.CPACK_WIX_UI_BANNER)"/>
|
||||
<?endif?>
|
||||
|
||||
<?ifdef CPACK_WIX_UI_DIALOG?>
|
||||
<WixVariable Id="WixUIDialogBmp" Value="$(var.CPACK_WIX_UI_DIALOG)"/>
|
||||
<?endif?>
|
||||
|
||||
<FeatureRef Id="ProductFeature"/>
|
||||
|
||||
<UIRef Id="WixUI_InstallDir" />
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
set(CMake_VERSION_MAJOR 2)
|
||||
set(CMake_VERSION_MINOR 8)
|
||||
set(CMake_VERSION_PATCH 10)
|
||||
set(CMake_VERSION_TWEAK 20121210)
|
||||
set(CMake_VERSION_TWEAK 20130118)
|
||||
#set(CMake_VERSION_RC 1)
|
||||
|
|
|
@ -221,6 +221,9 @@ bool cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
|
|||
CopyDefinition(includeFile, "CPACK_PACKAGE_NAME");
|
||||
CopyDefinition(includeFile, "CPACK_PACKAGE_VERSION");
|
||||
CopyDefinition(includeFile, "CPACK_WIX_LICENSE_RTF");
|
||||
CopyDefinition(includeFile, "CPACK_WIX_PRODUCT_ICON");
|
||||
CopyDefinition(includeFile, "CPACK_WIX_UI_BANNER");
|
||||
CopyDefinition(includeFile, "CPACK_WIX_UI_DIALOG");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#endif
|
||||
|
||||
#if !defined(_WIN32) \
|
||||
&& !defined(__QNXNTO__) && !defined(__BEOS__)
|
||||
&& !defined(__QNXNTO__) && !defined(__BEOS__) && !defined(__HAIKU__)
|
||||
# include "cmCPackDebGenerator.h"
|
||||
# include "cmCPackRPMGenerator.h"
|
||||
#endif
|
||||
|
@ -126,7 +126,7 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
|
|||
}
|
||||
#endif
|
||||
#if !defined(_WIN32) \
|
||||
&& !defined(__QNXNTO__) && !defined(__BEOS__)
|
||||
&& !defined(__QNXNTO__) && !defined(__BEOS__) && !defined(__HAIKU__)
|
||||
if (cmCPackDebGenerator::CanGenerate())
|
||||
{
|
||||
this->RegisterGenerator("DEB", "Debian packages",
|
||||
|
|
|
@ -1097,10 +1097,17 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
|
|||
}
|
||||
else
|
||||
{
|
||||
cmCTestLog(this->CTest, ERROR_MESSAGE,
|
||||
"Unknown gcov output line: [" << line->c_str() << "]" << std::endl);
|
||||
cont->Error ++;
|
||||
//abort();
|
||||
// gcov 4.7 can have output lines saying "No executable lines" and
|
||||
// "Removing 'filename.gcov'"... Don't log those as "errors."
|
||||
if(*line != "No executable lines" &&
|
||||
!cmSystemTools::StringStartsWith(line->c_str(), "Removing "))
|
||||
{
|
||||
cmCTestLog(this->CTest, ERROR_MESSAGE,
|
||||
"Unknown gcov output line: [" << line->c_str() << "]"
|
||||
<< std::endl);
|
||||
cont->Error ++;
|
||||
//abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -248,7 +248,12 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
|
|||
//---------------------------------------------------------
|
||||
void cmCTestMultiProcessHandler::StartNextTests()
|
||||
{
|
||||
size_t numToStart = this->ParallelLevel - this->RunningCount;
|
||||
size_t numToStart = 0;
|
||||
if(this->RunningCount < this->ParallelLevel)
|
||||
{
|
||||
numToStart = this->ParallelLevel - this->RunningCount;
|
||||
}
|
||||
|
||||
if(numToStart == 0)
|
||||
{
|
||||
return;
|
||||
|
|
|
@ -134,6 +134,10 @@ public:
|
|||
"They may contain custom commands generating such sources, but not "
|
||||
"PRE_BUILD, PRE_LINK, or POST_BUILD commands. "
|
||||
"Object libraries cannot be imported, exported, installed, or linked."
|
||||
" "
|
||||
"Some native build systems may not like targets that have only "
|
||||
"object files, so consider adding at least one real source file "
|
||||
"to any target that references $<TARGET_OBJECTS:objlib>."
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
#include "cmStringCommand.cxx"
|
||||
#include "cmSubdirCommand.cxx"
|
||||
#include "cmTargetLinkLibrariesCommand.cxx"
|
||||
#include "cmTimestamp.cxx"
|
||||
#include "cmTryCompileCommand.cxx"
|
||||
#include "cmTryRunCommand.cxx"
|
||||
#include "cmUnsetCommand.cxx"
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
#include <cm_zlib.h>
|
||||
#include <cmsys/Base64.h>
|
||||
|
||||
#if defined(__BEOS__) && !defined(__HAIKU__)
|
||||
#if defined(__BEOS__)
|
||||
#include <be/kernel/OS.h> /* disable_debugger() API. */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -279,7 +279,7 @@ typedef short int yytype_int16;
|
|||
#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
|
||||
|
||||
#ifndef YY_
|
||||
# if YYENABLE_NLS
|
||||
# if defined YYENABLE_NLS && YYENABLE_NLS
|
||||
# if ENABLE_NLS
|
||||
# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
|
||||
# define YY_(msgid) dgettext ("bison-runtime", msgid)
|
||||
|
@ -701,7 +701,7 @@ while (YYID (0))
|
|||
we won't break user code: when these are the locations we know. */
|
||||
|
||||
#ifndef YY_LOCATION_PRINT
|
||||
# if YYLTYPE_IS_TRIVIAL
|
||||
# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
|
||||
# define YY_LOCATION_PRINT(File, Loc) \
|
||||
fprintf (File, "%d.%d-%d.%d", \
|
||||
(Loc).first_line, (Loc).first_column, \
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
#include "cmRemoveDefinitionsCommand.cxx"
|
||||
#include "cmSourceGroupCommand.cxx"
|
||||
#include "cmSubdirDependsCommand.cxx"
|
||||
#include "cmTargetCompileDefinitionsCommand.cxx"
|
||||
#include "cmTargetIncludeDirectoriesCommand.cxx"
|
||||
#include "cmTargetPropCommandBase.cxx"
|
||||
#include "cmUseMangledMesaCommand.cxx"
|
||||
#include "cmUtilitySourceCommand.cxx"
|
||||
#include "cmVariableRequiresCommand.cxx"
|
||||
|
@ -66,6 +69,8 @@ void GetPredefinedCommands(std::list<cmCommand*>&
|
|||
commands.push_back(new cmRemoveDefinitionsCommand);
|
||||
commands.push_back(new cmSourceGroupCommand);
|
||||
commands.push_back(new cmSubdirDependsCommand);
|
||||
commands.push_back(new cmTargetIncludeDirectoriesCommand);
|
||||
commands.push_back(new cmTargetCompileDefinitionsCommand);
|
||||
commands.push_back(new cmUseMangledMesaCommand);
|
||||
commands.push_back(new cmUtilitySourceCommand);
|
||||
commands.push_back(new cmVariableRequiresCommand);
|
||||
|
|
|
@ -172,10 +172,11 @@ satisfy dependencies.
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
cmComputeLinkDepends
|
||||
::cmComputeLinkDepends(cmTarget* target, const char* config)
|
||||
::cmComputeLinkDepends(cmTarget* target, const char* config, cmTarget* head)
|
||||
{
|
||||
// Store context information.
|
||||
this->Target = target;
|
||||
this->HeadTarget = head;
|
||||
this->Makefile = this->Target->GetMakefile();
|
||||
this->LocalGenerator = this->Makefile->GetLocalGenerator();
|
||||
this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
|
||||
|
@ -352,7 +353,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
|
|||
{
|
||||
// Follow the target dependencies.
|
||||
if(cmTarget::LinkInterface const* iface =
|
||||
entry.Target->GetLinkInterface(this->Config))
|
||||
entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
|
||||
{
|
||||
// This target provides its own link interface information.
|
||||
this->AddLinkEntries(depender_index, iface->Libraries);
|
||||
|
@ -444,7 +445,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
|
|||
if(entry.Target)
|
||||
{
|
||||
if(cmTarget::LinkInterface const* iface =
|
||||
entry.Target->GetLinkInterface(this->Config))
|
||||
entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
|
||||
{
|
||||
// Follow public and private dependencies transitively.
|
||||
this->FollowSharedDeps(index, iface, true);
|
||||
|
@ -533,7 +534,7 @@ void cmComputeLinkDepends::AddDirectLinkEntries()
|
|||
{
|
||||
// Add direct link dependencies in this configuration.
|
||||
cmTarget::LinkImplementation const* impl =
|
||||
this->Target->GetLinkImplementation(this->Config);
|
||||
this->Target->GetLinkImplementation(this->Config, this->HeadTarget);
|
||||
this->AddLinkEntries(-1, impl->Libraries);
|
||||
for(std::vector<std::string>::const_iterator
|
||||
wi = impl->WrongConfigLibraries.begin();
|
||||
|
@ -944,7 +945,7 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
|
|||
if(cmTarget* target = this->EntryList[*ni].Target)
|
||||
{
|
||||
if(cmTarget::LinkInterface const* iface =
|
||||
target->GetLinkInterface(this->Config))
|
||||
target->GetLinkInterface(this->Config, this->HeadTarget))
|
||||
{
|
||||
if(iface->Multiplicity > count)
|
||||
{
|
||||
|
|
|
@ -32,7 +32,7 @@ class cmake;
|
|||
class cmComputeLinkDepends
|
||||
{
|
||||
public:
|
||||
cmComputeLinkDepends(cmTarget* target, const char* config);
|
||||
cmComputeLinkDepends(cmTarget* target, const char* config, cmTarget *head);
|
||||
~cmComputeLinkDepends();
|
||||
|
||||
// Basic information about each link item.
|
||||
|
@ -59,6 +59,7 @@ private:
|
|||
|
||||
// Context information.
|
||||
cmTarget* Target;
|
||||
cmTarget* HeadTarget;
|
||||
cmMakefile* Makefile;
|
||||
cmLocalGenerator* LocalGenerator;
|
||||
cmGlobalGenerator* GlobalGenerator;
|
||||
|
|
|
@ -239,10 +239,12 @@ because this need be done only for shared libraries without soname-s.
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
cmComputeLinkInformation
|
||||
::cmComputeLinkInformation(cmTarget* target, const char* config)
|
||||
::cmComputeLinkInformation(cmTarget* target, const char* config,
|
||||
cmTarget *headTarget)
|
||||
{
|
||||
// Store context information.
|
||||
this->Target = target;
|
||||
this->HeadTarget = headTarget;
|
||||
this->Makefile = this->Target->GetMakefile();
|
||||
this->LocalGenerator = this->Makefile->GetLocalGenerator();
|
||||
this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
|
||||
|
@ -265,7 +267,7 @@ cmComputeLinkInformation
|
|||
this->OrderDependentRPath = 0;
|
||||
|
||||
// Get the language used for linking this target.
|
||||
this->LinkLanguage = this->Target->GetLinkerLanguage(config);
|
||||
this->LinkLanguage = this->Target->GetLinkerLanguage(config, headTarget);
|
||||
if(!this->LinkLanguage)
|
||||
{
|
||||
// The Compute method will do nothing, so skip the rest of the
|
||||
|
@ -503,7 +505,7 @@ bool cmComputeLinkInformation::Compute()
|
|||
}
|
||||
|
||||
// Compute the ordered link line items.
|
||||
cmComputeLinkDepends cld(this->Target, this->Config);
|
||||
cmComputeLinkDepends cld(this->Target, this->Config, this->HeadTarget);
|
||||
cld.SetOldLinkDirMode(this->OldLinkDirMode);
|
||||
cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
|
||||
|
||||
|
@ -569,7 +571,8 @@ bool cmComputeLinkInformation::Compute()
|
|||
void cmComputeLinkInformation::AddImplicitLinkInfo()
|
||||
{
|
||||
// The link closure lists all languages whose implicit info is needed.
|
||||
cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config);
|
||||
cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config,
|
||||
this->HeadTarget);
|
||||
for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
|
||||
li != lc->Languages.end(); ++li)
|
||||
{
|
||||
|
@ -1376,10 +1379,31 @@ void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
|
|||
//----------------------------------------------------------------------------
|
||||
void cmComputeLinkInformation::ComputeFrameworkInfo()
|
||||
{
|
||||
// Avoid adding system framework paths. See "man ld" on OS X.
|
||||
this->FrameworkPathsEmmitted.insert("/Library/Frameworks");
|
||||
this->FrameworkPathsEmmitted.insert("/Network/Library/Frameworks");
|
||||
this->FrameworkPathsEmmitted.insert("/System/Library/Frameworks");
|
||||
// Avoid adding implicit framework paths.
|
||||
std::vector<std::string> implicitDirVec;
|
||||
|
||||
// Get platform-wide implicit directories.
|
||||
if(const char* implicitLinks = this->Makefile->GetDefinition
|
||||
("CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES"))
|
||||
{
|
||||
cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
|
||||
}
|
||||
|
||||
// Get language-specific implicit directories.
|
||||
std::string implicitDirVar = "CMAKE_";
|
||||
implicitDirVar += this->LinkLanguage;
|
||||
implicitDirVar += "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES";
|
||||
if(const char* implicitDirs =
|
||||
this->Makefile->GetDefinition(implicitDirVar.c_str()))
|
||||
{
|
||||
cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
|
||||
}
|
||||
|
||||
for(std::vector<std::string>::const_iterator i = implicitDirVec.begin();
|
||||
i != implicitDirVec.end(); ++i)
|
||||
{
|
||||
this->FrameworkPathsEmmitted.insert(*i);
|
||||
}
|
||||
|
||||
// Regular expression to extract a framework path and name.
|
||||
this->SplitFramework.compile("(.*)/(.*)\\.framework$");
|
||||
|
|
|
@ -29,7 +29,8 @@ class cmOrderDirectories;
|
|||
class cmComputeLinkInformation
|
||||
{
|
||||
public:
|
||||
cmComputeLinkInformation(cmTarget* target, const char* config);
|
||||
cmComputeLinkInformation(cmTarget* target, const char* config,
|
||||
cmTarget* headTarget);
|
||||
~cmComputeLinkInformation();
|
||||
bool Compute();
|
||||
|
||||
|
@ -74,6 +75,7 @@ private:
|
|||
|
||||
// Context information.
|
||||
cmTarget* Target;
|
||||
cmTarget* HeadTarget;
|
||||
cmMakefile* Makefile;
|
||||
cmLocalGenerator* LocalGenerator;
|
||||
cmGlobalGenerator* GlobalGenerator;
|
||||
|
|
|
@ -200,20 +200,48 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
|
|||
// Get the depender.
|
||||
cmTarget* depender = this->Targets[depender_index];
|
||||
|
||||
// Loop over all targets linked directly.
|
||||
// Loop over all targets linked directly in all configs.
|
||||
// We need to make targets depend on the union of all config-specific
|
||||
// dependencies in all targets, because the generated build-systems can't
|
||||
// deal with config-specific dependencies.
|
||||
{
|
||||
cmTarget::LinkLibraryVectorType const& tlibs =
|
||||
depender->GetOriginalLinkLibraries();
|
||||
std::set<cmStdString> emitted;
|
||||
{
|
||||
std::vector<std::string> tlibs;
|
||||
depender->GetDirectLinkLibraries(0, tlibs, depender);
|
||||
// A target should not depend on itself.
|
||||
emitted.insert(depender->GetName());
|
||||
for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin();
|
||||
for(std::vector<std::string>::const_iterator lib = tlibs.begin();
|
||||
lib != tlibs.end(); ++lib)
|
||||
{
|
||||
// Don't emit the same library twice for this target.
|
||||
if(emitted.insert(lib->first).second)
|
||||
if(emitted.insert(*lib).second)
|
||||
{
|
||||
this->AddTargetDepend(depender_index, lib->first.c_str(), true);
|
||||
this->AddTargetDepend(depender_index, lib->c_str(), true);
|
||||
this->AddInterfaceDepends(depender_index, lib->c_str(),
|
||||
true, emitted);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::vector<std::string> configs;
|
||||
depender->GetMakefile()->GetConfigurations(configs);
|
||||
for (std::vector<std::string>::const_iterator it = configs.begin();
|
||||
it != configs.end(); ++it)
|
||||
{
|
||||
std::vector<std::string> tlibs;
|
||||
depender->GetDirectLinkLibraries(it->c_str(), tlibs, depender);
|
||||
// A target should not depend on itself.
|
||||
emitted.insert(depender->GetName());
|
||||
for(std::vector<std::string>::const_iterator lib = tlibs.begin();
|
||||
lib != tlibs.end(); ++lib)
|
||||
{
|
||||
// Don't emit the same library twice for this target.
|
||||
if(emitted.insert(*lib).second)
|
||||
{
|
||||
this->AddTargetDepend(depender_index, lib->c_str(), true);
|
||||
this->AddInterfaceDepends(depender_index, lib->c_str(),
|
||||
true, emitted);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -236,6 +264,64 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
|
||||
cmTarget* dependee,
|
||||
const char *config,
|
||||
std::set<cmStdString> &emitted)
|
||||
{
|
||||
cmTarget* depender = this->Targets[depender_index];
|
||||
if(cmTarget::LinkInterface const* iface =
|
||||
dependee->GetLinkInterface(config, depender))
|
||||
{
|
||||
for(std::vector<std::string>::const_iterator
|
||||
lib = iface->Libraries.begin();
|
||||
lib != iface->Libraries.end(); ++lib)
|
||||
{
|
||||
// Don't emit the same library twice for this target.
|
||||
if(emitted.insert(*lib).second)
|
||||
{
|
||||
this->AddTargetDepend(depender_index, lib->c_str(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
|
||||
const char* dependee_name,
|
||||
bool linking,
|
||||
std::set<cmStdString> &emitted)
|
||||
{
|
||||
cmTarget* depender = this->Targets[depender_index];
|
||||
cmTarget* dependee =
|
||||
depender->GetMakefile()->FindTargetToUse(dependee_name);
|
||||
// Skip targets that will not really be linked. This is probably a
|
||||
// name conflict between an external library and an executable
|
||||
// within the project.
|
||||
if(linking && dependee &&
|
||||
dependee->GetType() == cmTarget::EXECUTABLE &&
|
||||
!dependee->IsExecutableWithExports())
|
||||
{
|
||||
dependee = 0;
|
||||
}
|
||||
|
||||
if(dependee)
|
||||
{
|
||||
this->AddInterfaceDepends(depender_index, dependee, 0, emitted);
|
||||
std::vector<std::string> configs;
|
||||
depender->GetMakefile()->GetConfigurations(configs);
|
||||
for (std::vector<std::string>::const_iterator it = configs.begin();
|
||||
it != configs.end(); ++it)
|
||||
{
|
||||
// A target should not depend on itself.
|
||||
emitted.insert(depender->GetName());
|
||||
this->AddInterfaceDepends(depender_index, dependee,
|
||||
it->c_str(), emitted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmComputeTargetDepends::AddTargetDepend(int depender_index,
|
||||
const char* dependee_name,
|
||||
|
|
|
@ -48,7 +48,11 @@ private:
|
|||
bool linking);
|
||||
void AddTargetDepend(int depender_index, cmTarget* dependee, bool linking);
|
||||
bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
|
||||
|
||||
void AddInterfaceDepends(int depender_index, const char* dependee_name,
|
||||
bool linking, std::set<cmStdString> &emitted);
|
||||
void AddInterfaceDepends(int depender_index, cmTarget* dependee,
|
||||
const char *config,
|
||||
std::set<cmStdString> &emitted);
|
||||
cmGlobalGenerator* GlobalGenerator;
|
||||
bool DebugMode;
|
||||
bool NoCycles;
|
||||
|
|
|
@ -47,7 +47,7 @@ std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
|
|||
{
|
||||
return target->GetLocation(this->Config);
|
||||
}
|
||||
return this->GE->Parse(argv0).Evaluate(this->Makefile, this->Config);
|
||||
return this->GE->Parse(argv0)->Evaluate(this->Makefile, this->Config);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -58,7 +58,7 @@ cmCustomCommandGenerator
|
|||
cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
|
||||
for(unsigned int j=1;j < commandLine.size(); ++j)
|
||||
{
|
||||
std::string arg = this->GE->Parse(commandLine[j]).Evaluate(this->Makefile,
|
||||
std::string arg = this->GE->Parse(commandLine[j])->Evaluate(this->Makefile,
|
||||
this->Config);
|
||||
cmd += " ";
|
||||
if(this->OldStyle)
|
||||
|
|
|
@ -26,7 +26,18 @@
|
|||
"strings which contain a '>' for example.\n" \
|
||||
" $<COMMA> = A literal ','. Used to compare " \
|
||||
"strings which contain a ',' for example.\n" \
|
||||
" $<TARGET_NAME:...> = Marks ... as being the name of a " \
|
||||
"target. This is required if exporting targets to multiple " \
|
||||
"dependent export sets. The '...' must be a literal name of a " \
|
||||
"target- it may not contain generator expressions.\n" \
|
||||
" $<INSTALL_INTERFACE:...> = content of \"...\" when the property " \
|
||||
"is exported using install(EXPORT), and empty otherwise.\n" \
|
||||
" $<BUILD_INTERFACE:...> = content of \"...\" when the property " \
|
||||
"is exported using export(), or when the target is used by another " \
|
||||
"target in the same buildsystem. Expands to the empty string " \
|
||||
"otherwise.\n" \
|
||||
" $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \
|
||||
" $<TARGET_DEFINED:tgt> = '1' if tgt is a target, else '0'\n" \
|
||||
" $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \
|
||||
" $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" \
|
||||
"where \"tgt\" is the name of a target. " \
|
||||
|
|
|
@ -896,6 +896,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
|
|||
" script, it may get fatal error messages from the script.",false,
|
||||
"Variables That Change Behavior");
|
||||
|
||||
cm->DefineProperty
|
||||
("CMAKE_DEBUG_TARGET_PROPERTIES", cmProperty::VARIABLE,
|
||||
"Enables tracing output for target properties.",
|
||||
"This variable can be populated with a list of properties to generate "
|
||||
"debug output for when evaluating target properties. Currently it can "
|
||||
"only be used when evaluating the INCLUDE_DIRECTORIES target property. "
|
||||
"In that case, it outputs a backtrace for each include directory in "
|
||||
"the build. Default is unset.",false,"Variables That Change Behavior");
|
||||
|
||||
// Variables defined by CMake that describe the system
|
||||
|
||||
cm->DefineProperty
|
||||
|
@ -1137,6 +1146,17 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
|
|||
false,
|
||||
"Variables that Control the Build");
|
||||
|
||||
cm->DefineProperty
|
||||
("CMAKE_BUILD_INTERFACE_INCLUDES", cmProperty::VARIABLE,
|
||||
"Automatically add the current source- and build directories "
|
||||
"to the INTERFACE_INCLUDE_DIRECTORIES.",
|
||||
"If this variable is enabled, CMake automatically adds for each "
|
||||
"target ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} "
|
||||
"to the INTERFACE_INCLUDE_DIRECTORIES."
|
||||
"By default CMAKE_BUILD_INTERFACE_INCLUDES is OFF.",
|
||||
false,
|
||||
"Variables that Control the Build");
|
||||
|
||||
cm->DefineProperty
|
||||
("CMAKE_INSTALL_RPATH", cmProperty::VARIABLE,
|
||||
"The rpath to use for installed targets.",
|
||||
|
@ -1621,6 +1641,23 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
|
|||
"These paths are implicit linker search directories for the compiler's "
|
||||
"language. "
|
||||
"CMake automatically detects these directories for each language and "
|
||||
"reports the results in this variable."
|
||||
"\n"
|
||||
"When a library in one of these directories is given by full path to "
|
||||
"target_link_libraries() CMake will generate the -l<name> form on "
|
||||
"link lines to ensure the linker searches its implicit directories "
|
||||
"for the library. "
|
||||
"Note that some toolchains read implicit directories from an "
|
||||
"environment variable such as LIBRARY_PATH so keep its value "
|
||||
"consistent when operating in a given build tree.",false,
|
||||
"Variables for Languages");
|
||||
|
||||
cm->DefineProperty
|
||||
("CMAKE_<LANG>_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", cmProperty::VARIABLE,
|
||||
"Implicit linker framework search path detected for language <LANG>.",
|
||||
"These paths are implicit linker framework search directories for "
|
||||
"the compiler's language. "
|
||||
"CMake automatically detects these directories for each language and "
|
||||
"reports the results in this variable.", false,
|
||||
"Variables for Languages");
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ cmExportBuildFileGenerator::cmExportBuildFileGenerator()
|
|||
//----------------------------------------------------------------------------
|
||||
bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
||||
{
|
||||
std::vector<cmTarget*> allTargets;
|
||||
{
|
||||
std::string expectedTargets;
|
||||
std::string sep;
|
||||
|
@ -31,20 +32,10 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
{
|
||||
expectedTargets += sep + this->Namespace + (*tei)->GetName();
|
||||
sep = " ";
|
||||
}
|
||||
|
||||
this->GenerateExpectedTargetsCode(os, expectedTargets);
|
||||
}
|
||||
|
||||
// Create all the imported targets.
|
||||
for(std::vector<cmTarget*>::const_iterator
|
||||
tei = this->Exports->begin();
|
||||
tei != this->Exports->end(); ++tei)
|
||||
{
|
||||
cmTarget* te = *tei;
|
||||
if(this->ExportedTargets.insert(te).second)
|
||||
{
|
||||
this->GenerateImportTargetCode(os, te);
|
||||
allTargets.push_back(te);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -58,14 +49,45 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
}
|
||||
}
|
||||
|
||||
this->GenerateExpectedTargetsCode(os, expectedTargets);
|
||||
}
|
||||
|
||||
std::vector<std::string> missingTargets;
|
||||
|
||||
// Create all the imported targets.
|
||||
for(std::vector<cmTarget*>::const_iterator
|
||||
tei = allTargets.begin();
|
||||
tei != allTargets.end(); ++tei)
|
||||
{
|
||||
cmTarget* te = *tei;
|
||||
this->GenerateImportTargetCode(os, te);
|
||||
|
||||
te->AppendBuildInterfaceIncludes();
|
||||
|
||||
ImportPropertyMap properties;
|
||||
|
||||
this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te,
|
||||
cmGeneratorExpression::BuildInterface,
|
||||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te,
|
||||
cmGeneratorExpression::BuildInterface,
|
||||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
|
||||
te, properties);
|
||||
|
||||
this->GenerateInterfaceProperties(te, os, properties);
|
||||
}
|
||||
|
||||
// Generate import file content for each configuration.
|
||||
for(std::vector<std::string>::const_iterator
|
||||
ci = this->Configurations.begin();
|
||||
ci != this->Configurations.end(); ++ci)
|
||||
{
|
||||
this->GenerateImportConfig(os, ci->c_str());
|
||||
this->GenerateImportConfig(os, ci->c_str(), missingTargets);
|
||||
}
|
||||
|
||||
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -73,7 +95,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
void
|
||||
cmExportBuildFileGenerator
|
||||
::GenerateImportTargetsConfig(std::ostream& os,
|
||||
const char* config, std::string const& suffix)
|
||||
const char* config, std::string const& suffix,
|
||||
std::vector<std::string> &missingTargets)
|
||||
{
|
||||
for(std::vector<cmTarget*>::const_iterator
|
||||
tei = this->Exports->begin();
|
||||
|
@ -86,9 +109,12 @@ cmExportBuildFileGenerator
|
|||
if(!properties.empty())
|
||||
{
|
||||
// Get the rest of the target details.
|
||||
std::vector<std::string> missingTargets;
|
||||
this->SetImportDetailProperties(config, suffix,
|
||||
target, properties, missingTargets);
|
||||
this->SetImportLinkInterface(config, suffix,
|
||||
cmGeneratorExpression::BuildInterface,
|
||||
target, properties, missingTargets);
|
||||
|
||||
|
||||
// TOOD: PUBLIC_HEADER_LOCATION
|
||||
// This should wait until the build feature propagation stuff
|
||||
|
@ -97,7 +123,6 @@ cmExportBuildFileGenerator
|
|||
// properties);
|
||||
|
||||
// Generate code in the export file.
|
||||
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
||||
this->GenerateImportPropertyCode(os, config, target, properties);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,8 @@ protected:
|
|||
virtual bool GenerateMainFile(std::ostream& os);
|
||||
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
||||
const char* config,
|
||||
std::string const& suffix);
|
||||
std::string const& suffix,
|
||||
std::vector<std::string> &missingTargets);
|
||||
virtual void HandleMissingTarget(std::string& link_libs,
|
||||
std::vector<std::string>& missingTargets,
|
||||
cmMakefile* mf,
|
||||
|
|
|
@ -107,7 +107,8 @@ bool cmExportFileGenerator::GenerateImportFile()
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
|
||||
const char* config)
|
||||
const char* config,
|
||||
std::vector<std::string> &missingTargets)
|
||||
{
|
||||
// Construct the property configuration suffix.
|
||||
std::string suffix = "_";
|
||||
|
@ -121,7 +122,297 @@ void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
|
|||
}
|
||||
|
||||
// Generate the per-config target information.
|
||||
this->GenerateImportTargetsConfig(os, config, suffix);
|
||||
this->GenerateImportTargetsConfig(os, config, suffix, missingTargets);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
|
||||
cmTarget *target,
|
||||
ImportPropertyMap &properties)
|
||||
{
|
||||
const char *input = target->GetProperty(propName);
|
||||
if (input)
|
||||
{
|
||||
properties[propName] = input;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
|
||||
const char *outputName,
|
||||
cmTarget *target,
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
ImportPropertyMap &properties,
|
||||
std::vector<std::string> &missingTargets)
|
||||
{
|
||||
const char *input = target->GetProperty(propName);
|
||||
if (input)
|
||||
{
|
||||
if (!*input)
|
||||
{
|
||||
// Set to empty
|
||||
properties[outputName] = "";
|
||||
return;
|
||||
}
|
||||
|
||||
std::string prepro = cmGeneratorExpression::Preprocess(input,
|
||||
preprocessRule);
|
||||
if (!prepro.empty())
|
||||
{
|
||||
this->ResolveTargetsInGeneratorExpressions(prepro, target,
|
||||
missingTargets);
|
||||
properties[outputName] = prepro;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
|
||||
cmTarget *target,
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
ImportPropertyMap &properties,
|
||||
std::vector<std::string> &missingTargets)
|
||||
{
|
||||
this->PopulateInterfaceProperty(propName, propName, target, preprocessRule,
|
||||
properties, missingTargets);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
|
||||
std::ostream& os,
|
||||
const ImportPropertyMap &properties)
|
||||
{
|
||||
if (!properties.empty())
|
||||
{
|
||||
std::string targetName = this->Namespace;
|
||||
targetName += target->GetName();
|
||||
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 << ")\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
cmExportFileGenerator::AddTargetNamespace(std::string &input,
|
||||
cmTarget* target,
|
||||
std::vector<std::string> &missingTargets)
|
||||
{
|
||||
cmMakefile *mf = target->GetMakefile();
|
||||
|
||||
cmTarget *tgt = mf->FindTargetToUse(input.c_str());
|
||||
if (!tgt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(tgt->IsImported())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
|
||||
{
|
||||
input = this->Namespace + input;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string namespacedTarget;
|
||||
this->HandleMissingTarget(namespacedTarget, missingTargets,
|
||||
mf, target, tgt);
|
||||
if (!namespacedTarget.empty())
|
||||
{
|
||||
input = namespacedTarget;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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
|
||||
cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
|
||||
std::string &input,
|
||||
cmTarget* target,
|
||||
std::vector<std::string> &missingTargets,
|
||||
FreeTargetsReplace replace)
|
||||
{
|
||||
if (replace == NoReplaceFreeTargets)
|
||||
{
|
||||
this->ResolveTargetsInGeneratorExpression(input, target, missingTargets);
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> parts;
|
||||
cmGeneratorExpression::Split(input, parts);
|
||||
|
||||
std::string sep;
|
||||
input = "";
|
||||
for(std::vector<std::string>::iterator li = parts.begin();
|
||||
li != parts.end(); ++li)
|
||||
{
|
||||
if (!isGeneratorExpression(*li))
|
||||
{
|
||||
this->AddTargetNamespace(*li, target, missingTargets);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->ResolveTargetsInGeneratorExpression(
|
||||
*li,
|
||||
target,
|
||||
missingTargets);
|
||||
}
|
||||
input += sep + *li;
|
||||
sep = ";";
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
|
||||
std::string &input,
|
||||
cmTarget* target,
|
||||
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)
|
||||
{
|
||||
std::string::size_type nameStartPos = pos +
|
||||
sizeof("$<TARGET_PROPERTY:") - 1;
|
||||
std::string::size_type closePos = input.find(">", nameStartPos);
|
||||
std::string::size_type commaPos = input.find(",", nameStartPos);
|
||||
std::string::size_type nextOpenPos = input.find("$<", nameStartPos);
|
||||
if (commaPos == input.npos // Implied 'this' target
|
||||
|| closePos == input.npos // Imcomplete expression.
|
||||
|| closePos < commaPos // Implied 'this' target
|
||||
|| nextOpenPos < commaPos) // Non-literal
|
||||
{
|
||||
lastPos = nameStartPos;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string targetName = input.substr(nameStartPos,
|
||||
commaPos - nameStartPos);
|
||||
|
||||
if (!this->AddTargetNamespace(targetName, target, missingTargets))
|
||||
{
|
||||
errorString = "$<TARGET_PROPERTY:" + targetName + ",prop> requires "
|
||||
"its first parameter to be a reachable target.";
|
||||
break;
|
||||
}
|
||||
input.replace(nameStartPos, commaPos - nameStartPos, targetName);
|
||||
lastPos = pos + targetName.size();
|
||||
}
|
||||
if (!errorString.empty())
|
||||
{
|
||||
mf->IssueMessage(cmake::FATAL_ERROR, errorString);
|
||||
return;
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
lastPos = pos;
|
||||
while((pos = input.find("$<TARGET_NAME:", lastPos)) != input.npos)
|
||||
{
|
||||
std::string::size_type nameStartPos = pos + sizeof("$<TARGET_NAME:") - 1;
|
||||
std::string::size_type endPos = input.find(">", nameStartPos);
|
||||
if (endPos == input.npos)
|
||||
{
|
||||
errorString = "$<TARGET_NAME:...> expression incomplete";
|
||||
break;
|
||||
}
|
||||
std::string targetName = input.substr(nameStartPos,
|
||||
endPos - nameStartPos);
|
||||
if(targetName.find("$<") != input.npos)
|
||||
{
|
||||
errorString = "$<TARGET_NAME:...> requires its parameter to be a "
|
||||
"literal.";
|
||||
break;
|
||||
}
|
||||
if (!this->AddTargetNamespace(targetName, target, missingTargets))
|
||||
{
|
||||
errorString = "$<TARGET_NAME:...> requires its parameter to be a "
|
||||
"reachable target.";
|
||||
break;
|
||||
}
|
||||
input.replace(pos, endPos - pos + 1, targetName);
|
||||
lastPos = endPos;
|
||||
}
|
||||
if (!errorString.empty())
|
||||
{
|
||||
mf->IssueMessage(cmake::FATAL_ERROR, errorString);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmExportFileGenerator
|
||||
::SetImportLinkInterface(const char* config, std::string const& suffix,
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
cmTarget* target, ImportPropertyMap& properties,
|
||||
std::vector<std::string>& missingTargets)
|
||||
{
|
||||
// Add the transitive link dependencies for this configuration.
|
||||
cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
|
||||
target);
|
||||
if (!iface)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (iface->ImplementationIsInterface)
|
||||
{
|
||||
this->SetImportLinkProperty(suffix, target,
|
||||
"IMPORTED_LINK_INTERFACE_LIBRARIES",
|
||||
iface->Libraries, properties, missingTargets);
|
||||
return;
|
||||
}
|
||||
|
||||
const char *propContent;
|
||||
|
||||
if (const char *prop_suffixed = target->GetProperty(
|
||||
("LINK_INTERFACE_LIBRARIES" + suffix).c_str()))
|
||||
{
|
||||
propContent = prop_suffixed;
|
||||
}
|
||||
else if (const char *prop = target->GetProperty(
|
||||
"LINK_INTERFACE_LIBRARIES"))
|
||||
{
|
||||
propContent = prop;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*propContent)
|
||||
{
|
||||
properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = "";
|
||||
return;
|
||||
}
|
||||
|
||||
std::string prepro = cmGeneratorExpression::Preprocess(propContent,
|
||||
preprocessRule);
|
||||
if (!prepro.empty())
|
||||
{
|
||||
this->ResolveTargetsInGeneratorExpressions(prepro, target,
|
||||
missingTargets,
|
||||
ReplaceFreeTargets);
|
||||
properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -162,14 +453,13 @@ cmExportFileGenerator
|
|||
}
|
||||
|
||||
// Add the transitive link dependencies for this configuration.
|
||||
if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config))
|
||||
if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
|
||||
target))
|
||||
{
|
||||
this->SetImportLinkProperty(suffix, target,
|
||||
"IMPORTED_LINK_INTERFACE_LANGUAGES",
|
||||
iface->Languages, properties, missingTargets);
|
||||
this->SetImportLinkProperty(suffix, target,
|
||||
"IMPORTED_LINK_INTERFACE_LIBRARIES",
|
||||
iface->Libraries, properties, missingTargets);
|
||||
|
||||
this->SetImportLinkProperty(suffix, target,
|
||||
"IMPORTED_LINK_DEPENDENT_LIBRARIES",
|
||||
iface->SharedDeps, properties, missingTargets);
|
||||
|
@ -201,9 +491,6 @@ cmExportFileGenerator
|
|||
return;
|
||||
}
|
||||
|
||||
// Get the makefile in which to lookup target information.
|
||||
cmMakefile* mf = target->GetMakefile();
|
||||
|
||||
// Construct the property value.
|
||||
std::string link_libs;
|
||||
const char* sep = "";
|
||||
|
@ -214,33 +501,9 @@ cmExportFileGenerator
|
|||
link_libs += sep;
|
||||
sep = ";";
|
||||
|
||||
// Append this entry.
|
||||
if(cmTarget* tgt = mf->FindTargetToUse(li->c_str()))
|
||||
{
|
||||
// This is a target.
|
||||
if(tgt->IsImported())
|
||||
{
|
||||
// The target is imported (and therefore is not in the
|
||||
// export). Append the raw name.
|
||||
link_libs += *li;
|
||||
}
|
||||
else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
|
||||
{
|
||||
// The target is in the export. Append it with the export
|
||||
// namespace.
|
||||
link_libs += this->Namespace;
|
||||
link_libs += *li;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->HandleMissingTarget(link_libs, missingTargets, mf, target, tgt);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append the raw name.
|
||||
link_libs += *li;
|
||||
}
|
||||
std::string temp = *li;
|
||||
this->AddTargetNamespace(temp, target, missingTargets);
|
||||
link_libs += temp;
|
||||
}
|
||||
|
||||
// Store the property.
|
||||
|
@ -415,21 +678,29 @@ cmExportFileGenerator
|
|||
void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os,
|
||||
const std::vector<std::string>& missingTargets)
|
||||
{
|
||||
if (missingTargets.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
os << "# Make sure the targets which have been exported in some other \n"
|
||||
"# export set exist.\n";
|
||||
std::set<std::string> emitted;
|
||||
for(unsigned int i=0; i<missingTargets.size(); ++i)
|
||||
{
|
||||
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 \\\""
|
||||
<< missingTargets[i] << "\\\" not found ! \")\n"
|
||||
<< " ENDIF()\n"
|
||||
<< "ENDIF()\n";
|
||||
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 "
|
||||
<< "\"Required imported target \\\"" << missingTargets[i]
|
||||
<< "\\\" not found ! \")\n"
|
||||
<< " ELSE()\n"
|
||||
<< " MESSAGE(FATAL_ERROR \"Required imported target \\\""
|
||||
<< missingTargets[i] << "\\\" not found ! \")\n"
|
||||
<< " ENDIF()\n"
|
||||
<< "ENDIF()\n";
|
||||
}
|
||||
}
|
||||
os << "\n";
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#define cmExportFileGenerator_h
|
||||
|
||||
#include "cmCommand.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
|
||||
/** \class cmExportFileGenerator
|
||||
* \brief Generate a file exporting targets from a build or install tree.
|
||||
|
@ -46,7 +47,8 @@ protected:
|
|||
|
||||
// Generate per-configuration target information to the given output
|
||||
// stream.
|
||||
void GenerateImportConfig(std::ostream& os, const char* config);
|
||||
void GenerateImportConfig(std::ostream& os, const char* config,
|
||||
std::vector<std::string> &missingTargets);
|
||||
|
||||
// Methods to implement export file code generation.
|
||||
void GenerateImportHeaderCode(std::ostream& os, const char* config = 0);
|
||||
|
@ -84,7 +86,8 @@ protected:
|
|||
/** Each subclass knows where the target files are located. */
|
||||
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
||||
const char* config,
|
||||
std::string const& suffix) = 0;
|
||||
std::string const& suffix,
|
||||
std::vector<std::string> &missingTargets) = 0;
|
||||
|
||||
/** Each subclass knows how to deal with a target that is missing from an
|
||||
* export set. */
|
||||
|
@ -93,6 +96,30 @@ protected:
|
|||
cmMakefile* mf,
|
||||
cmTarget* depender,
|
||||
cmTarget* dependee) = 0;
|
||||
void PopulateInterfaceProperty(const char *,
|
||||
cmTarget *target,
|
||||
cmGeneratorExpression::PreprocessContext,
|
||||
ImportPropertyMap &properties,
|
||||
std::vector<std::string> &missingTargets);
|
||||
void PopulateInterfaceProperty(const char *propName, cmTarget *target,
|
||||
ImportPropertyMap &properties);
|
||||
void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
|
||||
const ImportPropertyMap &properties);
|
||||
|
||||
void SetImportLinkInterface(const char* config, std::string const& suffix,
|
||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||
cmTarget* target, ImportPropertyMap& properties,
|
||||
std::vector<std::string>& missingTargets);
|
||||
|
||||
enum FreeTargetsReplace {
|
||||
ReplaceFreeTargets,
|
||||
NoReplaceFreeTargets
|
||||
};
|
||||
|
||||
void ResolveTargetsInGeneratorExpressions(std::string &input,
|
||||
cmTarget* target,
|
||||
std::vector<std::string> &missingTargets,
|
||||
FreeTargetsReplace replace = NoReplaceFreeTargets);
|
||||
|
||||
// The namespace in which the exports are placed in the generated file.
|
||||
std::string Namespace;
|
||||
|
@ -109,6 +136,20 @@ protected:
|
|||
|
||||
// The set of targets included in the export.
|
||||
std::set<cmTarget*> ExportedTargets;
|
||||
|
||||
private:
|
||||
void PopulateInterfaceProperty(const char *, const char *,
|
||||
cmTarget *target,
|
||||
cmGeneratorExpression::PreprocessContext,
|
||||
ImportPropertyMap &properties,
|
||||
std::vector<std::string> &missingTargets);
|
||||
|
||||
bool AddTargetNamespace(std::string &input, cmTarget* target,
|
||||
std::vector<std::string> &missingTargets);
|
||||
|
||||
void ResolveTargetsInGeneratorExpression(std::string &input,
|
||||
cmTarget* target,
|
||||
std::vector<std::string> &missingTargets);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -39,6 +39,7 @@ std::string cmExportInstallFileGenerator::GetConfigImportFileGlob()
|
|||
//----------------------------------------------------------------------------
|
||||
bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
||||
{
|
||||
std::vector<cmTarget*> allTargets;
|
||||
{
|
||||
std::string expectedTargets;
|
||||
std::string sep;
|
||||
|
@ -48,20 +49,10 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
{
|
||||
expectedTargets += sep + this->Namespace + (*tei)->Target->GetName();
|
||||
sep = " ";
|
||||
}
|
||||
|
||||
this->GenerateExpectedTargetsCode(os, expectedTargets);
|
||||
}
|
||||
|
||||
// Create all the imported targets.
|
||||
for(std::vector<cmTargetExport*>::const_iterator
|
||||
tei = this->IEGen->GetExportSet()->GetTargetExports()->begin();
|
||||
tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei)
|
||||
{
|
||||
cmTargetExport const* te = *tei;
|
||||
if(this->ExportedTargets.insert(te->Target).second)
|
||||
{
|
||||
this->GenerateImportTargetCode(os, te->Target);
|
||||
allTargets.push_back(te->Target);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -75,6 +66,36 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
}
|
||||
}
|
||||
|
||||
this->GenerateExpectedTargetsCode(os, expectedTargets);
|
||||
}
|
||||
|
||||
std::vector<std::string> missingTargets;
|
||||
|
||||
// Create all the imported targets.
|
||||
for(std::vector<cmTarget*>::const_iterator
|
||||
tei = allTargets.begin();
|
||||
tei != allTargets.end(); ++tei)
|
||||
{
|
||||
cmTarget* te = *tei;
|
||||
this->GenerateImportTargetCode(os, te);
|
||||
|
||||
ImportPropertyMap properties;
|
||||
|
||||
this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES",
|
||||
te,
|
||||
cmGeneratorExpression::InstallInterface,
|
||||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS",
|
||||
te,
|
||||
cmGeneratorExpression::InstallInterface,
|
||||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
|
||||
te, properties);
|
||||
|
||||
this->GenerateInterfaceProperties(te, os, properties);
|
||||
}
|
||||
|
||||
|
||||
// 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"
|
||||
|
@ -85,23 +106,29 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||
<< "ENDFOREACH(f)\n"
|
||||
<< "\n";
|
||||
|
||||
this->GenerateImportedFileCheckLoop(os);
|
||||
|
||||
// Generate an import file for each configuration.
|
||||
bool result = true;
|
||||
for(std::vector<std::string>::const_iterator
|
||||
ci = this->Configurations.begin();
|
||||
ci != this->Configurations.end(); ++ci)
|
||||
{
|
||||
if(!this->GenerateImportFileConfig(ci->c_str()))
|
||||
if(!this->GenerateImportFileConfig(ci->c_str(), missingTargets))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
|
||||
cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config,
|
||||
std::vector<std::string> &missingTargets)
|
||||
{
|
||||
// Skip configurations not enabled for this export.
|
||||
if(!this->IEGen->InstallsForConfig(config))
|
||||
|
@ -141,7 +168,7 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
|
|||
this->GenerateImportHeaderCode(os, config);
|
||||
|
||||
// Generate the per-config target information.
|
||||
this->GenerateImportConfig(os, config);
|
||||
this->GenerateImportConfig(os, config, missingTargets);
|
||||
|
||||
// End with the import file footer.
|
||||
this->GenerateImportFooterCode(os);
|
||||
|
@ -156,7 +183,8 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
|
|||
void
|
||||
cmExportInstallFileGenerator
|
||||
::GenerateImportTargetsConfig(std::ostream& os,
|
||||
const char* config, std::string const& suffix)
|
||||
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.
|
||||
|
@ -205,10 +233,13 @@ cmExportInstallFileGenerator
|
|||
if(!properties.empty())
|
||||
{
|
||||
// Get the rest of the target details.
|
||||
std::vector<std::string> missingTargets;
|
||||
this->SetImportDetailProperties(config, suffix,
|
||||
te->Target, properties, missingTargets);
|
||||
|
||||
this->SetImportLinkInterface(config, suffix,
|
||||
cmGeneratorExpression::InstallInterface,
|
||||
te->Target, properties, missingTargets);
|
||||
|
||||
// TOOD: PUBLIC_HEADER_LOCATION
|
||||
// This should wait until the build feature propagation stuff
|
||||
// is done. Then this can be a propagated include directory.
|
||||
|
@ -216,15 +247,12 @@ cmExportInstallFileGenerator
|
|||
// properties);
|
||||
|
||||
// Generate code in the export file.
|
||||
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
||||
this->GenerateImportPropertyCode(os, config, te->Target, properties);
|
||||
this->GenerateImportedFileChecksCode(os, te->Target, properties,
|
||||
importedLocations);
|
||||
}
|
||||
}
|
||||
|
||||
this->GenerateImportedFileCheckLoop(os);
|
||||
|
||||
// Cleanup the import prefix variable.
|
||||
if(!this->ImportPrefix.empty())
|
||||
{
|
||||
|
|
|
@ -56,7 +56,8 @@ protected:
|
|||
virtual bool GenerateMainFile(std::ostream& os);
|
||||
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
||||
const char* config,
|
||||
std::string const& suffix);
|
||||
std::string const& suffix,
|
||||
std::vector<std::string> &missingTargets);
|
||||
virtual void HandleMissingTarget(std::string& link_libs,
|
||||
std::vector<std::string>& missingTargets,
|
||||
cmMakefile* mf,
|
||||
|
@ -72,7 +73,8 @@ protected:
|
|||
|
||||
|
||||
/** Generate a per-configuration file for the targets. */
|
||||
bool GenerateImportFileConfig(const char* config);
|
||||
bool GenerateImportFileConfig(const char* config,
|
||||
std::vector<std::string> &missingTargets);
|
||||
|
||||
/** Fill in properties indicating installed file locations. */
|
||||
void SetImportLocationProperty(const char* config,
|
||||
|
|
|
@ -811,6 +811,11 @@ std::string cmExtraCodeBlocksGenerator::BuildMakeCommand(
|
|||
command += " VERBOSE=1 ";
|
||||
command += target;
|
||||
}
|
||||
else if (strcmp(this->GlobalGenerator->GetName(), "Ninja")==0)
|
||||
{
|
||||
command += " -v ";
|
||||
command += target;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include "cmFileTimeComparison.h"
|
||||
#include "cmCryptoHash.h"
|
||||
|
||||
#include "cmTimestamp.h"
|
||||
|
||||
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
||||
#include "cm_curl.h"
|
||||
#endif
|
||||
|
@ -161,6 +163,10 @@ bool cmFileCommand
|
|||
{
|
||||
return this->HandleCMakePathCommand(args, true);
|
||||
}
|
||||
else if ( subCommand == "TIMESTAMP" )
|
||||
{
|
||||
return this->HandleTimestampCommand(args);
|
||||
}
|
||||
|
||||
std::string e = "does not recognize sub-command "+subCommand;
|
||||
this->SetError(e.c_str());
|
||||
|
@ -3241,3 +3247,54 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
|
|||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmFileCommand::HandleTimestampCommand(
|
||||
std::vector<std::string> const& args)
|
||||
{
|
||||
if(args.size() < 3)
|
||||
{
|
||||
this->SetError("sub-command TIMESTAMP requires at least two arguments.");
|
||||
return false;
|
||||
}
|
||||
else if(args.size() > 5)
|
||||
{
|
||||
this->SetError("sub-command TIMESTAMP takes at most four arguments.");
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int argsIndex = 1;
|
||||
|
||||
const std::string& filename = args[argsIndex++];
|
||||
|
||||
const std::string& outputVariable = args[argsIndex++];
|
||||
|
||||
std::string formatString;
|
||||
if(args.size() > argsIndex && args[argsIndex] != "UTC")
|
||||
{
|
||||
formatString = args[argsIndex++];
|
||||
}
|
||||
|
||||
bool utcFlag = false;
|
||||
if(args.size() > argsIndex)
|
||||
{
|
||||
if(args[argsIndex] == "UTC")
|
||||
{
|
||||
utcFlag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string e = " TIMESTAMP sub-command does not recognize option " +
|
||||
args[argsIndex] + ".";
|
||||
this->SetError(e.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cmTimestamp timestamp;
|
||||
std::string result = timestamp.FileModificationTime(
|
||||
filename.c_str(), formatString, utcFlag);
|
||||
this->Makefile->AddDefinition(outputVariable.c_str(), result.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ public:
|
|||
" [TLS_VERIFY on|off] [TLS_CAINFO file])\n"
|
||||
" file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n"
|
||||
" [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\n"
|
||||
" file(TIMESTAMP filename variable [<format string>] [UTC])\n"
|
||||
"WRITE will write a message into a file called 'filename'. It "
|
||||
"overwrites the file if it already exists, and creates the file "
|
||||
"if it does not exist. (If the file is a build input, use "
|
||||
|
@ -200,6 +201,12 @@ public:
|
|||
"If SHOW_PROGRESS is specified, progress information will be printed "
|
||||
"as status messages until the operation is complete."
|
||||
"\n"
|
||||
"TIMESTAMP will write a string representation of "
|
||||
"the modification time of filename to variable.\n"
|
||||
"Should the command be unable to obtain a timestamp "
|
||||
"variable will be set to the empty string \"\".\n"
|
||||
"See documentation of the string TIMESTAMP sub-command for more details."
|
||||
"\n"
|
||||
"The file() command also provides COPY and INSTALL signatures:\n"
|
||||
" file(<COPY|INSTALL> files... DESTINATION <dir>\n"
|
||||
" [FILE_PERMISSIONS permissions...]\n"
|
||||
|
@ -260,6 +267,8 @@ protected:
|
|||
bool HandleInstallCommand(std::vector<std::string> const& args);
|
||||
bool HandleDownloadCommand(std::vector<std::string> const& args);
|
||||
bool HandleUploadCommand(std::vector<std::string> const& args);
|
||||
|
||||
bool HandleTimestampCommand(std::vector<std::string> const& args);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -25,55 +25,55 @@
|
|||
//----------------------------------------------------------------------------
|
||||
cmGeneratorExpression::cmGeneratorExpression(
|
||||
cmListFileBacktrace const& backtrace):
|
||||
Backtrace(backtrace), CompiledExpression(0)
|
||||
Backtrace(backtrace)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const cmCompiledGeneratorExpression &
|
||||
cmsys::auto_ptr<cmCompiledGeneratorExpression>
|
||||
cmGeneratorExpression::Parse(std::string const& input)
|
||||
{
|
||||
return this->Parse(input.c_str());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const cmCompiledGeneratorExpression &
|
||||
cmsys::auto_ptr<cmCompiledGeneratorExpression>
|
||||
cmGeneratorExpression::Parse(const char* input)
|
||||
{
|
||||
cmGeneratorExpressionLexer l;
|
||||
std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(input);
|
||||
bool needsParsing = l.GetSawGeneratorExpression();
|
||||
std::vector<cmGeneratorExpressionEvaluator*> evaluators;
|
||||
|
||||
if (needsParsing)
|
||||
{
|
||||
cmGeneratorExpressionParser p(tokens);
|
||||
p.Parse(evaluators);
|
||||
}
|
||||
|
||||
delete this->CompiledExpression;
|
||||
this->CompiledExpression = new cmCompiledGeneratorExpression(
|
||||
this->Backtrace,
|
||||
evaluators,
|
||||
input,
|
||||
needsParsing);
|
||||
return *this->CompiledExpression;
|
||||
return cmsys::auto_ptr<cmCompiledGeneratorExpression>(
|
||||
new cmCompiledGeneratorExpression(
|
||||
this->Backtrace,
|
||||
input));
|
||||
}
|
||||
|
||||
cmGeneratorExpression::~cmGeneratorExpression()
|
||||
{
|
||||
delete this->CompiledExpression;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char *cmCompiledGeneratorExpression::Evaluate(
|
||||
cmMakefile* mf, const char* config, bool quiet,
|
||||
cmTarget *target,
|
||||
cmTarget *headTarget,
|
||||
cmGeneratorExpressionDAGChecker *dagChecker) const
|
||||
{
|
||||
return this->Evaluate(mf,
|
||||
config,
|
||||
quiet,
|
||||
headTarget,
|
||||
headTarget,
|
||||
dagChecker);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char *cmCompiledGeneratorExpression::Evaluate(
|
||||
cmMakefile* mf, const char* config, bool quiet,
|
||||
cmTarget *headTarget,
|
||||
cmTarget *currentTarget,
|
||||
cmGeneratorExpressionDAGChecker *dagChecker) const
|
||||
{
|
||||
if (!this->NeedsParsing)
|
||||
{
|
||||
return this->Input;
|
||||
return this->Input.c_str();
|
||||
}
|
||||
|
||||
this->Output = "";
|
||||
|
@ -88,12 +88,21 @@ const char *cmCompiledGeneratorExpression::Evaluate(
|
|||
context.Config = config;
|
||||
context.Quiet = quiet;
|
||||
context.HadError = false;
|
||||
context.Target = target;
|
||||
context.HeadTarget = headTarget;
|
||||
context.CurrentTarget = currentTarget ? currentTarget : headTarget;
|
||||
context.Backtrace = this->Backtrace;
|
||||
|
||||
for ( ; it != end; ++it)
|
||||
{
|
||||
this->Output += (*it)->Evaluate(&context, dagChecker);
|
||||
const std::string result = (*it)->Evaluate(&context, dagChecker);
|
||||
this->Output += result;
|
||||
|
||||
for(std::set<cmStdString>::const_iterator
|
||||
p = context.SeenTargetProperties.begin();
|
||||
p != context.SeenTargetProperties.end(); ++p)
|
||||
{
|
||||
this->SeenTargetProperties[*p] += result + ";";
|
||||
}
|
||||
if (context.HadError)
|
||||
{
|
||||
this->Output = "";
|
||||
|
@ -108,12 +117,19 @@ const char *cmCompiledGeneratorExpression::Evaluate(
|
|||
|
||||
cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
|
||||
cmListFileBacktrace const& backtrace,
|
||||
const std::vector<cmGeneratorExpressionEvaluator*> &evaluators,
|
||||
const char *input, bool needsParsing)
|
||||
: Backtrace(backtrace), Evaluators(evaluators), Input(input),
|
||||
NeedsParsing(needsParsing)
|
||||
const char *input)
|
||||
: Backtrace(backtrace), Input(input ? input : "")
|
||||
{
|
||||
cmGeneratorExpressionLexer l;
|
||||
std::vector<cmGeneratorExpressionToken> tokens =
|
||||
l.Tokenize(this->Input.c_str());
|
||||
this->NeedsParsing = l.GetSawGeneratorExpression();
|
||||
|
||||
if (this->NeedsParsing)
|
||||
{
|
||||
cmGeneratorExpressionParser p(tokens);
|
||||
p.Parse(this->Evaluators);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -131,15 +147,41 @@ cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression()
|
|||
}
|
||||
}
|
||||
|
||||
std::string cmGeneratorExpression::Preprocess(const std::string &input,
|
||||
PreprocessContext context)
|
||||
//----------------------------------------------------------------------------
|
||||
static std::string stripEmptyListElements(const std::string &input)
|
||||
{
|
||||
if (context != StripAllGeneratorExpressions)
|
||||
{
|
||||
assert(!"cmGeneratorExpression::Preprocess called with invalid args");
|
||||
return std::string();
|
||||
}
|
||||
std::string result;
|
||||
|
||||
const char *c = input.c_str();
|
||||
bool skipSemiColons = true;
|
||||
for ( ; *c; ++c)
|
||||
{
|
||||
if(c[0] == ';')
|
||||
{
|
||||
if(skipSemiColons)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
skipSemiColons = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
skipSemiColons = false;
|
||||
}
|
||||
result += *c;
|
||||
}
|
||||
|
||||
if (!result.empty() && *(result.end() - 1) == ';')
|
||||
{
|
||||
result.resize(result.size() - 1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static std::string stripAllGeneratorExpressions(const std::string &input)
|
||||
{
|
||||
std::string result;
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type lastPos = pos;
|
||||
|
@ -176,5 +218,144 @@ std::string cmGeneratorExpression::Preprocess(const std::string &input,
|
|||
lastPos = pos;
|
||||
}
|
||||
result += input.substr(lastPos);
|
||||
return result;
|
||||
return stripEmptyListElements(result);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static std::string stripExportInterface(const std::string &input,
|
||||
cmGeneratorExpression::PreprocessContext context)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type lastPos = pos;
|
||||
while((pos = input.find("$<BUILD_INTERFACE:", lastPos)) != input.npos
|
||||
|| (pos = input.find("$<INSTALL_INTERFACE:", lastPos)) != input.npos)
|
||||
{
|
||||
result += input.substr(lastPos, pos - lastPos);
|
||||
const bool gotInstallInterface = input[pos + 2] == 'I';
|
||||
pos += gotInstallInterface ? sizeof("$<INSTALL_INTERFACE:") - 1
|
||||
: sizeof("$<BUILD_INTERFACE:") - 1;
|
||||
int nestingLevel = 1;
|
||||
const char *c = input.c_str() + pos;
|
||||
const char * const cStart = c;
|
||||
for ( ; *c; ++c)
|
||||
{
|
||||
if(c[0] == '$' && c[1] == '<')
|
||||
{
|
||||
++nestingLevel;
|
||||
++c;
|
||||
continue;
|
||||
}
|
||||
if(c[0] == '>')
|
||||
{
|
||||
--nestingLevel;
|
||||
if (nestingLevel != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(context == cmGeneratorExpression::BuildInterface
|
||||
&& !gotInstallInterface)
|
||||
{
|
||||
result += input.substr(pos, c - cStart);
|
||||
}
|
||||
else if(context == cmGeneratorExpression::InstallInterface
|
||||
&& gotInstallInterface)
|
||||
{
|
||||
result += input.substr(pos, c - cStart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
const std::string::size_type traversed = (c - cStart) + 1;
|
||||
if (!*c)
|
||||
{
|
||||
result += std::string(gotInstallInterface ? "$<INSTALL_INTERFACE:"
|
||||
: "$<BUILD_INTERFACE:")
|
||||
+ input.substr(pos, traversed);
|
||||
}
|
||||
pos += traversed;
|
||||
lastPos = pos;
|
||||
}
|
||||
result += input.substr(lastPos);
|
||||
|
||||
return stripEmptyListElements(result);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGeneratorExpression::Split(const std::string &input,
|
||||
std::vector<std::string> &output)
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type lastPos = pos;
|
||||
while((pos = input.find("$<", lastPos)) != input.npos)
|
||||
{
|
||||
std::string part = input.substr(lastPos, pos - lastPos);
|
||||
std::string preGenex;
|
||||
if (!part.empty())
|
||||
{
|
||||
std::string::size_type startPos = input.rfind(";", pos);
|
||||
if (startPos != pos - 1 && startPos >= lastPos)
|
||||
{
|
||||
part = input.substr(lastPos, startPos - lastPos);
|
||||
preGenex = input.substr(startPos + 1, pos - startPos - 1);
|
||||
}
|
||||
cmSystemTools::ExpandListArgument(part.c_str(), output);
|
||||
}
|
||||
pos += 2;
|
||||
int nestingLevel = 1;
|
||||
const char *c = input.c_str() + pos;
|
||||
const char * const cStart = c;
|
||||
for ( ; *c; ++c)
|
||||
{
|
||||
if(c[0] == '$' && c[1] == '<')
|
||||
{
|
||||
++nestingLevel;
|
||||
++c;
|
||||
continue;
|
||||
}
|
||||
if(c[0] == '>')
|
||||
{
|
||||
--nestingLevel;
|
||||
if (nestingLevel == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( ; *c; ++c)
|
||||
{
|
||||
// Capture the part after the genex and before the next ';'
|
||||
if(c[0] == ';')
|
||||
{
|
||||
--c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const std::string::size_type traversed = (c - cStart) + 1;
|
||||
output.push_back(preGenex + "$<" + input.substr(pos, traversed));
|
||||
pos += traversed;
|
||||
lastPos = pos;
|
||||
}
|
||||
if (lastPos < input.size())
|
||||
{
|
||||
cmSystemTools::ExpandListArgument(input.substr(lastPos), output);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmGeneratorExpression::Preprocess(const std::string &input,
|
||||
PreprocessContext context)
|
||||
{
|
||||
if (context == StripAllGeneratorExpressions)
|
||||
{
|
||||
return stripAllGeneratorExpressions(input);
|
||||
}
|
||||
else if (context == BuildInterface || context == InstallInterface)
|
||||
{
|
||||
return stripExportInterface(input, context);
|
||||
}
|
||||
|
||||
assert(!"cmGeneratorExpression::Preprocess called with invalid args");
|
||||
return std::string();
|
||||
}
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
#define cmGeneratorExpression_h
|
||||
|
||||
#include "cmStandardIncludes.h"
|
||||
#include "cmListFileCache.h"
|
||||
|
||||
#include <stack>
|
||||
|
||||
#include <cmsys/RegularExpression.hxx>
|
||||
#include <cmsys/auto_ptr.hxx>
|
||||
|
||||
class cmTarget;
|
||||
class cmMakefile;
|
||||
|
@ -44,22 +46,27 @@ public:
|
|||
cmGeneratorExpression(cmListFileBacktrace const& backtrace);
|
||||
~cmGeneratorExpression();
|
||||
|
||||
const cmCompiledGeneratorExpression& Parse(std::string const& input);
|
||||
const cmCompiledGeneratorExpression& Parse(const char* input);
|
||||
cmsys::auto_ptr<cmCompiledGeneratorExpression> Parse(
|
||||
std::string const& input);
|
||||
cmsys::auto_ptr<cmCompiledGeneratorExpression> Parse(const char* input);
|
||||
|
||||
enum PreprocessContext {
|
||||
StripAllGeneratorExpressions
|
||||
StripAllGeneratorExpressions,
|
||||
BuildInterface,
|
||||
InstallInterface
|
||||
};
|
||||
|
||||
static std::string Preprocess(const std::string &input,
|
||||
PreprocessContext context);
|
||||
|
||||
static void Split(const std::string &input,
|
||||
std::vector<std::string> &output);
|
||||
|
||||
private:
|
||||
cmGeneratorExpression(const cmGeneratorExpression &);
|
||||
void operator=(const cmGeneratorExpression &);
|
||||
|
||||
cmListFileBacktrace const& Backtrace;
|
||||
cmCompiledGeneratorExpression *CompiledExpression;
|
||||
};
|
||||
|
||||
class cmCompiledGeneratorExpression
|
||||
|
@ -67,31 +74,49 @@ class cmCompiledGeneratorExpression
|
|||
public:
|
||||
const char* Evaluate(cmMakefile* mf, const char* config,
|
||||
bool quiet = false,
|
||||
cmTarget *target = 0,
|
||||
cmTarget *headTarget = 0,
|
||||
cmTarget *currentTarget = 0,
|
||||
cmGeneratorExpressionDAGChecker *dagChecker = 0) const;
|
||||
const char* Evaluate(cmMakefile* mf, const char* config,
|
||||
bool quiet,
|
||||
cmTarget *headTarget,
|
||||
cmGeneratorExpressionDAGChecker *dagChecker) const;
|
||||
|
||||
/** Get set of targets found during evaluations. */
|
||||
std::set<cmTarget*> const& GetTargets() const
|
||||
{ return this->Targets; }
|
||||
|
||||
std::map<cmStdString, cmStdString> const& GetSeenTargetProperties() const
|
||||
{ return this->SeenTargetProperties; }
|
||||
|
||||
~cmCompiledGeneratorExpression();
|
||||
|
||||
std::string GetInput() const
|
||||
{
|
||||
return this->Input;
|
||||
}
|
||||
|
||||
cmListFileBacktrace GetBacktrace() const
|
||||
{
|
||||
return this->Backtrace;
|
||||
}
|
||||
|
||||
private:
|
||||
cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace,
|
||||
const std::vector<cmGeneratorExpressionEvaluator*> &evaluators,
|
||||
const char *input, bool needsParsing);
|
||||
const char *input);
|
||||
|
||||
friend class cmGeneratorExpression;
|
||||
|
||||
cmCompiledGeneratorExpression(const cmCompiledGeneratorExpression &);
|
||||
void operator=(const cmCompiledGeneratorExpression &);
|
||||
|
||||
cmListFileBacktrace const& Backtrace;
|
||||
const std::vector<cmGeneratorExpressionEvaluator*> Evaluators;
|
||||
const char* const Input;
|
||||
const bool NeedsParsing;
|
||||
cmListFileBacktrace Backtrace;
|
||||
std::vector<cmGeneratorExpressionEvaluator*> Evaluators;
|
||||
const std::string Input;
|
||||
bool NeedsParsing;
|
||||
|
||||
mutable std::set<cmTarget*> Targets;
|
||||
mutable std::map<cmStdString, cmStdString> SeenTargetProperties;
|
||||
mutable std::string Output;
|
||||
};
|
||||
|
||||
|
|
|
@ -24,13 +24,14 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
|
|||
: Parent(parent), Target(target), Property(property),
|
||||
Content(content), Backtrace(backtrace)
|
||||
{
|
||||
this->IsDAG = this->isDAG();
|
||||
this->CheckResult = this->checkGraph();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmGeneratorExpressionDAGChecker::check() const
|
||||
cmGeneratorExpressionDAGChecker::Result
|
||||
cmGeneratorExpressionDAGChecker::check() const
|
||||
{
|
||||
return this->IsDAG;
|
||||
return this->CheckResult;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -38,7 +39,7 @@ void cmGeneratorExpressionDAGChecker::reportError(
|
|||
cmGeneratorExpressionContext *context,
|
||||
const std::string &expr)
|
||||
{
|
||||
if (this->IsDAG)
|
||||
if (this->CheckResult == DAG)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -57,7 +58,7 @@ void cmGeneratorExpressionDAGChecker::reportError(
|
|||
e << "Error evaluating generator expression:\n"
|
||||
<< " " << expr << "\n"
|
||||
<< "Self reference on target \""
|
||||
<< context->Target->GetName() << "\".\n";
|
||||
<< context->HeadTarget->GetName() << "\".\n";
|
||||
context->Makefile->GetCMakeInstance()
|
||||
->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(),
|
||||
parent->Backtrace);
|
||||
|
@ -91,16 +92,17 @@ void cmGeneratorExpressionDAGChecker::reportError(
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmGeneratorExpressionDAGChecker::isDAG() const
|
||||
cmGeneratorExpressionDAGChecker::Result
|
||||
cmGeneratorExpressionDAGChecker::checkGraph() const
|
||||
{
|
||||
const cmGeneratorExpressionDAGChecker *parent = this->Parent;
|
||||
while (parent)
|
||||
{
|
||||
if (this->Target == parent->Target && this->Property == parent->Property)
|
||||
{
|
||||
return false;
|
||||
return parent->Parent ? CYCLIC_REFERENCE : SELF_REFERENCE;
|
||||
}
|
||||
parent = parent->Parent;
|
||||
}
|
||||
return true;
|
||||
return DAG;
|
||||
}
|
||||
|
|
|
@ -25,12 +25,18 @@ struct cmGeneratorExpressionDAGChecker
|
|||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *parent);
|
||||
|
||||
bool check() const;
|
||||
enum Result {
|
||||
DAG,
|
||||
SELF_REFERENCE,
|
||||
CYCLIC_REFERENCE
|
||||
};
|
||||
|
||||
Result check() const;
|
||||
|
||||
void reportError(cmGeneratorExpressionContext *context,
|
||||
const std::string &expr);
|
||||
private:
|
||||
bool isDAG() const;
|
||||
Result checkGraph() const;
|
||||
|
||||
private:
|
||||
const cmGeneratorExpressionDAGChecker * const Parent;
|
||||
|
@ -38,7 +44,7 @@ private:
|
|||
const std::string Property;
|
||||
const GeneratorExpressionContent * const Content;
|
||||
const cmListFileBacktrace Backtrace;
|
||||
bool IsDAG;
|
||||
Result CheckResult;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include <cmsys/String.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
#if !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x510
|
||||
static
|
||||
|
@ -47,6 +49,8 @@ struct cmGeneratorExpressionNode
|
|||
|
||||
virtual bool GeneratesContent() const { return true; }
|
||||
|
||||
virtual bool RequiresLiteralInput() const { return false; }
|
||||
|
||||
virtual bool AcceptsSingleArbitraryContentParameter() const
|
||||
{ return false; }
|
||||
|
||||
|
@ -95,6 +99,12 @@ static const struct OneNode : public cmGeneratorExpressionNode
|
|||
}
|
||||
} oneNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct OneNode buildInterfaceNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct ZeroNode installInterfaceNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
#define BOOLEAN_OP_NODE(OPNAME, OP, SUCCESS_VALUE, FAILURE_VALUE) \
|
||||
static const struct OP ## Node : public cmGeneratorExpressionNode \
|
||||
|
@ -257,11 +267,50 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
|
|||
return parameters.front().empty() ? "1" : "0";
|
||||
}
|
||||
|
||||
return cmsysString_strcasecmp(parameters.begin()->c_str(),
|
||||
context->Config) == 0 ? "1" : "0";
|
||||
if (cmsysString_strcasecmp(parameters.begin()->c_str(),
|
||||
context->Config) == 0)
|
||||
{
|
||||
return "1";
|
||||
}
|
||||
|
||||
if (context->CurrentTarget
|
||||
&& context->CurrentTarget->IsImported())
|
||||
{
|
||||
const char* loc = 0;
|
||||
const char* imp = 0;
|
||||
std::string suffix;
|
||||
return context->CurrentTarget->GetMappedConfig(context->Config,
|
||||
&loc,
|
||||
&imp,
|
||||
suffix) ? "1" : "0";
|
||||
}
|
||||
return "0";
|
||||
}
|
||||
} configurationTestNode;
|
||||
|
||||
|
||||
static const struct TargetDefinedNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
TargetDefinedNode() {}
|
||||
|
||||
virtual int NumExpectedParameters() const { return 1; }
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
return context->Makefile->FindTargetToUse(parameters.front().c_str())
|
||||
? "1" : "0";
|
||||
}
|
||||
} targetDefinedNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const char* targetPropertyTransitiveWhitelist[] = {
|
||||
"INTERFACE_INCLUDE_DIRECTORIES"
|
||||
, "INTERFACE_COMPILE_DEFINITIONS"
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
|
@ -289,8 +338,19 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|||
cmsys::RegularExpression propertyNameValidator;
|
||||
propertyNameValidator.compile("^[A-Za-z0-9_]+$");
|
||||
|
||||
cmTarget* target = context->Target;
|
||||
cmTarget* target = context->HeadTarget;
|
||||
std::string propertyName = *parameters.begin();
|
||||
|
||||
if (!target && parameters.size() == 1)
|
||||
{
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
"$<TARGET_PROPERTY:prop> may only be used with targets. It may not "
|
||||
"be used with add_custom_command. Specify the target to read a "
|
||||
"property from using the $<TARGET_PROPERTY:tgt,prop> signature "
|
||||
"instead.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (parameters.size() == 2)
|
||||
{
|
||||
if (parameters.begin()->empty() && parameters[1].empty())
|
||||
|
@ -336,6 +396,14 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|||
}
|
||||
}
|
||||
|
||||
if (target == context->HeadTarget)
|
||||
{
|
||||
// Keep track of the properties seen while processing.
|
||||
// The evaluation of the LINK_LIBRARIES generator expressions
|
||||
// will check this to ensure that properties form a DAG.
|
||||
context->SeenTargetProperties.insert(propertyName);
|
||||
}
|
||||
|
||||
if (propertyName.empty())
|
||||
{
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
|
@ -351,23 +419,74 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|||
return std::string();
|
||||
}
|
||||
|
||||
assert(target);
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace,
|
||||
target->GetName(),
|
||||
propertyName,
|
||||
content,
|
||||
dagCheckerParent);
|
||||
|
||||
if (!dagChecker.check())
|
||||
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::DAG:
|
||||
break;
|
||||
}
|
||||
|
||||
const char *prop = target->GetProperty(propertyName.c_str());
|
||||
return prop ? prop : "";
|
||||
if (!prop)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
for (size_t i = 0;
|
||||
i < (sizeof(targetPropertyTransitiveWhitelist) /
|
||||
sizeof(*targetPropertyTransitiveWhitelist));
|
||||
++i)
|
||||
{
|
||||
if (targetPropertyTransitiveWhitelist[i] == propertyName)
|
||||
{
|
||||
cmGeneratorExpression ge(context->Backtrace);
|
||||
return ge.Parse(prop)->Evaluate(context->Makefile,
|
||||
context->Config,
|
||||
context->Quiet,
|
||||
context->HeadTarget,
|
||||
target,
|
||||
&dagChecker);
|
||||
}
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
} targetPropertyNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct TargetNameNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
TargetNameNode() {}
|
||||
|
||||
virtual bool GeneratesContent() const { return true; }
|
||||
|
||||
virtual bool AcceptsSingleArbitraryContentParameter() const { return true; }
|
||||
virtual bool RequiresLiteralInput() const { return true; }
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *,
|
||||
const GeneratorExpressionContent *,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
return parameters.front();
|
||||
}
|
||||
|
||||
virtual int NumExpectedParameters() const { return 1; }
|
||||
|
||||
} targetNameNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<bool linker, bool soname>
|
||||
struct TargetFilesystemArtifactResultCreator
|
||||
|
@ -553,13 +672,13 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
|
|||
{
|
||||
if (identifier == "0")
|
||||
return &zeroNode;
|
||||
if (identifier == "1")
|
||||
else if (identifier == "1")
|
||||
return &oneNode;
|
||||
if (identifier == "AND")
|
||||
else if (identifier == "AND")
|
||||
return &andNode;
|
||||
if (identifier == "OR")
|
||||
else if (identifier == "OR")
|
||||
return &orNode;
|
||||
if (identifier == "NOT")
|
||||
else if (identifier == "NOT")
|
||||
return ¬Node;
|
||||
else if (identifier == "CONFIGURATION")
|
||||
return &configurationNode;
|
||||
|
@ -593,6 +712,14 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
|
|||
return &commaNode;
|
||||
else if (identifier == "TARGET_PROPERTY")
|
||||
return &targetPropertyNode;
|
||||
else if (identifier == "TARGET_NAME")
|
||||
return &targetNameNode;
|
||||
else if (identifier == "BUILD_INTERFACE")
|
||||
return &buildInterfaceNode;
|
||||
else if (identifier == "INSTALL_INTERFACE")
|
||||
return &installInterfaceNode;
|
||||
else if (identifier == "TARGET_DEFINED")
|
||||
return &targetDefinedNode;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
@ -682,6 +809,15 @@ std::string GeneratorExpressionContent::Evaluate(
|
|||
= pit->end();
|
||||
for ( ; it != end; ++it)
|
||||
{
|
||||
if (node->RequiresLiteralInput())
|
||||
{
|
||||
if ((*it)->GetType() != cmGeneratorExpressionEvaluator::Text)
|
||||
{
|
||||
reportError(context, this->GetOriginalExpression(),
|
||||
"$<" + identifier + "> expression requires literal input.");
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
result += (*it)->Evaluate(context, dagChecker);
|
||||
if (context->HadError)
|
||||
{
|
||||
|
@ -689,6 +825,12 @@ std::string GeneratorExpressionContent::Evaluate(
|
|||
}
|
||||
}
|
||||
}
|
||||
if (node->RequiresLiteralInput())
|
||||
{
|
||||
std::vector<std::string> parameters;
|
||||
parameters.push_back(result);
|
||||
return node->Evaluate(parameters, context, this, dagChecker);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,12 @@ struct cmGeneratorExpressionContext
|
|||
{
|
||||
cmListFileBacktrace Backtrace;
|
||||
std::set<cmTarget*> Targets;
|
||||
std::set<cmStdString> SeenTargetProperties;
|
||||
cmMakefile *Makefile;
|
||||
const char *Config;
|
||||
cmTarget *Target;
|
||||
cmTarget *HeadTarget; // The target whose property is being evaluated.
|
||||
cmTarget *CurrentTarget; // The dependent of HeadTarget which appears
|
||||
// directly or indirectly in the property.
|
||||
bool Quiet;
|
||||
bool HadError;
|
||||
};
|
||||
|
|
|
@ -252,45 +252,7 @@ const char* cmGeneratorTarget::GetCreateRuleVariable()
|
|||
std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
|
||||
const char *config)
|
||||
{
|
||||
std::vector<std::string> includes;
|
||||
const char *prop = this->Target->GetProperty("INCLUDE_DIRECTORIES");
|
||||
if(!prop)
|
||||
{
|
||||
return includes;
|
||||
}
|
||||
|
||||
cmListFileBacktrace lfbt;
|
||||
cmGeneratorExpression ge(lfbt);
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
|
||||
this->GetName(),
|
||||
"INCLUDE_DIRECTORIES", 0, 0);
|
||||
|
||||
cmSystemTools::ExpandListArgument(ge.Parse(prop)
|
||||
.Evaluate(this->Makefile,
|
||||
config,
|
||||
false,
|
||||
this->Target,
|
||||
&dagChecker),
|
||||
includes);
|
||||
|
||||
std::set<std::string> uniqueIncludes;
|
||||
std::vector<std::string> orderedAndUniqueIncludes;
|
||||
for(std::vector<std::string>::const_iterator
|
||||
li = includes.begin(); li != includes.end(); ++li)
|
||||
{
|
||||
std::string inc = *li;
|
||||
if (!cmSystemTools::IsOff(inc.c_str()))
|
||||
{
|
||||
cmSystemTools::ConvertToUnixSlashes(inc);
|
||||
}
|
||||
if(uniqueIncludes.insert(inc).second)
|
||||
{
|
||||
orderedAndUniqueIncludes.push_back(inc);
|
||||
}
|
||||
}
|
||||
|
||||
return orderedAndUniqueIncludes;
|
||||
return this->Target->GetIncludeDirectories(config);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -315,7 +277,7 @@ std::string cmGeneratorTarget::GetCompileDefinitions(const char *config)
|
|||
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
|
||||
this->GetName(),
|
||||
defPropName, 0, 0);
|
||||
return ge.Parse(prop).Evaluate(this->Makefile,
|
||||
return ge.Parse(prop)->Evaluate(this->Makefile,
|
||||
config,
|
||||
false,
|
||||
this->Target,
|
||||
|
|
|
@ -938,6 +938,11 @@ void cmGlobalGenerator::Generate()
|
|||
(*targets)[tit->first] = tit->second;
|
||||
(*targets)[tit->first].SetMakefile(mf);
|
||||
}
|
||||
|
||||
for ( tit = targets->begin(); tit != targets->end(); ++ tit )
|
||||
{
|
||||
tit->second.AppendBuildInterfaceIncludes();
|
||||
}
|
||||
}
|
||||
|
||||
// Add generator specific helper commands
|
||||
|
|
|
@ -1206,7 +1206,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
|
|||
|
||||
// If the language is compiled as a source trust Xcode to link with it.
|
||||
cmTarget::LinkImplementation const* impl =
|
||||
cmtarget.GetLinkImplementation("NOCONFIG");
|
||||
cmtarget.GetLinkImplementation("NOCONFIG", &cmtarget);
|
||||
for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
|
||||
li != impl->Languages.end(); ++li)
|
||||
{
|
||||
|
@ -1367,16 +1367,18 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// This function removes each occurence of the flag and returns the last one
|
||||
// This function removes each occurrence of the flag and returns the last one
|
||||
// (i.e., the dominant flag in GCC)
|
||||
std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
|
||||
std::string& flags)
|
||||
{
|
||||
std::string retFlag;
|
||||
std::string::size_type pos = flags.rfind(flag);
|
||||
std::string::size_type lastOccurancePos = flags.rfind(flag);
|
||||
bool saved = false;
|
||||
while(pos != flags.npos)
|
||||
while(lastOccurancePos != flags.npos)
|
||||
{
|
||||
//increment pos, we use lastOccurancePos to reduce search space on next inc
|
||||
std::string::size_type pos = lastOccurancePos;
|
||||
if(pos == 0 || flags[pos-1]==' ')
|
||||
{
|
||||
while(pos < flags.size() && flags[pos] != ' ')
|
||||
|
@ -1388,9 +1390,12 @@ std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
|
|||
flags[pos] = ' ';
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
saved = true;
|
||||
pos = flags.rfind(flag);
|
||||
}
|
||||
//decrement lastOccurancePos while making sure we don't loop around
|
||||
//and become a very large positive number since size_type is unsigned
|
||||
lastOccurancePos = lastOccurancePos == 0 ? 0 : lastOccurancePos-1;
|
||||
lastOccurancePos = flags.rfind(flag,lastOccurancePos);
|
||||
}
|
||||
return retFlag;
|
||||
}
|
||||
|
@ -1639,14 +1644,16 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||
if(strcmp(lang, "CXX") == 0)
|
||||
{
|
||||
this->CurrentLocalGenerator->AddLanguageFlags(cflags, "C", configName);
|
||||
this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target, "C");
|
||||
this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target,
|
||||
"C", configName);
|
||||
}
|
||||
|
||||
// Add language-specific flags.
|
||||
this->CurrentLocalGenerator->AddLanguageFlags(flags, lang, configName);
|
||||
|
||||
// Add shared-library flags if needed.
|
||||
this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target, lang);
|
||||
this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target,
|
||||
lang, configName);
|
||||
}
|
||||
else if(binary)
|
||||
{
|
||||
|
@ -1997,15 +2004,20 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||
dirs.Add(incpath.c_str());
|
||||
}
|
||||
}
|
||||
std::vector<std::string>& frameworks = target.GetFrameworks();
|
||||
if(frameworks.size())
|
||||
if(target.GetType() != cmTarget::OBJECT_LIBRARY &&
|
||||
target.GetType() != cmTarget::STATIC_LIBRARY)
|
||||
{
|
||||
for(std::vector<std::string>::iterator fmIt = frameworks.begin();
|
||||
fmIt != frameworks.end(); ++fmIt)
|
||||
// Add framework search paths needed for linking.
|
||||
if(cmComputeLinkInformation* cli = target.GetLinkInformation(configName))
|
||||
{
|
||||
if(emitted.insert(*fmIt).second)
|
||||
std::vector<std::string> const& fwDirs = cli->GetFrameworkPaths();
|
||||
for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
|
||||
fdi != fwDirs.end(); ++fdi)
|
||||
{
|
||||
fdirs.Add(this->XCodeEscapePath(fmIt->c_str()).c_str());
|
||||
if(emitted.insert(*fdi).second)
|
||||
{
|
||||
fdirs.Add(this->XCodeEscapePath(fdi->c_str()).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2691,25 +2703,6 @@ void cmGlobalXCodeGenerator
|
|||
linkDirs.c_str(), configName);
|
||||
}
|
||||
|
||||
// add the framework search paths
|
||||
{
|
||||
const char* sep = "";
|
||||
std::string fdirs;
|
||||
std::vector<std::string> const& fwDirs = cli.GetFrameworkPaths();
|
||||
for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
|
||||
fdi != fwDirs.end(); ++fdi)
|
||||
{
|
||||
fdirs += sep;
|
||||
sep = " ";
|
||||
fdirs += this->XCodeEscapePath(fdi->c_str());
|
||||
}
|
||||
if(!fdirs.empty())
|
||||
{
|
||||
this->AppendBuildSettingAttribute(target, "FRAMEWORK_SEARCH_PATHS",
|
||||
fdirs.c_str(), configName);
|
||||
}
|
||||
}
|
||||
|
||||
// now add the link libraries
|
||||
{
|
||||
std::string linkLibs;
|
||||
|
|
|
@ -224,10 +224,6 @@ cmLoadedCommand::~cmLoadedCommand()
|
|||
bool cmLoadCommandCommand
|
||||
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
|
||||
{
|
||||
this->Makefile->IssueMessage(
|
||||
cmake::AUTHOR_WARNING,
|
||||
"The \"load_command\" command will be removed in CMake 3.0. "
|
||||
"See command documentation for details.");
|
||||
if(args.size() < 1 )
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
*/
|
||||
virtual const char* GetTerseDocumentation() const
|
||||
{
|
||||
return "Deprecated. Use macro() or function() instead.";
|
||||
return "Load a command into a running CMake.";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,13 +56,6 @@ public:
|
|||
virtual const char* GetFullDocumentation() const
|
||||
{
|
||||
return
|
||||
"This command will be removed in CMake 3.0. "
|
||||
"It works only when the target architecture matches the "
|
||||
"running CMake binary. "
|
||||
"Use macro() or function() to add commands. "
|
||||
"Use execute_process() to run advanced computations "
|
||||
"in external processes."
|
||||
"\n"
|
||||
" load_command(COMMAND_NAME <loc1> [loc2 ...])\n"
|
||||
"The given locations are searched for a library whose name is "
|
||||
"cmCOMMAND_NAME. If found, it is loaded as a module and the command "
|
||||
|
@ -74,12 +67,6 @@ public:
|
|||
"Otherwise the variable will not be set.";
|
||||
}
|
||||
|
||||
/** This command is kept for compatibility with older CMake versions. */
|
||||
virtual bool IsDiscouraged() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
cmTypeMacro(cmLoadCommandCommand, cmCommand);
|
||||
};
|
||||
|
||||
|
|
|
@ -1329,7 +1329,9 @@ std::string cmLocalGenerator::GetIncludeFlags(
|
|||
void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
|
||||
cmGeneratorTarget* target,
|
||||
const char* lang,
|
||||
const char *config)
|
||||
const char *config,
|
||||
bool stripImplicitInclDirs
|
||||
)
|
||||
{
|
||||
// Need to decide whether to automatically include the source and
|
||||
// binary directories at the beginning of the include path.
|
||||
|
@ -1404,18 +1406,21 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
|
|||
return;
|
||||
}
|
||||
|
||||
// Load implicit include directories for this language.
|
||||
std::string impDirVar = "CMAKE_";
|
||||
impDirVar += lang;
|
||||
impDirVar += "_IMPLICIT_INCLUDE_DIRECTORIES";
|
||||
if(const char* value = this->Makefile->GetDefinition(impDirVar.c_str()))
|
||||
if (stripImplicitInclDirs)
|
||||
{
|
||||
std::vector<std::string> impDirVec;
|
||||
cmSystemTools::ExpandListArgument(value, impDirVec);
|
||||
for(std::vector<std::string>::const_iterator i = impDirVec.begin();
|
||||
i != impDirVec.end(); ++i)
|
||||
// Load implicit include directories for this language.
|
||||
std::string impDirVar = "CMAKE_";
|
||||
impDirVar += lang;
|
||||
impDirVar += "_IMPLICIT_INCLUDE_DIRECTORIES";
|
||||
if(const char* value = this->Makefile->GetDefinition(impDirVar.c_str()))
|
||||
{
|
||||
emitted.insert(*i);
|
||||
std::vector<std::string> impDirVec;
|
||||
cmSystemTools::ExpandListArgument(value, impDirVec);
|
||||
for(std::vector<std::string>::const_iterator i = impDirVec.begin();
|
||||
i != impDirVec.end(); ++i)
|
||||
{
|
||||
emitted.insert(*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1703,7 +1708,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
|
|||
for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
|
||||
fdi != fwDirs.end(); ++fdi)
|
||||
{
|
||||
frameworkPath = " -F";
|
||||
frameworkPath += "-F";
|
||||
frameworkPath += this->Convert(fdi->c_str(), NONE, SHELL, false);
|
||||
frameworkPath += " ";
|
||||
}
|
||||
|
@ -1979,7 +1984,8 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags,
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target,
|
||||
std::string const& lang)
|
||||
std::string const& lang,
|
||||
const char *config)
|
||||
{
|
||||
int targetType = target->GetType();
|
||||
|
||||
|
@ -1992,8 +1998,18 @@ void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target,
|
|||
}
|
||||
else
|
||||
{
|
||||
// Add position independendent flags, if needed.
|
||||
if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE"))
|
||||
if (target->GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE"))
|
||||
{
|
||||
this->AddPositionIndependentFlags(flags, lang, targetType);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (target->GetLinkInterfaceDependentBoolProperty(
|
||||
"POSITION_INDEPENDENT_CODE",
|
||||
config))
|
||||
{
|
||||
this->AddPositionIndependentFlags(flags, lang, targetType);
|
||||
}
|
||||
|
|
|
@ -142,7 +142,7 @@ public:
|
|||
void AddLanguageFlags(std::string& flags, const char* lang,
|
||||
const char* config);
|
||||
void AddCMP0018Flags(std::string &flags, cmTarget* target,
|
||||
std::string const& lang);
|
||||
std::string const& lang, const char *config);
|
||||
void AddConfigVariableFlags(std::string& flags, const char* var,
|
||||
const char* config);
|
||||
///! Append flags to a string.
|
||||
|
@ -212,7 +212,8 @@ public:
|
|||
/** Get the include flags for the current makefile and language. */
|
||||
void GetIncludeDirectories(std::vector<std::string>& dirs,
|
||||
cmGeneratorTarget* target,
|
||||
const char* lang = "C", const char *config = 0);
|
||||
const char* lang = "C", const char *config = 0,
|
||||
bool stripImplicitInclDirs = true);
|
||||
|
||||
/** Compute the language used to compile the given source file. */
|
||||
const char* GetSourceFileLanguage(const cmSourceFile& source);
|
||||
|
|
|
@ -814,7 +814,7 @@ bool cmMakefile::NeedBackwardsCompatibility(unsigned int major,
|
|||
void cmMakefile::FinalPass()
|
||||
{
|
||||
// do all the variable expansions here
|
||||
this->ExpandVariables();
|
||||
this->ExpandVariablesCMP0019();
|
||||
|
||||
// give all the commands a chance to do something
|
||||
// after the file has been parsed before generation
|
||||
|
@ -1485,9 +1485,12 @@ void cmMakefile::InitializeFromParent()
|
|||
// Initialize definitions with the closure of the parent scope.
|
||||
this->Internal->VarStack.top() = parent->Internal->VarStack.top().Closure();
|
||||
|
||||
// copy include paths
|
||||
this->SetProperty("INCLUDE_DIRECTORIES",
|
||||
parent->GetProperty("INCLUDE_DIRECTORIES"));
|
||||
const std::vector<IncludeDirectoriesEntry> parentIncludes =
|
||||
parent->GetIncludeDirectoriesEntries();
|
||||
this->IncludeDirectoriesEntries.insert(this->IncludeDirectoriesEntries.end(),
|
||||
parentIncludes.begin(),
|
||||
parentIncludes.end());
|
||||
|
||||
this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
|
||||
|
||||
// define flags
|
||||
|
@ -1612,41 +1615,6 @@ void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void AddStringToProperty(cmProperty *prop, const char* name, const char* s,
|
||||
bool before)
|
||||
{
|
||||
if (!prop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't worry about duplicates at this point. We eliminate them when
|
||||
// we convert the property to a vector in GetIncludeDirectories.
|
||||
|
||||
if (before)
|
||||
{
|
||||
const char *val = prop->GetValue();
|
||||
cmOStringStream oss;
|
||||
|
||||
if(val && *val)
|
||||
{
|
||||
oss << s << ";" << val;
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << s;
|
||||
}
|
||||
|
||||
std::string newVal = oss.str();
|
||||
prop->Set(name, newVal.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
prop->Append(name, s);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
|
||||
{
|
||||
|
@ -1655,18 +1623,21 @@ void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
|
|||
return;
|
||||
}
|
||||
|
||||
// Directory property:
|
||||
cmProperty *prop =
|
||||
this->GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES");
|
||||
AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before);
|
||||
std::vector<IncludeDirectoriesEntry>::iterator position =
|
||||
before ? this->IncludeDirectoriesEntries.begin()
|
||||
: this->IncludeDirectoriesEntries.end();
|
||||
|
||||
cmListFileBacktrace lfbt;
|
||||
this->GetBacktrace(lfbt);
|
||||
IncludeDirectoriesEntry entry(inc, lfbt);
|
||||
this->IncludeDirectoriesEntries.insert(position, entry);
|
||||
|
||||
// Property on each target:
|
||||
for (cmTargets::iterator l = this->Targets.begin();
|
||||
l != this->Targets.end(); ++l)
|
||||
{
|
||||
cmTarget &t = l->second;
|
||||
prop = t.GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES");
|
||||
AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before);
|
||||
t.InsertInclude(entry, before);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2122,21 +2093,33 @@ void cmMakefile::AddExtraDirectory(const char* dir)
|
|||
this->AuxSourceDirectories.push_back(dir);
|
||||
}
|
||||
|
||||
|
||||
// expand CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
|
||||
// include and library directories.
|
||||
|
||||
void cmMakefile::ExpandVariables()
|
||||
static bool mightExpandVariablesCMP0019(const char* s)
|
||||
{
|
||||
// Now expand variables in the include and link strings
|
||||
return s && *s && strstr(s,"${") && strchr(s,'}');
|
||||
}
|
||||
|
||||
void cmMakefile::ExpandVariablesCMP0019()
|
||||
{
|
||||
// Drop this ancient compatibility behavior with a policy.
|
||||
cmPolicies::PolicyStatus pol = this->GetPolicyStatus(cmPolicies::CMP0019);
|
||||
if(pol != cmPolicies::OLD && pol != cmPolicies::WARN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
cmOStringStream w;
|
||||
|
||||
// May not be necessary anymore... But may need a policy for strict
|
||||
// backwards compatibility
|
||||
const char *includeDirs = this->GetProperty("INCLUDE_DIRECTORIES");
|
||||
if (includeDirs)
|
||||
if(mightExpandVariablesCMP0019(includeDirs))
|
||||
{
|
||||
std::string dirs = includeDirs;
|
||||
this->ExpandVariablesInString(dirs, true, true);
|
||||
if(pol == cmPolicies::WARN && dirs != includeDirs)
|
||||
{
|
||||
w << "Evaluated directory INCLUDE_DIRECTORIES\n"
|
||||
<< " " << includeDirs << "\n"
|
||||
<< "as\n"
|
||||
<< " " << dirs << "\n";
|
||||
}
|
||||
this->SetProperty("INCLUDE_DIRECTORIES", dirs.c_str());
|
||||
}
|
||||
|
||||
|
@ -2146,10 +2129,17 @@ void cmMakefile::ExpandVariables()
|
|||
{
|
||||
cmTarget &t = l->second;
|
||||
includeDirs = t.GetProperty("INCLUDE_DIRECTORIES");
|
||||
if (includeDirs)
|
||||
if(mightExpandVariablesCMP0019(includeDirs))
|
||||
{
|
||||
std::string dirs = includeDirs;
|
||||
this->ExpandVariablesInString(dirs, true, true);
|
||||
if(pol == cmPolicies::WARN && dirs != includeDirs)
|
||||
{
|
||||
w << "Evaluated target " << t.GetName() << " INCLUDE_DIRECTORIES\n"
|
||||
<< " " << includeDirs << "\n"
|
||||
<< "as\n"
|
||||
<< " " << dirs << "\n";
|
||||
}
|
||||
t.SetProperty("INCLUDE_DIRECTORIES", dirs.c_str());
|
||||
}
|
||||
}
|
||||
|
@ -2157,13 +2147,45 @@ void cmMakefile::ExpandVariables()
|
|||
for(std::vector<std::string>::iterator d = this->LinkDirectories.begin();
|
||||
d != this->LinkDirectories.end(); ++d)
|
||||
{
|
||||
this->ExpandVariablesInString(*d, true, true);
|
||||
if(mightExpandVariablesCMP0019(d->c_str()))
|
||||
{
|
||||
std::string orig = *d;
|
||||
this->ExpandVariablesInString(*d, true, true);
|
||||
if(pol == cmPolicies::WARN && *d != orig)
|
||||
{
|
||||
w << "Evaluated link directory\n"
|
||||
<< " " << orig << "\n"
|
||||
<< "as\n"
|
||||
<< " " << *d << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
for(cmTarget::LinkLibraryVectorType::iterator l =
|
||||
this->LinkLibraries.begin();
|
||||
l != this->LinkLibraries.end(); ++l)
|
||||
{
|
||||
this->ExpandVariablesInString(l->first, true, true);
|
||||
if(mightExpandVariablesCMP0019(l->first.c_str()))
|
||||
{
|
||||
std::string orig = l->first;
|
||||
this->ExpandVariablesInString(l->first, true, true);
|
||||
if(pol == cmPolicies::WARN && l->first != orig)
|
||||
{
|
||||
w << "Evaluated link library\n"
|
||||
<< " " << orig << "\n"
|
||||
<< "as\n"
|
||||
<< " " << l->first << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!w.str().empty())
|
||||
{
|
||||
cmOStringStream m;
|
||||
m << this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0019)
|
||||
<< "\n"
|
||||
<< "The following variable evaluations were encountered:\n"
|
||||
<< w.str();
|
||||
this->IssueMessage(cmake::AUTHOR_WARNING, m.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3400,6 +3422,15 @@ void cmMakefile::SetProperty(const char* prop, const char* value)
|
|||
this->SetLinkDirectories(varArgsExpanded);
|
||||
return;
|
||||
}
|
||||
if (propname == "INCLUDE_DIRECTORIES")
|
||||
{
|
||||
this->IncludeDirectoriesEntries.clear();
|
||||
cmListFileBacktrace lfbt;
|
||||
this->GetBacktrace(lfbt);
|
||||
this->IncludeDirectoriesEntries.push_back(
|
||||
IncludeDirectoriesEntry(value, lfbt));
|
||||
return;
|
||||
}
|
||||
|
||||
if ( propname == "INCLUDE_REGULAR_EXPRESSION" )
|
||||
{
|
||||
|
@ -3431,6 +3462,14 @@ void cmMakefile::AppendProperty(const char* prop, const char* value,
|
|||
// handle special props
|
||||
std::string propname = prop;
|
||||
|
||||
if (propname == "INCLUDE_DIRECTORIES")
|
||||
{
|
||||
cmListFileBacktrace lfbt;
|
||||
this->GetBacktrace(lfbt);
|
||||
this->IncludeDirectoriesEntries.push_back(
|
||||
IncludeDirectoriesEntry(value, lfbt));
|
||||
return;
|
||||
}
|
||||
if ( propname == "LINK_DIRECTORIES" )
|
||||
{
|
||||
std::vector<std::string> varArgsExpanded;
|
||||
|
@ -3542,6 +3581,20 @@ const char *cmMakefile::GetProperty(const char* prop,
|
|||
output = str.str();
|
||||
return output.c_str();
|
||||
}
|
||||
else if (!strcmp("INCLUDE_DIRECTORIES",prop))
|
||||
{
|
||||
std::string sep;
|
||||
for (std::vector<IncludeDirectoriesEntry>::const_iterator
|
||||
it = this->IncludeDirectoriesEntries.begin(),
|
||||
end = this->IncludeDirectoriesEntries.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
output += sep;
|
||||
output += it->Value;
|
||||
sep = ";";
|
||||
}
|
||||
return output.c_str();
|
||||
}
|
||||
|
||||
bool chain = false;
|
||||
const char *retVal =
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "cmNewLineStyle.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmake.h"
|
||||
#include "cmMakefileIncludeDirectoriesEntry.h"
|
||||
|
||||
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
||||
#include "cmSourceGroup.h"
|
||||
|
@ -693,7 +694,7 @@ public:
|
|||
/**
|
||||
* Expand variables in the makefiles ivars such as link directories etc
|
||||
*/
|
||||
void ExpandVariables();
|
||||
void ExpandVariablesCMP0019();
|
||||
|
||||
/**
|
||||
* Replace variables and #cmakedefine lines in the given string.
|
||||
|
@ -861,6 +862,13 @@ public:
|
|||
/** Set whether or not to report a CMP0000 violation. */
|
||||
void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
|
||||
|
||||
typedef cmMakefileIncludeDirectoriesEntry IncludeDirectoriesEntry;
|
||||
|
||||
std::vector<IncludeDirectoriesEntry> GetIncludeDirectoriesEntries() const
|
||||
{
|
||||
return this->IncludeDirectoriesEntries;
|
||||
}
|
||||
|
||||
protected:
|
||||
// add link libraries and directories to the target
|
||||
void AddGlobalLinkInformation(const char* name, cmTarget& target);
|
||||
|
@ -909,6 +917,8 @@ protected:
|
|||
std::vector<std::string> HeaderFileExtensions;
|
||||
std::string DefineFlags;
|
||||
|
||||
std::vector<IncludeDirectoriesEntry> IncludeDirectoriesEntries;
|
||||
|
||||
// Track the value of the computed DEFINITIONS property.
|
||||
void AddDefineFlag(const char*, std::string&);
|
||||
void RemoveDefineFlag(const char*, std::string::size_type, std::string&);
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2012 Stephen Kelly <steveire@gmail.com>
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
|
||||
#ifndef cmMakefileIncludeDirectoriesEntry_h
|
||||
#define cmMakefileIncludeDirectoriesEntry_h
|
||||
|
||||
#include <string>
|
||||
#include "cmListFileCache.h"
|
||||
|
||||
struct cmMakefileIncludeDirectoriesEntry {
|
||||
cmMakefileIncludeDirectoriesEntry(const std::string &value,
|
||||
const cmListFileBacktrace &bt)
|
||||
: Value(value), Backtrace(bt)
|
||||
{}
|
||||
std::string Value;
|
||||
cmListFileBacktrace Backtrace;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -268,7 +268,8 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l)
|
|||
this->AddFortranFlags(flags);
|
||||
}
|
||||
|
||||
this->LocalGenerator->AddCMP0018Flags(flags, this->Target, lang);
|
||||
this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
|
||||
lang, this->ConfigName);
|
||||
|
||||
// Add include directory flags.
|
||||
this->AddIncludeFlags(flags, lang);
|
||||
|
@ -1550,10 +1551,10 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags()
|
|||
this->LocalGenerator->GetIncludeDirectories(includes,
|
||||
this->GeneratorTarget,
|
||||
"C", config);
|
||||
std::vector<std::string>::iterator i;
|
||||
// check all include directories for frameworks as this
|
||||
// will already have added a -F for the framework
|
||||
for(i = includes.begin(); i != includes.end(); ++i)
|
||||
for(std::vector<std::string>::iterator i = includes.begin();
|
||||
i != includes.end(); ++i)
|
||||
{
|
||||
if(this->Target->NameResolvesToFramework(i->c_str()))
|
||||
{
|
||||
|
@ -1565,17 +1566,21 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags()
|
|||
}
|
||||
|
||||
std::string flags;
|
||||
std::vector<std::string>& frameworks = this->Target->GetFrameworks();
|
||||
for(i = frameworks.begin();
|
||||
i != frameworks.end(); ++i)
|
||||
const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
|
||||
if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
|
||||
{
|
||||
if(emitted.insert(*i).second)
|
||||
std::vector<std::string> const& frameworks = cli->GetFrameworkPaths();
|
||||
for(std::vector<std::string>::const_iterator i = frameworks.begin();
|
||||
i != frameworks.end(); ++i)
|
||||
{
|
||||
flags += "-F";
|
||||
flags += this->Convert(i->c_str(),
|
||||
cmLocalGenerator::START_OUTPUT,
|
||||
cmLocalGenerator::SHELL, true);
|
||||
flags += " ";
|
||||
if(emitted.insert(*i).second)
|
||||
{
|
||||
flags += "-F";
|
||||
flags += this->Convert(i->c_str(),
|
||||
cmLocalGenerator::START_OUTPUT,
|
||||
cmLocalGenerator::SHELL, true);
|
||||
flags += " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
return flags;
|
||||
|
|
|
@ -147,7 +147,8 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source,
|
|||
|
||||
// Add shared-library flags if needed.
|
||||
this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
|
||||
language.c_str());
|
||||
language.c_str(),
|
||||
this->GetConfigName());
|
||||
|
||||
// Add include directory flags.
|
||||
{
|
||||
|
|
|
@ -491,6 +491,23 @@ cmPolicies::cmPolicies()
|
|||
"CMAKE_SHARED_LIBRARY_<Lang>_FLAGS whether it is modified or not and "
|
||||
"honor the POSITION_INDEPENDENT_CODE target property.",
|
||||
2,8,9,0, cmPolicies::WARN);
|
||||
|
||||
this->DefinePolicy(
|
||||
CMP0019, "CMP0019",
|
||||
"Do not re-expand variables in include and link information.",
|
||||
"CMake 2.8.10 and lower re-evaluated values given to the "
|
||||
"include_directories, link_directories, and link_libraries "
|
||||
"commands to expand any leftover variable references at the "
|
||||
"end of the configuration step. "
|
||||
"This was for strict compatibility with VERY early CMake versions "
|
||||
"because all variable references are now normally evaluated during "
|
||||
"CMake language processing. "
|
||||
"CMake 2.8.11 and higher prefer to skip the extra evaluation."
|
||||
"\n"
|
||||
"The OLD behavior for this policy is to re-evaluate the values "
|
||||
"for strict compatibility. "
|
||||
"The NEW behavior for this policy is to leave the values untouched.",
|
||||
2,8,11,0, cmPolicies::WARN);
|
||||
}
|
||||
|
||||
cmPolicies::~cmPolicies()
|
||||
|
|
|
@ -68,6 +68,7 @@ public:
|
|||
CMP0018, ///< Ignore language flags for shared libs, and adhere to
|
||||
/// POSITION_INDEPENDENT_CODE property and *_COMPILE_OPTIONS_PI{E,C}
|
||||
/// instead.
|
||||
CMP0019, ///< No variable re-expansion in include and link info
|
||||
|
||||
/** \brief Always the last entry.
|
||||
*
|
||||
|
|
|
@ -212,36 +212,11 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
|
|||
}
|
||||
|
||||
|
||||
const char* qtIncDir = 0;
|
||||
const char* qtCoreIncDir = 0;
|
||||
|
||||
// check whether ${QT_INCLUDE_DIR} is part of the implicit include dirs,
|
||||
// see http://public.kitware.com/Bug/view.php?id=13667
|
||||
bool qtIncludeDirMayHaveBeenRemoved = false;
|
||||
if (makefile->IsSet("QT_INCLUDE_DIR"))
|
||||
{
|
||||
qtIncDir = makefile->GetDefinition("QT_INCLUDE_DIR");
|
||||
std::string s =
|
||||
makefile->GetSafeDefinition("CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES");
|
||||
std::vector<std::string> implIncDirs;
|
||||
cmSystemTools::ExpandListArgument(s, implIncDirs);
|
||||
if (std::find(implIncDirs.begin(), implIncDirs.end(),std::string(qtIncDir))
|
||||
!= implIncDirs.end())
|
||||
{
|
||||
qtIncludeDirMayHaveBeenRemoved = true;
|
||||
if (makefile->IsSet("QT_QTCORE_INCLUDE_DIR"))
|
||||
{
|
||||
qtCoreIncDir = makefile->GetDefinition("QT_QTCORE_INCLUDE_DIR");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool haveQtCoreIncDir = false;
|
||||
bool haveQtIncDir = false;
|
||||
|
||||
std::vector<std::string> includeDirs;
|
||||
cmGeneratorTarget gtgt(target);
|
||||
localGen->GetIncludeDirectories(includeDirs, >gt, "CXX");
|
||||
// Get the include dirs for this target, without stripping the implicit
|
||||
// include dirs off, see http://public.kitware.com/Bug/view.php?id=13667
|
||||
localGen->GetIncludeDirectories(includeDirs, >gt, "CXX", 0, false);
|
||||
std::string _moc_incs = "";
|
||||
const char* sep = "";
|
||||
for(std::vector<std::string>::const_iterator incDirIt = includeDirs.begin();
|
||||
|
@ -251,37 +226,6 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
|
|||
_moc_incs += sep;
|
||||
sep = ";";
|
||||
_moc_incs += *incDirIt;
|
||||
|
||||
if (qtIncludeDirMayHaveBeenRemoved && qtCoreIncDir && qtIncDir) // #13667
|
||||
{
|
||||
if (*incDirIt == qtIncDir)
|
||||
{
|
||||
haveQtIncDir = true;
|
||||
qtIncludeDirMayHaveBeenRemoved = false; // it's here, i.e. not removed
|
||||
}
|
||||
if (*incDirIt == qtCoreIncDir)
|
||||
{
|
||||
haveQtCoreIncDir = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Some projects (kdelibs, phonon) query the compiler for its default
|
||||
// include search dirs, and add those to
|
||||
// CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES.
|
||||
// These may include e.g./usr/lib/qt/include . This is typically also part
|
||||
// of ${QT_INCLUDES}. If this directory is then contained in the implicit
|
||||
// include dirs, it is removed from the include dirs returned from the
|
||||
// target above. So we add ${QT_INCLUDE_DIR} manually for moc if we detected
|
||||
// that ${QT_QTCORE_INCLUDE_DIR} is among the include dirs (there shouldn't
|
||||
// be a way to use Qt4 without using ${QT_QTCORE_INCLUDE_DIR} I think.
|
||||
// See #13646 and #13667.
|
||||
if (qtIncludeDirMayHaveBeenRemoved && qtCoreIncDir && qtIncDir
|
||||
&& (haveQtCoreIncDir == true) && (haveQtIncDir == false))
|
||||
{
|
||||
_moc_incs += sep;
|
||||
sep = ";";
|
||||
_moc_incs += qtIncDir;
|
||||
}
|
||||
|
||||
const char* tmp = target->GetProperty("COMPILE_DEFINITIONS");
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <cmTimestamp.h>
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmStringCommand
|
||||
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
|
||||
|
@ -87,6 +89,10 @@ bool cmStringCommand
|
|||
{
|
||||
return this->HandleFindCommand(args);
|
||||
}
|
||||
else if(subCommand == "TIMESTAMP")
|
||||
{
|
||||
return this->HandleTimestampCommand(args);
|
||||
}
|
||||
|
||||
std::string e = "does not recognize sub-command "+subCommand;
|
||||
this->SetError(e.c_str());
|
||||
|
@ -879,3 +885,51 @@ bool cmStringCommand
|
|||
this->Makefile->AddDefinition(variableName.c_str(), &*result.begin());
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmStringCommand
|
||||
::HandleTimestampCommand(std::vector<std::string> const& args)
|
||||
{
|
||||
if(args.size() < 2)
|
||||
{
|
||||
this->SetError("sub-command TIMESTAMP requires at least one argument.");
|
||||
return false;
|
||||
}
|
||||
else if(args.size() > 4)
|
||||
{
|
||||
this->SetError("sub-command TIMESTAMP takes at most three arguments.");
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int argsIndex = 1;
|
||||
|
||||
const std::string &outputVariable = args[argsIndex++];
|
||||
|
||||
std::string formatString;
|
||||
if(args.size() > argsIndex && args[argsIndex] != "UTC")
|
||||
{
|
||||
formatString = args[argsIndex++];
|
||||
}
|
||||
|
||||
bool utcFlag = false;
|
||||
if(args.size() > argsIndex)
|
||||
{
|
||||
if(args[argsIndex] == "UTC")
|
||||
{
|
||||
utcFlag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string e = " TIMESTAMP sub-command does not recognize option " +
|
||||
args[argsIndex] + ".";
|
||||
this->SetError(e.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cmTimestamp timestamp;
|
||||
std::string result = timestamp.CurrentTime(formatString, utcFlag);
|
||||
this->Makefile->AddDefinition(outputVariable.c_str(), result.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ public:
|
|||
" string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]\n"
|
||||
" [RANDOM_SEED <seed>] <output variable>)\n"
|
||||
" string(FIND <string> <substring> <output variable> [REVERSE])\n"
|
||||
" string(TIMESTAMP <output variable> [<format string>] [UTC])\n"
|
||||
"REGEX MATCH will match the regular expression once and store the "
|
||||
"match in the output variable.\n"
|
||||
"REGEX MATCHALL will match the regular expression as many times as "
|
||||
|
@ -142,7 +143,33 @@ public:
|
|||
" () Saves a matched subexpression, which can be referenced \n"
|
||||
" in the REGEX REPLACE operation. Additionally it is saved\n"
|
||||
" by all regular expression-related commands, including \n"
|
||||
" e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9).";
|
||||
" e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9).\n"
|
||||
"TIMESTAMP will write a string representation of "
|
||||
"the current date and/or time to the output variable.\n"
|
||||
"Should the command be unable to obtain a timestamp "
|
||||
"the output variable will be set to the empty string \"\".\n"
|
||||
"The optional UTC flag requests the current date/time "
|
||||
"representation to be in Coordinated Universal Time (UTC) "
|
||||
"rather than local time.\n"
|
||||
"The optional <format string> may contain the following "
|
||||
"format specifiers: \n"
|
||||
" %d The day of the current month (01-31).\n"
|
||||
" %H The hour on a 24-hour clock (00-23).\n"
|
||||
" %I The hour on a 12-hour clock (01-12).\n"
|
||||
" %j The day of the current year (001-366).\n"
|
||||
" %m The month of the current year (01-12).\n"
|
||||
" %M The minute of the current hour (00-59).\n"
|
||||
" %S The second of the current minute.\n"
|
||||
" 60 represents a leap second. (00-60)\n"
|
||||
" %U The week number of the current year (00-53).\n"
|
||||
" %w The day of the current week. 0 is Sunday. (0-6)\n"
|
||||
" %y The last two digits of the current year (00-99)\n"
|
||||
" %Y The current year. \n"
|
||||
"Unknown format specifiers will be ignored "
|
||||
"and copied to the output as-is.\n"
|
||||
"If no explicit <format string> is given it will default to:\n"
|
||||
" %Y-%m-%dT%H:%M:%S for local time.\n"
|
||||
" %Y-%m-%dT%H:%M:%SZ for UTC.";
|
||||
}
|
||||
|
||||
cmTypeMacro(cmStringCommand, cmCommand);
|
||||
|
@ -165,6 +192,7 @@ protected:
|
|||
bool HandleStripCommand(std::vector<std::string> const& args);
|
||||
bool HandleRandomCommand(std::vector<std::string> const& args);
|
||||
bool HandleFindCommand(std::vector<std::string> const& args);
|
||||
bool HandleTimestampCommand(std::vector<std::string> const& args);
|
||||
|
||||
class RegexReplacement
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,6 +15,7 @@
|
|||
#include "cmCustomCommand.h"
|
||||
#include "cmPropertyMap.h"
|
||||
#include "cmPolicies.h"
|
||||
#include "cmMakefileIncludeDirectoriesEntry.h"
|
||||
|
||||
#include <cmsys/auto_ptr.hxx>
|
||||
|
||||
|
@ -24,11 +25,13 @@ class cmSourceFile;
|
|||
class cmGlobalGenerator;
|
||||
class cmComputeLinkInformation;
|
||||
class cmListFileBacktrace;
|
||||
class cmTarget;
|
||||
|
||||
struct cmTargetLinkInformationMap:
|
||||
public std::map<cmStdString, cmComputeLinkInformation*>
|
||||
public std::map<std::pair<cmTarget*, std::string>, cmComputeLinkInformation*>
|
||||
{
|
||||
typedef std::map<cmStdString, cmComputeLinkInformation*> derived;
|
||||
typedef std::map<std::pair<cmTarget*, std::string>,
|
||||
cmComputeLinkInformation*> derived;
|
||||
cmTargetLinkInformationMap() {}
|
||||
cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r);
|
||||
~cmTargetLinkInformationMap();
|
||||
|
@ -109,9 +112,6 @@ public:
|
|||
std::vector<cmCustomCommand> &GetPostBuildCommands()
|
||||
{return this->PostBuildCommands;}
|
||||
|
||||
///! Return the list of frameworks being linked to this target
|
||||
std::vector<std::string> &GetFrameworks() {return this->Frameworks;}
|
||||
|
||||
/**
|
||||
* Get the list of the source files used by this target
|
||||
*/
|
||||
|
@ -168,6 +168,9 @@ public:
|
|||
return this->LinkLibraries;}
|
||||
const LinkLibraryVectorType &GetOriginalLinkLibraries() const
|
||||
{return this->OriginalLinkLibraries;}
|
||||
void GetDirectLinkLibraries(const char *config,
|
||||
std::vector<std::string> &,
|
||||
cmTarget *head);
|
||||
|
||||
/** Compute the link type to use for the given configuration. */
|
||||
LinkLibraryType ComputeLinkType(const char* config);
|
||||
|
@ -179,7 +182,6 @@ public:
|
|||
|
||||
// Check to see if a library is a framework and treat it different on Mac
|
||||
bool NameResolvesToFramework(const std::string& libname);
|
||||
bool AddFramework(const std::string& lib, LinkLibraryType llt);
|
||||
void AddLinkLibrary(cmMakefile& mf,
|
||||
const char *target, const char* lib,
|
||||
LinkLibraryType llt);
|
||||
|
@ -256,12 +258,15 @@ public:
|
|||
// Needed only for OLD behavior of CMP0003.
|
||||
std::vector<std::string> WrongConfigLibraries;
|
||||
|
||||
LinkInterface(): Multiplicity(0) {}
|
||||
bool ImplementationIsInterface;
|
||||
|
||||
LinkInterface(): Multiplicity(0), ImplementationIsInterface(false) {}
|
||||
};
|
||||
|
||||
/** Get the link interface for the given configuration. Returns 0
|
||||
if the target cannot be linked. */
|
||||
LinkInterface const* GetLinkInterface(const char* config);
|
||||
LinkInterface const* GetLinkInterface(const char* config,
|
||||
cmTarget *headTarget);
|
||||
|
||||
/** The link implementation specifies the direct library
|
||||
dependencies needed by the object files of the target. */
|
||||
|
@ -277,7 +282,8 @@ public:
|
|||
// Needed only for OLD behavior of CMP0003.
|
||||
std::vector<std::string> WrongConfigLibraries;
|
||||
};
|
||||
LinkImplementation const* GetLinkImplementation(const char* config);
|
||||
LinkImplementation const* GetLinkImplementation(const char* config,
|
||||
cmTarget *head);
|
||||
|
||||
/** Link information from the transitive closure of the link
|
||||
implementation and the interfaces of its dependencies. */
|
||||
|
@ -289,7 +295,7 @@ public:
|
|||
// Languages whose runtime libraries must be linked.
|
||||
std::vector<std::string> Languages;
|
||||
};
|
||||
LinkClosure const* GetLinkClosure(const char* config);
|
||||
LinkClosure const* GetLinkClosure(const char* config, cmTarget *head);
|
||||
|
||||
/** Strip off leading and trailing whitespace from an item named in
|
||||
the link dependencies of this target. */
|
||||
|
@ -334,7 +340,7 @@ public:
|
|||
bool FindSourceFiles();
|
||||
|
||||
///! Return the preferred linker language for this target
|
||||
const char* GetLinkerLanguage(const char* config = 0);
|
||||
const char* GetLinkerLanguage(const char* config = 0, cmTarget *head = 0);
|
||||
|
||||
/** Get the full name of the target according to the settings in its
|
||||
makefile. */
|
||||
|
@ -402,11 +408,17 @@ public:
|
|||
std::string GetInstallNameDirForInstallTree(const char* config,
|
||||
bool for_xcode = false);
|
||||
|
||||
cmComputeLinkInformation* GetLinkInformation(const char* config);
|
||||
cmComputeLinkInformation* GetLinkInformation(const char* config,
|
||||
cmTarget *head = 0);
|
||||
|
||||
// Get the properties
|
||||
cmPropertyMap &GetProperties() { return this->Properties; };
|
||||
|
||||
bool GetMappedConfig(std::string const& desired_config,
|
||||
const char** loc,
|
||||
const char** imp,
|
||||
std::string& suffix);
|
||||
|
||||
// Define the properties
|
||||
static void DefineProperties(cmake *cm);
|
||||
|
||||
|
@ -474,6 +486,21 @@ public:
|
|||
/** @return the Mac framework directory without the base. */
|
||||
std::string GetFrameworkDirectory(const char* config = 0);
|
||||
|
||||
std::vector<std::string> GetIncludeDirectories(const char *config);
|
||||
void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
|
||||
bool before = false);
|
||||
|
||||
void AppendBuildInterfaceIncludes();
|
||||
|
||||
void GetLinkDependentTargetsForProperty(const std::string &p,
|
||||
std::set<std::string> &targets);
|
||||
bool IsNullImpliedByLinkLibraries(const std::string &p);
|
||||
|
||||
void AddLinkDependentTargetsForProperties(
|
||||
const std::map<cmStdString, cmStdString> &map);
|
||||
|
||||
bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||
const char *config);
|
||||
private:
|
||||
/**
|
||||
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
||||
|
@ -569,7 +596,6 @@ private:
|
|||
LinkLibraryVectorType LinkLibraries;
|
||||
LinkLibraryVectorType PrevLinkedLibraries;
|
||||
bool LinkLibrariesAnalyzed;
|
||||
std::vector<std::string> Frameworks;
|
||||
std::vector<std::string> LinkDirectories;
|
||||
std::set<cmStdString> LinkDirectoriesEmmitted;
|
||||
bool HaveInstallRule;
|
||||
|
@ -584,6 +610,10 @@ private:
|
|||
bool DLLPlatform;
|
||||
bool IsApple;
|
||||
bool IsImportedTarget;
|
||||
mutable std::map<cmStdString, std::set<std::string> >
|
||||
LinkDependentProperties;
|
||||
mutable std::set<std::string> LinkImplicitNullProperties;
|
||||
bool BuildInterfaceIncludesAppended;
|
||||
|
||||
// Cache target output paths for each configuration.
|
||||
struct OutputInfo;
|
||||
|
@ -593,16 +623,21 @@ private:
|
|||
|
||||
// Cache import information from properties for each configuration.
|
||||
struct ImportInfo;
|
||||
ImportInfo const* GetImportInfo(const char* config);
|
||||
void ComputeImportInfo(std::string const& desired_config, ImportInfo& info);
|
||||
ImportInfo const* GetImportInfo(const char* config,
|
||||
cmTarget *workingTarget);
|
||||
void ComputeImportInfo(std::string const& desired_config, ImportInfo& info,
|
||||
cmTarget *head);
|
||||
|
||||
cmTargetLinkInformationMap LinkInformation;
|
||||
void CheckPropertyCompatibility(cmComputeLinkInformation *info,
|
||||
const char* config);
|
||||
|
||||
bool ComputeLinkInterface(const char* config, LinkInterface& iface);
|
||||
bool ComputeLinkInterface(const char* config, LinkInterface& iface,
|
||||
cmTarget *head);
|
||||
|
||||
void ComputeLinkImplementation(const char* config,
|
||||
LinkImplementation& impl);
|
||||
void ComputeLinkClosure(const char* config, LinkClosure& lc);
|
||||
LinkImplementation& impl, cmTarget *head);
|
||||
void ComputeLinkClosure(const char* config, LinkClosure& lc, cmTarget *head);
|
||||
|
||||
void ClearLinkMaps();
|
||||
|
||||
|
@ -610,6 +645,9 @@ 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;
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2013 Stephen Kelly <steveire@gmail.com>
|
||||
|
||||
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.
|
||||
============================================================================*/
|
||||
#include "cmTargetCompileDefinitionsCommand.h"
|
||||
|
||||
#include "cmMakefileIncludeDirectoriesEntry.h"
|
||||
|
||||
bool cmTargetCompileDefinitionsCommand
|
||||
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
|
||||
{
|
||||
return this->HandleArguments(args, "COMPILE_DEFINITIONS");
|
||||
}
|
||||
|
||||
void cmTargetCompileDefinitionsCommand
|
||||
::HandleImportedTargetInvalidScope(const std::string &scope,
|
||||
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.";
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
}
|
||||
|
||||
void cmTargetCompileDefinitionsCommand
|
||||
::HandleMissingTarget(const std::string &name)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Cannot specify compile definitions for target \"" << name << "\" "
|
||||
"which is not built by this project.";
|
||||
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 &)
|
||||
{
|
||||
content += sep + entry;
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmTargetCompileDefinitionsCommand
|
||||
::HandleDirectContent(cmTarget *tgt, const std::string &content,
|
||||
bool)
|
||||
{
|
||||
tgt->AppendProperty("COMPILE_DEFINITIONS", content.c_str());
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2013 Stephen Kelly <steveire@gmail.com>
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
|
||||
#ifndef cmTargetCompileDefinitionsCommand_h
|
||||
#define cmTargetCompileDefinitionsCommand_h
|
||||
|
||||
#include "cmTargetPropCommandBase.h"
|
||||
|
||||
class cmTargetCompileDefinitionsCommand : public cmTargetPropCommandBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is a virtual constructor for the command.
|
||||
*/
|
||||
virtual cmCommand* Clone()
|
||||
{
|
||||
return new cmTargetCompileDefinitionsCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when the command is first encountered in
|
||||
* the CMakeLists.txt file.
|
||||
*/
|
||||
virtual bool InitialPass(std::vector<std::string> const& args,
|
||||
cmExecutionStatus &status);
|
||||
|
||||
/**
|
||||
* The name of the command as specified in CMakeList.txt.
|
||||
*/
|
||||
virtual const char* GetName() const { return "target_compile_definitions";}
|
||||
|
||||
/**
|
||||
* Succinct documentation.
|
||||
*/
|
||||
virtual const char* GetTerseDocumentation() const
|
||||
{
|
||||
return
|
||||
"Add compile definitions to a target.";
|
||||
}
|
||||
|
||||
/**
|
||||
* More documentation.
|
||||
*/
|
||||
virtual const char* GetFullDocumentation() const
|
||||
{
|
||||
return
|
||||
" target_compile_definitions(<target> "
|
||||
"<INTERFACE|PUBLIC|PRIVATE> [items1...]\n"
|
||||
" [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])\n"
|
||||
"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. "
|
||||
"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 "
|
||||
"INTERFACE items will populate the INTERFACE_COMPILE_DEFINITIONS "
|
||||
"property of <target>. "
|
||||
"The non-scope arguments specify compile definitions or targets to use "
|
||||
"INTERFACE_COMPILE_DEFINITIONS from. "
|
||||
"Repeated calls for the same <target> append items in the order called."
|
||||
"\n"
|
||||
"Arguments to target_compile_definitions may use \"generator "
|
||||
"expressions\" with the syntax \"$<...>\". "
|
||||
CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
|
||||
;
|
||||
}
|
||||
|
||||
cmTypeMacro(cmTargetCompileDefinitionsCommand, cmCommand);
|
||||
|
||||
private:
|
||||
virtual void HandleImportedTargetInvalidScope(const std::string &scope,
|
||||
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,
|
||||
bool prepend);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,74 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2013 Stephen Kelly <steveire@gmail.com>
|
||||
|
||||
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.
|
||||
============================================================================*/
|
||||
#include "cmTargetIncludeDirectoriesCommand.h"
|
||||
|
||||
#include "cmMakefileIncludeDirectoriesEntry.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTargetIncludeDirectoriesCommand
|
||||
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
|
||||
{
|
||||
return this->HandleArguments(args, "INCLUDE_DIRECTORIES", PROCESS_BEFORE);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTargetIncludeDirectoriesCommand
|
||||
::HandleImportedTargetInvalidScope(const std::string &tgt,
|
||||
const std::string &scope)
|
||||
{
|
||||
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.";
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTargetIncludeDirectoriesCommand
|
||||
::HandleMissingTarget(const std::string &name)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Cannot specify include directories for target \"" << name << "\" "
|
||||
"which is not built by this project.";
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTargetIncludeDirectoriesCommand
|
||||
::HandleNonTargetArg(std::string &content,
|
||||
const std::string &sep,
|
||||
const std::string &entry,
|
||||
const std::string &tgt)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
content += sep + entry;
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTargetIncludeDirectoriesCommand
|
||||
::HandleDirectContent(cmTarget *tgt, const std::string &content,
|
||||
bool prepend)
|
||||
{
|
||||
cmListFileBacktrace lfbt;
|
||||
this->Makefile->GetBacktrace(lfbt);
|
||||
cmMakefileIncludeDirectoriesEntry entry(content, lfbt);
|
||||
tgt->InsertInclude(entry, prepend);
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2013 Stephen Kelly <steveire@gmail.com>
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
|
||||
#ifndef cmTargetIncludeDirectoriesCommand_h
|
||||
#define cmTargetIncludeDirectoriesCommand_h
|
||||
|
||||
#include "cmTargetPropCommandBase.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class cmTargetIncludeDirectoriesCommand : public cmTargetPropCommandBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is a virtual constructor for the command.
|
||||
*/
|
||||
virtual cmCommand* Clone()
|
||||
{
|
||||
return new cmTargetIncludeDirectoriesCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when the command is first encountered in
|
||||
* the CMakeLists.txt file.
|
||||
*/
|
||||
virtual bool InitialPass(std::vector<std::string> const& args,
|
||||
cmExecutionStatus &status);
|
||||
|
||||
/**
|
||||
* The name of the command as specified in CMakeList.txt.
|
||||
*/
|
||||
virtual const char* GetName() const { return "target_include_directories";}
|
||||
|
||||
/**
|
||||
* Succinct documentation.
|
||||
*/
|
||||
virtual const char* GetTerseDocumentation() const
|
||||
{
|
||||
return
|
||||
"Add include directories to a target.";
|
||||
}
|
||||
|
||||
/**
|
||||
* More documentation.
|
||||
*/
|
||||
virtual const char* GetFullDocumentation() const
|
||||
{
|
||||
return
|
||||
" target_include_directories(<target> [BEFORE] "
|
||||
"<INTERFACE|PUBLIC|PRIVATE> [items1...]\n"
|
||||
" [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])\n"
|
||||
"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"
|
||||
"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 "
|
||||
"the scope of the following arguments. PRIVATE and PUBLIC items will "
|
||||
"populate the INCLUDE_DIRECTORIES property of <target>. PUBLIC and "
|
||||
"INTERFACE items will populate the INTERFACE_INCLUDE_DIRECTORIES "
|
||||
"property of <target>. "
|
||||
"The non-scope arguments specify either include directories or targets "
|
||||
"to use INTERFACE_INCLUDE_DIRECTORIES from. Any specified include "
|
||||
"directories must be absolute paths, not relative paths. "
|
||||
"Repeated calls for the same <target> append items in the order called."
|
||||
"\n"
|
||||
"Arguments to target_include_directories may use \"generator "
|
||||
"expressions\" with the syntax \"$<...>\". "
|
||||
CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
|
||||
;
|
||||
}
|
||||
|
||||
cmTypeMacro(cmTargetIncludeDirectoriesCommand, cmCommand);
|
||||
|
||||
private:
|
||||
virtual void HandleImportedTargetInvalidScope(const std::string &tgt,
|
||||
const std::string &scope);
|
||||
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,
|
||||
bool prepend);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -33,6 +33,10 @@ 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
|
||||
|
@ -257,6 +261,16 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
|
|||
// 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)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#define cmTargetLinkLibrariesCommand_h
|
||||
|
||||
#include "cmCommand.h"
|
||||
#include "cmDocumentGeneratorExpressions.h"
|
||||
|
||||
/** \class cmTargetLinkLibrariesCommand
|
||||
* \brief Specify a list of libraries to link into executables.
|
||||
|
@ -141,6 +142,12 @@ public:
|
|||
"However, if two archives are really so interdependent they should "
|
||||
"probably be combined into a single archive."
|
||||
")"
|
||||
"\n"
|
||||
"Arguments to target_link_libraries may use \"generator expressions\" "
|
||||
"with the syntax \"$<...>\". Note however, that generator expressions "
|
||||
"will not be used in OLD handling of CMP0003 or CMP0004."
|
||||
"\n"
|
||||
CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2013 Stephen Kelly <steveire@gmail.com>
|
||||
|
||||
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.
|
||||
============================================================================*/
|
||||
|
||||
#include "cmTargetPropCommandBase.h"
|
||||
|
||||
#include "cmGlobalGenerator.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTargetPropCommandBase
|
||||
::HandleArguments(std::vector<std::string> const& args, const char *prop,
|
||||
ArgumentFlags flags)
|
||||
{
|
||||
if(args.size() < 3)
|
||||
{
|
||||
this->SetError("called with incorrect number of arguments");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lookup the target for which libraries are specified.
|
||||
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)
|
||||
{
|
||||
this->HandleMissingTarget(args[0]);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int argIndex = 1;
|
||||
|
||||
bool prepend = false;
|
||||
if ((flags & PROCESS_BEFORE) && args[argIndex] == "BEFORE")
|
||||
{
|
||||
if (args.size() < 4)
|
||||
{
|
||||
this->SetError("called with incorrect number of arguments");
|
||||
return false;
|
||||
}
|
||||
prepend = true;
|
||||
++argIndex;
|
||||
}
|
||||
|
||||
this->Property = prop;
|
||||
|
||||
while (argIndex < args.size())
|
||||
{
|
||||
if (!this->ProcessContentArgs(args, argIndex, prepend))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmTargetPropCommandBase
|
||||
::ProcessContentArgs(std::vector<std::string> const& args,
|
||||
unsigned int &argIndex, bool prepend)
|
||||
{
|
||||
const std::string scope = args[argIndex];
|
||||
|
||||
if(scope != "PUBLIC"
|
||||
&& scope != "PRIVATE"
|
||||
&& scope != "INTERFACE" )
|
||||
{
|
||||
this->SetError("called with invalid arguments");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(this->Target->IsImported() && scope != "INTERFACE")
|
||||
{
|
||||
this->HandleImportedTargetInvalidScope(args[0], scope);
|
||||
return false;
|
||||
}
|
||||
|
||||
++argIndex;
|
||||
|
||||
std::string content;
|
||||
|
||||
std::string sep;
|
||||
for(unsigned int i=argIndex; i < args.size(); ++i, ++argIndex)
|
||||
{
|
||||
if(args[i] == "PUBLIC"
|
||||
|| args[i] == "PRIVATE"
|
||||
|| args[i] == "INTERFACE" )
|
||||
{
|
||||
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 = ";";
|
||||
}
|
||||
this->PopulateTargetProperies(scope, content, prepend);
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTargetPropCommandBase
|
||||
::PopulateTargetProperies(const std::string &scope,
|
||||
const std::string &content, bool prepend)
|
||||
{
|
||||
if (scope == "PRIVATE" || scope == "PUBLIC")
|
||||
{
|
||||
this->HandleDirectContent(this->Target, content, prepend);
|
||||
}
|
||||
if (scope == "INTERFACE" || scope == "PUBLIC")
|
||||
{
|
||||
if (prepend)
|
||||
{
|
||||
const std::string propName = std::string("INTERFACE_") + this->Property;
|
||||
const char *propValue = this->Target->GetProperty(propName.c_str());
|
||||
const std::string totalContent = content + (propValue
|
||||
? std::string(";") + propValue
|
||||
: std::string());
|
||||
this->Target->SetProperty(propName.c_str(), totalContent.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
this->Target->AppendProperty(("INTERFACE_" + this->Property).c_str(),
|
||||
content.c_str());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2013 Stephen Kelly <steveire@gmail.com>
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
|
||||
#ifndef cmTargetPropCommandBase_h
|
||||
#define cmTargetPropCommandBase_h
|
||||
|
||||
#include "cmCommand.h"
|
||||
#include "cmDocumentGeneratorExpressions.h"
|
||||
|
||||
class cmTarget;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class cmTargetPropCommandBase : public cmCommand
|
||||
{
|
||||
public:
|
||||
|
||||
enum ArgumentFlags {
|
||||
NO_FLAGS = 0,
|
||||
PROCESS_BEFORE = 1
|
||||
};
|
||||
|
||||
bool HandleArguments(std::vector<std::string> const& args,
|
||||
const char *prop, ArgumentFlags flags = NO_FLAGS);
|
||||
|
||||
private:
|
||||
virtual void HandleImportedTargetInvalidScope(const std::string &tgt,
|
||||
const std::string &scope) = 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,
|
||||
bool prepend) = 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;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -112,7 +112,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
|
|||
else
|
||||
{
|
||||
// Use the command name given.
|
||||
exe = ge.Parse(exe.c_str()).Evaluate(mf, config);
|
||||
exe = ge.Parse(exe.c_str())->Evaluate(mf, config);
|
||||
cmSystemTools::ConvertToUnixSlashes(exe);
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
|
|||
for(std::vector<std::string>::const_iterator ci = command.begin()+1;
|
||||
ci != command.end(); ++ci)
|
||||
{
|
||||
os << " " << lg->EscapeForCMake(ge.Parse(*ci).Evaluate(mf, config));
|
||||
os << " " << lg->EscapeForCMake(ge.Parse(*ci)->Evaluate(mf, config));
|
||||
}
|
||||
|
||||
// Finish the test command.
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2012 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
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.
|
||||
============================================================================*/
|
||||
#include "cmTimestamp.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmTimestamp::CurrentTime(
|
||||
const std::string& formatString, bool utcFlag)
|
||||
{
|
||||
time_t currentTimeT = time(0);
|
||||
if(currentTimeT == time_t(-1))
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return CreateTimestampFromTimeT(currentTimeT, formatString, utcFlag);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmTimestamp::FileModificationTime(const char* path,
|
||||
const std::string& formatString, bool utcFlag)
|
||||
{
|
||||
struct stat info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
if(stat(path, &info) != 0)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return CreateTimestampFromTimeT(info.st_mtime, formatString, utcFlag);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT,
|
||||
std::string formatString, bool utcFlag)
|
||||
{
|
||||
if(formatString.empty())
|
||||
{
|
||||
formatString = "%Y-%m-%dT%H:%M:%S";
|
||||
if(utcFlag)
|
||||
{
|
||||
formatString += "Z";
|
||||
}
|
||||
}
|
||||
|
||||
struct tm timeStruct;
|
||||
memset(&timeStruct, 0, sizeof(timeStruct));
|
||||
|
||||
struct tm* ptr = (struct tm*) 0;
|
||||
if(utcFlag)
|
||||
{
|
||||
ptr = gmtime(&timeT);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = localtime(&timeT);
|
||||
}
|
||||
|
||||
if(ptr == 0)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
timeStruct = *ptr;
|
||||
|
||||
std::string result;
|
||||
for(std::string::size_type i = 0; i < formatString.size(); ++i)
|
||||
{
|
||||
char c1 = formatString[i];
|
||||
char c2 = (i+1 < formatString.size()) ?
|
||||
formatString[i+1] : static_cast<char>(0);
|
||||
|
||||
if(c1 == '%' && c2 != 0)
|
||||
{
|
||||
result += AddTimestampComponent(c2, timeStruct);
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += c1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmTimestamp::AddTimestampComponent(
|
||||
char flag, struct tm& timeStruct)
|
||||
{
|
||||
std::string formatString = "%";
|
||||
formatString += flag;
|
||||
|
||||
switch(flag)
|
||||
{
|
||||
case 'd':
|
||||
case 'H':
|
||||
case 'I':
|
||||
case 'j':
|
||||
case 'm':
|
||||
case 'M':
|
||||
case 'S':
|
||||
case 'U':
|
||||
case 'w':
|
||||
case 'y':
|
||||
case 'Y':
|
||||
break;
|
||||
default:
|
||||
{
|
||||
return formatString;
|
||||
}
|
||||
}
|
||||
|
||||
char buffer[16];
|
||||
|
||||
size_t size = strftime(buffer, sizeof(buffer),
|
||||
formatString.c_str(), &timeStruct);
|
||||
|
||||
return std::string(buffer, size);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2012 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
#ifndef cmTimestamp_h
|
||||
#define cmTimestamp_h
|
||||
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
|
||||
/** \class cmTimestamp
|
||||
* \brief Utility class to generate sting representation of a timestamp
|
||||
*
|
||||
*/
|
||||
class cmTimestamp
|
||||
{
|
||||
public:
|
||||
cmTimestamp() {}
|
||||
|
||||
std::string CurrentTime(const std::string& formatString, bool utcFlag);
|
||||
|
||||
std::string FileModificationTime(const char* path,
|
||||
const std::string& formatString, bool utcFlag);
|
||||
|
||||
private:
|
||||
std::string CreateTimestampFromTimeT(time_t timeT,
|
||||
std::string formatString, bool utcFlag);
|
||||
|
||||
std::string AddTimestampComponent(char flag, struct tm& timeStruct);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -572,6 +572,12 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
|
|||
sep = ";";
|
||||
}
|
||||
(*this->BuildFileStream ) << "</Outputs>\n";
|
||||
if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10)
|
||||
{
|
||||
// VS >= 11 let us turn off linking of custom command outputs.
|
||||
this->WritePlatformConfigTag("LinkObjects", i->c_str(), 3);
|
||||
(*this->BuildFileStream ) << "false</LinkObjects>\n";
|
||||
}
|
||||
}
|
||||
this->WriteString("</CustomBuild>\n", 2);
|
||||
}
|
||||
|
@ -879,14 +885,23 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
|
|||
}
|
||||
}
|
||||
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = this->GeneratorTarget->ExternalObjects.begin();
|
||||
si != this->GeneratorTarget->ExternalObjects.end(); ++si)
|
||||
if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10)
|
||||
{
|
||||
// For VS >= 11 we use LinkObjects to avoid linking custom command
|
||||
// outputs. Use Object for all external objects, generated or not.
|
||||
this->WriteSources("Object", this->GeneratorTarget->ExternalObjects);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If an object file is generated in this target, then vs10 will use
|
||||
// it in the build, and we have to list it as None instead of Object.
|
||||
std::vector<cmSourceFile*> const* d = this->Target->GetSourceDepends(*si);
|
||||
this->WriteSource((d && !d->empty())? "None":"Object", *si);
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = this->GeneratorTarget->ExternalObjects.begin();
|
||||
si != this->GeneratorTarget->ExternalObjects.end(); ++si)
|
||||
{
|
||||
std::vector<cmSourceFile*> const* d=this->Target->GetSourceDepends(*si);
|
||||
this->WriteSource((d && !d->empty())? "None":"Object", *si);
|
||||
}
|
||||
}
|
||||
|
||||
this->WriteSources("None", this->GeneratorTarget->ExtraSources);
|
||||
|
|
|
@ -953,7 +953,7 @@ int cmake::AddCMakePaths()
|
|||
cMakeSelf = cmSystemTools::GetRealPath(cMakeSelf.c_str());
|
||||
cMakeSelf += "/cmake";
|
||||
cMakeSelf += cmSystemTools::GetExecutableExtension();
|
||||
#if __APPLE__
|
||||
#ifdef __APPLE__
|
||||
// on the apple this might be the gui bundle
|
||||
if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
|
||||
{
|
||||
|
@ -3299,6 +3299,12 @@ int cmake::ExecuteLinkScript(std::vector<std::string>& args)
|
|||
int result = 0;
|
||||
while(result == 0 && cmSystemTools::GetLineFromStream(fin, command))
|
||||
{
|
||||
// Skip empty command lines.
|
||||
if(command.find_first_not_of(" \t") == command.npos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Setup this command line.
|
||||
const char* cmd[2] = {command.c_str(), 0};
|
||||
cmsysProcess_SetCommand(cp, cmd);
|
||||
|
@ -3552,6 +3558,13 @@ void cmake::DefineProperty(const char *name, cmProperty::ScopeType scope,
|
|||
chained);
|
||||
}
|
||||
|
||||
bool cmake::GetIsPropertyDefined(const char *name,
|
||||
cmProperty::ScopeType scope)
|
||||
{
|
||||
return this->PropertyDefinitions[scope].find(name) !=
|
||||
this->PropertyDefinitions[scope].end();
|
||||
}
|
||||
|
||||
cmPropertyDefinition *cmake
|
||||
::GetPropertyDefinition(const char *name,
|
||||
cmProperty::ScopeType scope)
|
||||
|
|
|
@ -341,6 +341,8 @@ class cmake
|
|||
bool chain = false,
|
||||
const char *variableGroup = 0);
|
||||
|
||||
bool GetIsPropertyDefined(const char *name, cmProperty::ScopeType scope);
|
||||
|
||||
// get property definition
|
||||
cmPropertyDefinition *GetPropertyDefinition
|
||||
(const char *name, cmProperty::ScopeType scope);
|
||||
|
|
|
@ -116,7 +116,6 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
|
|||
SET(KWSYS_USE_MD5 1)
|
||||
SET(KWSYS_USE_Process 1)
|
||||
SET(KWSYS_USE_RegularExpression 1)
|
||||
SET(KWSYS_USE_Registry 1)
|
||||
SET(KWSYS_USE_System 1)
|
||||
SET(KWSYS_USE_SystemTools 1)
|
||||
SET(KWSYS_USE_CommandLineArguments 1)
|
||||
|
@ -575,6 +574,8 @@ IF(KWSYS_USE_SystemTools)
|
|||
ENDIF()
|
||||
|
||||
IF(KWSYS_USE_SystemInformation)
|
||||
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS SIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P})
|
||||
IF(NOT CYGWIN)
|
||||
INCLUDE(CheckIncludeFiles)
|
||||
CHECK_INCLUDE_FILES("sys/types.h;ifaddrs.h" KWSYS_SYS_HAS_IFADDRS_H)
|
||||
|
@ -597,6 +598,20 @@ IF(KWSYS_USE_SystemInformation)
|
|||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(CMAKE_SYSTEM MATCHES "HP-UX")
|
||||
CHECK_INCLUDE_FILES("sys/mpctl.h" KWSYS_SYS_HAS_MPCTL_H)
|
||||
IF(KWSYS_SYS_HAS_MPCTL_H)
|
||||
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS KWSYS_SYS_HAS_MPCTL_H=1)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(CMAKE_SYSTEM MATCHES "BSD")
|
||||
CHECK_INCLUDE_FILES("machine/cpu.h" KWSYS_SYS_HAS_MACHINE_CPU_H)
|
||||
IF(KWSYS_SYS_HAS_MACHINE_CPU_H)
|
||||
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS KWSYS_SYS_HAS_MACHINE_CPU_H=1)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(KWSYS_LFS_AVAILABLE AND NOT KWSYS_LFS_DISABLE)
|
||||
SET(KWSYS_PLATFORM_CXX_TEST_DEFINES -DKWSYS_HAS_LFS=1)
|
||||
ENDIF()
|
||||
|
@ -625,6 +640,20 @@ IF(KWSYS_USE_SystemInformation)
|
|||
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS KWSYS_CXX_HAS__ATOI64=1)
|
||||
ENDIF()
|
||||
IF(BORLAND)
|
||||
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM
|
||||
"Checking whether Borland CXX compiler supports assembler instructions" DIRECT)
|
||||
IF(KWSYS_CXX_HAS_BORLAND_ASM)
|
||||
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM=1)
|
||||
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM_CPUID
|
||||
"Checking whether Borland CXX compiler supports CPUID assembler instruction" DIRECT)
|
||||
IF(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
|
||||
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM_CPUID=1)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(KWSYS_USE___INT64)
|
||||
SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS KWSYS_USE___INT64=1)
|
||||
|
@ -762,7 +791,7 @@ SET(KWSYS_HXX_FILES Configure String
|
|||
# Add selected C++ classes.
|
||||
SET(cppclasses
|
||||
Directory DynamicLoader Glob RegularExpression SystemTools
|
||||
CommandLineArguments Registry IOStream SystemInformation
|
||||
CommandLineArguments IOStream SystemInformation
|
||||
)
|
||||
FOREACH(cpp ${cppclasses})
|
||||
IF(KWSYS_USE_${cpp})
|
||||
|
@ -800,12 +829,8 @@ SET(KWSYS_CXX_SRCS)
|
|||
# Add the proper sources for this platform's Process implementation.
|
||||
IF(KWSYS_USE_Process)
|
||||
IF(NOT UNIX)
|
||||
# Use the Windows implementation. We need the encoded forwarding executable.
|
||||
SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c
|
||||
${PROJECT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c)
|
||||
SET_SOURCE_FILES_PROPERTIES(
|
||||
${PROJECT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c
|
||||
PROPERTIES GENERATED 1)
|
||||
# Use the Windows implementation.
|
||||
SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c)
|
||||
ELSE(NOT UNIX)
|
||||
# Use the UNIX implementation.
|
||||
SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c)
|
||||
|
@ -937,43 +962,6 @@ IF(KWSYS_USE_String)
|
|||
COMPILE_FLAGS "-DKWSYS_STRING_C")
|
||||
ENDIF(KWSYS_USE_String)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Process execution on windows needs to build a forwarding executable
|
||||
# that works around a Win9x bug. We encode the executable into a C
|
||||
# file and build it into the library. Win9x platforms reproduce the
|
||||
# executable into a temporary directory when it is needed.
|
||||
IF(KWSYS_USE_Process)
|
||||
IF(NOT UNIX)
|
||||
# Build the forwarding executable itself and a program that will
|
||||
# encode it into a C file.
|
||||
ADD_EXECUTABLE(${KWSYS_NAMESPACE}ProcessFwd9x ProcessFwd9x.c)
|
||||
ADD_EXECUTABLE(${KWSYS_NAMESPACE}EncodeExecutable EncodeExecutable.c)
|
||||
SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}ProcessFwd9x PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}EncodeExecutable PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}ProcessFwd9x PROPERTY LABELS ${KWSYS_LABELS_EXE})
|
||||
SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}EncodeExecutable PROPERTY LABELS ${KWSYS_LABELS_EXE})
|
||||
|
||||
SET(CFG_INTDIR "/${CMAKE_CFG_INTDIR}")
|
||||
IF(CMAKE_BUILD_TOOL MATCHES "make")
|
||||
SET(CFG_INTDIR "")
|
||||
ENDIF(CMAKE_BUILD_TOOL MATCHES "make")
|
||||
|
||||
# Take advantage of a better custom command syntax if possible.
|
||||
SET(CMD ${CMAKE_CURRENT_BINARY_DIR}${CFG_INTDIR}/${KWSYS_NAMESPACE}EncodeExecutable.exe)
|
||||
SET(FWD ${CMAKE_CURRENT_BINARY_DIR}${CFG_INTDIR}/${KWSYS_NAMESPACE}ProcessFwd9x.exe)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c
|
||||
COMMAND ${CMD}
|
||||
ARGS ${FWD} ${CMAKE_CURRENT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c
|
||||
${KWSYS_NAMESPACE} ProcessFwd9x
|
||||
DEPENDS ${CMD} ${FWD})
|
||||
|
||||
# Make sure build occurs in proper order.
|
||||
ADD_DEPENDENCIES(${KWSYS_NAMESPACE} ${KWSYS_NAMESPACE}ProcessFwd9x
|
||||
${KWSYS_NAMESPACE}EncodeExecutable)
|
||||
ENDIF(NOT UNIX)
|
||||
ENDIF(KWSYS_USE_Process)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Setup testing if not being built as part of another project.
|
||||
IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
|
||||
|
@ -1012,7 +1000,6 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
|
|||
)
|
||||
ENDIF(NOT WATCOM)
|
||||
SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
|
||||
testRegistry
|
||||
testIOS
|
||||
testSystemTools
|
||||
testCommandLineArguments
|
||||
|
@ -1116,8 +1103,6 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
|
|||
# We expect test to fail
|
||||
SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES WILL_FAIL ON)
|
||||
GET_TEST_PROPERTY(kwsys.testFail WILL_FAIL wfv)
|
||||
SET_TESTS_PROPERTIES(kwsys.testRegistry PROPERTIES FAIL_REGULAR_EXPRESSION "ERROR_NOT_VALGRIND;FAIL;Test failed")
|
||||
SET_TESTS_PROPERTIES(kwsys.testRegistry PROPERTIES PASS_REGULAR_EXPRESSION "Test passed")
|
||||
SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value")
|
||||
MESSAGE(STATUS "GET_TEST_PROPERTY returned: ${wfv}")
|
||||
ENDIF()
|
||||
|
|
|
@ -98,6 +98,14 @@
|
|||
#elif defined(__SYSC_ZARCH__)
|
||||
# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
|
||||
|
||||
/* Aarch64 */
|
||||
#elif defined(__aarch64__)
|
||||
# if !defined(__AARCH64EB__)
|
||||
# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE
|
||||
# else
|
||||
# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG
|
||||
# endif
|
||||
|
||||
/* Unknown CPU */
|
||||
#else
|
||||
# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID 0
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
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.
|
||||
============================================================================*/
|
||||
#include <stdio.h>
|
||||
#ifdef __WATCOMC__
|
||||
#define _unlink unlink
|
||||
#endif
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
FILE* ifp;
|
||||
FILE* ofp;
|
||||
int i;
|
||||
int n;
|
||||
int count = 0;
|
||||
unsigned char buffer[1024];
|
||||
|
||||
/* Check arguments. */
|
||||
if(argc != 5)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <input> <output> <kwsys-name> <array>\n",
|
||||
argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Open the input file. */
|
||||
ifp = fopen(argv[1], "rb");
|
||||
if(!ifp)
|
||||
{
|
||||
fprintf(stderr, "Cannot open input file: \"%s\"\n", argv[1]);
|
||||
return 2;
|
||||
}
|
||||
ofp = fopen(argv[2], "w");
|
||||
if(!ofp)
|
||||
{
|
||||
fprintf(stderr, "Cannot open output file: \"%s\"\n", argv[2]);
|
||||
fclose(ifp);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Prepend header comment. */
|
||||
fprintf(ofp, "/*\n * DO NOT EDIT\n * This file is generated by:\n");
|
||||
fprintf(ofp, " * %s\n */\n\n", argv[0]);
|
||||
fprintf(ofp, "#include \"kwsysPrivate.h\"\n");
|
||||
fprintf(ofp, "#include KWSYS_HEADER(Configure.h)\n\n");
|
||||
fprintf(ofp, "#include <stdio.h>\n\n");
|
||||
fprintf(ofp, "#if defined(_WIN32)\n");
|
||||
fprintf(ofp, "# include <io.h>\n");
|
||||
fprintf(ofp, "#else\n");
|
||||
fprintf(ofp, "# include <unistd.h>\n");
|
||||
fprintf(ofp, "#endif\n");
|
||||
fprintf(ofp, "\n");
|
||||
fprintf(ofp, "static void kwsys_unlink(const char* fname)\n");
|
||||
fprintf(ofp, "{\n");
|
||||
fprintf(ofp, "#if defined(__WATCOMC__)\n");
|
||||
fprintf(ofp, " unlink(fname);\n");
|
||||
fprintf(ofp, "#else\n");
|
||||
fprintf(ofp, " _unlink(fname);\n");
|
||||
fprintf(ofp, "#endif\n");
|
||||
fprintf(ofp, "}\n");
|
||||
fprintf(ofp, "\n");
|
||||
|
||||
/* Split file up in 1024-byte chunks. */
|
||||
while((n = (int)fread(buffer, 1, 1024, ifp)) > 0)
|
||||
{
|
||||
fprintf(ofp, "static unsigned char kwsysEncodedArray%s_%d[%d] = {\n",
|
||||
argv[4], count++, n);
|
||||
for(i=0; i < n-1; ++i)
|
||||
{
|
||||
fprintf(ofp, "0x%02X", buffer[i]);
|
||||
if(i%10 == 9)
|
||||
{
|
||||
fprintf(ofp, ",\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(ofp, ", ");
|
||||
}
|
||||
}
|
||||
fprintf(ofp, "0x%02X};\n\n", buffer[n-1]);
|
||||
}
|
||||
fclose(ifp);
|
||||
|
||||
/* Provide a function to write the data to a file. */
|
||||
fprintf(ofp, "extern %s_EXPORT int %sEncodedWriteArray%s(const char* fname)\n",
|
||||
argv[3], argv[3], argv[4]);
|
||||
fprintf(ofp, "{\n");
|
||||
fprintf(ofp, " FILE* ofp = fopen(fname, \"wb\");\n");
|
||||
fprintf(ofp, " if(!ofp) { return 0; }\n");
|
||||
for(i=0; i < count; ++i)
|
||||
{
|
||||
fprintf(ofp, " if(fwrite(kwsysEncodedArray%s_%d, 1,\n"
|
||||
" sizeof(kwsysEncodedArray%s_%d), ofp) !=\n"
|
||||
" sizeof(kwsysEncodedArray%s_%d))\n",
|
||||
argv[4], i, argv[4], i, argv[4], i);
|
||||
fprintf(ofp, " {\n");
|
||||
fprintf(ofp, " fclose(ofp);\n");
|
||||
fprintf(ofp, " kwsys_unlink(fname);\n");
|
||||
fprintf(ofp, " return 0;\n");
|
||||
fprintf(ofp, " }\n");
|
||||
}
|
||||
fprintf(ofp, " fclose(ofp);\n");
|
||||
fprintf(ofp, " return 1;\n");
|
||||
fprintf(ofp, "}\n");
|
||||
fclose(ofp);
|
||||
return 0;
|
||||
}
|
|
@ -26,12 +26,9 @@
|
|||
/* Whether ostream supports long long. */
|
||||
#define @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG @KWSYS_IOS_HAS_OSTREAM_LONG_LONG@
|
||||
|
||||
/* Size of type long long and 0 if not available. */
|
||||
#define @KWSYS_NAMESPACE@_IOS_SIZEOF_LONG_LONG @KWSYS_SIZEOF_LONG_LONG@
|
||||
|
||||
/* Determine whether we need to define the streaming operators for
|
||||
long long or __int64. */
|
||||
#if @KWSYS_NAMESPACE@_IOS_SIZEOF_LONG_LONG
|
||||
#if @KWSYS_USE_LONG_LONG@
|
||||
# if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG || \
|
||||
!@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
|
||||
# define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1
|
||||
|
@ -136,7 +133,6 @@ operator<<(kwsys_ios::ostream& os, @KWSYS_NAMESPACE@::IOStreamULL value)
|
|||
/* If building a C++ file in kwsys itself, give the source file
|
||||
access to the macros without a configured namespace. */
|
||||
#if defined(KWSYS_NAMESPACE)
|
||||
# define KWSYS_IOS_SIZEOF_LONG_LONG @KWSYS_NAMESPACE@_IOS_SIZEOF_LONG_LONG
|
||||
# define KWSYS_IOS_HAS_ISTREAM_LONG_LONG @KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG
|
||||
# define KWSYS_IOS_HAS_OSTREAM_LONG_LONG @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
|
||||
# define KWSYS_IOS_NEED_OPERATORS_LL @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL
|
||||
|
|
|
@ -1,211 +0,0 @@
|
|||
/*============================================================================
|
||||
KWSys - Kitware System Library
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
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.
|
||||
============================================================================*/
|
||||
|
||||
/*
|
||||
On Windows9x platforms, this executable is spawned between a parent
|
||||
process and the child it is invoking to work around a bug. See the
|
||||
Win32 implementation file for details.
|
||||
|
||||
Future Work: This executable must be linked statically against the C
|
||||
runtime library before being encoded into the library. Building it
|
||||
in this way may be hard because CMake has limited abilities to build
|
||||
different targets with different configurations in the same
|
||||
directory. We may just have to create and encode the executable
|
||||
once instead of generating it during the build. This would be an
|
||||
acceptable solution because the forwarding executable should not
|
||||
change very often and is pretty simple.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push, 1)
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void ReportLastError(HANDLE errorPipe);
|
||||
|
||||
int main()
|
||||
{
|
||||
/* Process startup information for the real child. */
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
/* The result of waiting for the child to exit. */
|
||||
DWORD waitResult;
|
||||
|
||||
/* The child's process return code. */
|
||||
DWORD retVal;
|
||||
|
||||
/* The command line used to invoke this process. */
|
||||
LPSTR commandLine = GetCommandLine();
|
||||
|
||||
/* Pointer that will be advanced to the beginning of the command
|
||||
line of the real child process. */
|
||||
LPSTR cmdLine = commandLine;
|
||||
|
||||
/* Handle to the error reporting pipe provided by the parent. This
|
||||
is parsed off the command line. */
|
||||
HANDLE errorPipe = 0;
|
||||
HANDLE errorPipeOrig = 0;
|
||||
|
||||
/* Handle to the event the parent uses to tell us to resume the child.
|
||||
This is parsed off the command line. */
|
||||
HANDLE resumeEvent = 0;
|
||||
|
||||
/* Handle to the event the parent uses to tell us to kill the child.
|
||||
This is parsed off the command line. */
|
||||
HANDLE killEvent = 0;
|
||||
|
||||
/* Flag for whether to hide window of child process. */
|
||||
int hideWindow = 0;
|
||||
|
||||
/* An array of the handles on which we wait when the child is
|
||||
running. */
|
||||
HANDLE waitHandles[2] = {0, 0};
|
||||
|
||||
/* Move the pointer past the name of this executable. */
|
||||
if(*cmdLine == '"')
|
||||
{
|
||||
++cmdLine;
|
||||
while(*cmdLine && *cmdLine != '"') { ++cmdLine; }
|
||||
if(*cmdLine) { ++cmdLine; }
|
||||
}
|
||||
else
|
||||
{
|
||||
while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
|
||||
}
|
||||
|
||||
/* Parse the error pipe handle. */
|
||||
while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
|
||||
sscanf(cmdLine, "%p", &errorPipeOrig);
|
||||
|
||||
/* Parse the resume event handle. */
|
||||
while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
|
||||
while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
|
||||
sscanf(cmdLine, "%p", &resumeEvent);
|
||||
|
||||
/* Parse the kill event handle. */
|
||||
while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
|
||||
while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
|
||||
sscanf(cmdLine, "%p", &killEvent);
|
||||
|
||||
/* Parse the hide window flag. */
|
||||
while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
|
||||
while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
|
||||
sscanf(cmdLine, "%d", &hideWindow);
|
||||
|
||||
/* Skip to the beginning of the command line of the real child. */
|
||||
while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
|
||||
while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
|
||||
|
||||
/* Create a non-inherited copy of the error pipe. We do not want
|
||||
the child to get it. */
|
||||
if(DuplicateHandle(GetCurrentProcess(), errorPipeOrig,
|
||||
GetCurrentProcess(), &errorPipe,
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
/* Have a non-inherited duplicate. Close the inherited one. */
|
||||
CloseHandle(errorPipeOrig);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Could not duplicate handle. Report the error. */
|
||||
ReportLastError(errorPipeOrig);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create the subprocess. */
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
ZeroMemory(&pi, sizeof(pi));
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = hideWindow?SW_HIDE:SW_SHOWDEFAULT;
|
||||
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
||||
if(CreateProcess(0, cmdLine, 0, 0, TRUE, CREATE_SUSPENDED, 0, 0, &si, &pi))
|
||||
{
|
||||
/* Process created successfully. Close the error reporting pipe
|
||||
to notify the parent of success. */
|
||||
CloseHandle(errorPipe);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error creating the process. Report the error to the parent
|
||||
process through the special error reporting pipe. */
|
||||
ReportLastError(errorPipe);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Wait for resume or kill event from parent. */
|
||||
waitHandles[0] = killEvent;
|
||||
waitHandles[1] = resumeEvent;
|
||||
waitResult = WaitForMultipleObjects(2, waitHandles, 0, INFINITE);
|
||||
|
||||
/* Check what happened. */
|
||||
if(waitResult == WAIT_OBJECT_0)
|
||||
{
|
||||
/* We were asked to kill the child. */
|
||||
TerminateProcess(pi.hProcess, 255);
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We were asked to resume the child. */
|
||||
ResumeThread(pi.hThread);
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
|
||||
/* Wait for subprocess to exit or for kill event from parent. */
|
||||
waitHandles[0] = killEvent;
|
||||
waitHandles[1] = pi.hProcess;
|
||||
waitResult = WaitForMultipleObjects(2, waitHandles, 0, INFINITE);
|
||||
|
||||
/* Check what happened. */
|
||||
if(waitResult == WAIT_OBJECT_0)
|
||||
{
|
||||
/* We were asked to kill the child. */
|
||||
TerminateProcess(pi.hProcess, 255);
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
CloseHandle(pi.hProcess);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The child exited. Get the return code. */
|
||||
GetExitCodeProcess(pi.hProcess, &retVal);
|
||||
CloseHandle(pi.hProcess);
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
void ReportLastError(HANDLE errorPipe)
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
DWORD n;
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
WriteFile(errorPipe, lpMsgBuf, strlen(lpMsgBuf)+1, &n, 0);
|
||||
LocalFree( lpMsgBuf );
|
||||
}
|
|
@ -63,10 +63,6 @@ do.
|
|||
#include <dirent.h> /* DIR, dirent */
|
||||
#include <ctype.h> /* isspace */
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#undef __BEOS__
|
||||
#endif
|
||||
|
||||
#if defined(__VMS)
|
||||
# define KWSYSPE_VMS_NONBLOCK , O_NONBLOCK
|
||||
#else
|
||||
|
@ -422,9 +418,10 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
|
|||
parse it. */
|
||||
newCommands[cp->NumberOfCommands] =
|
||||
kwsysSystem_Parse_CommandForUnix(*command, 0);
|
||||
if(!newCommands[cp->NumberOfCommands])
|
||||
if(!newCommands[cp->NumberOfCommands] ||
|
||||
!newCommands[cp->NumberOfCommands][0])
|
||||
{
|
||||
/* Out of memory. */
|
||||
/* Out of memory or no command parsed. */
|
||||
free(newCommands);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -28,14 +28,6 @@ On windows, a thread is created to wait for data on each pipe. The
|
|||
threads are synchronized with the main thread to simulate the use of
|
||||
a UNIX-style select system call.
|
||||
|
||||
On Windows9x platforms, a small WIN32 console application is spawned
|
||||
in-between the calling process and the actual child to be executed.
|
||||
This is to work-around a problem with connecting pipes from WIN16
|
||||
console applications to WIN32 applications.
|
||||
|
||||
For more information, please check Microsoft Knowledge Base Articles
|
||||
Q190351 and Q150956.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -91,18 +83,12 @@ Q190351 and Q150956.
|
|||
# define KWSYSPE_DEBUG(x) (void)1
|
||||
#endif
|
||||
|
||||
#define kwsysEncodedWriteArrayProcessFwd9x kwsys_ns(EncodedWriteArrayProcessFwd9x)
|
||||
|
||||
typedef LARGE_INTEGER kwsysProcessTime;
|
||||
|
||||
typedef struct kwsysProcessCreateInformation_s
|
||||
{
|
||||
/* Windows child startup control data. */
|
||||
STARTUPINFO StartupInfo;
|
||||
|
||||
/* Special error reporting pipe for Win9x forwarding executable. */
|
||||
HANDLE ErrorPipeRead;
|
||||
HANDLE ErrorPipeWrite;
|
||||
} kwsysProcessCreateInformation;
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
@ -146,7 +132,6 @@ static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProc
|
|||
static void kwsysProcessSetExitException(kwsysProcess* cp, int code);
|
||||
static void kwsysProcessKillTree(int pid);
|
||||
static void kwsysProcessDisablePipeThreads(kwsysProcess* cp);
|
||||
extern kwsysEXPORT int kwsysEncodedWriteArrayProcessFwd9x(const char* fname);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* A structure containing synchronization data for each thread. */
|
||||
|
@ -233,15 +218,6 @@ struct kwsysProcess_s
|
|||
/* Whether to treat command lines as verbatim. */
|
||||
int Verbatim;
|
||||
|
||||
/* On Win9x platforms, the path to the forwarding executable. */
|
||||
char* Win9x;
|
||||
|
||||
/* On Win9x platforms, the resume event for the forwarding executable. */
|
||||
HANDLE Win9xResumeEvent;
|
||||
|
||||
/* On Win9x platforms, the kill event for the forwarding executable. */
|
||||
HANDLE Win9xKillEvent;
|
||||
|
||||
/* Mutex to protect the shared index used by threads to report data. */
|
||||
HANDLE SharedIndexMutex;
|
||||
|
||||
|
@ -269,9 +245,6 @@ struct kwsysProcess_s
|
|||
HANDLE PipeNativeSTDOUT[2];
|
||||
HANDLE PipeNativeSTDERR[2];
|
||||
|
||||
/* Handle to automatically delete the Win9x forwarding executable. */
|
||||
HANDLE Win9xHandle;
|
||||
|
||||
/* ------------- Data managed per call to Execute ------------- */
|
||||
|
||||
/* The exceptional behavior that terminated the process, if any. */
|
||||
|
@ -311,7 +284,7 @@ struct kwsysProcess_s
|
|||
for pipes to close after process termination. */
|
||||
int PipesLeft;
|
||||
|
||||
/* Buffer for error messages (possibly from Win9x child). */
|
||||
/* Buffer for error messages. */
|
||||
char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
|
||||
|
||||
/* Description for the ExitException. */
|
||||
|
@ -337,9 +310,6 @@ kwsysProcess* kwsysProcess_New(void)
|
|||
/* Process control structure. */
|
||||
kwsysProcess* cp;
|
||||
|
||||
/* Path to Win9x forwarding executable. */
|
||||
char* win9x = 0;
|
||||
|
||||
/* Windows version number data. */
|
||||
OSVERSIONINFO osv;
|
||||
|
||||
|
@ -365,73 +335,11 @@ kwsysProcess* kwsysProcess_New(void)
|
|||
GetVersionEx(&osv);
|
||||
if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
|
||||
{
|
||||
/* This is Win9x. We need the console forwarding executable to
|
||||
work-around a Windows 9x bug. */
|
||||
char fwdName[_MAX_FNAME+1] = "";
|
||||
char tempDir[_MAX_PATH+1] = "";
|
||||
|
||||
/* We will try putting the executable in the system temp
|
||||
directory. Note that the returned path already has a trailing
|
||||
slash. */
|
||||
DWORD length = GetTempPath(_MAX_PATH+1, tempDir);
|
||||
|
||||
/* Construct the executable name from the process id and kwsysProcess
|
||||
instance. This should be unique. */
|
||||
sprintf(fwdName, KWSYS_NAMESPACE_STRING "pew9xfwd_%ld_%p.exe",
|
||||
GetCurrentProcessId(), cp);
|
||||
|
||||
/* If we have a temp directory, use it. */
|
||||
if(length > 0 && length <= _MAX_PATH)
|
||||
{
|
||||
/* Allocate a buffer to hold the forwarding executable path. */
|
||||
size_t tdlen = strlen(tempDir);
|
||||
win9x = (char*)malloc(tdlen + strlen(fwdName) + 2);
|
||||
if(!win9x)
|
||||
{
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Construct the full path to the forwarding executable. */
|
||||
sprintf(win9x, "%s%s", tempDir, fwdName);
|
||||
}
|
||||
|
||||
/* If we found a place to put the forwarding executable, try to
|
||||
write it. */
|
||||
if(win9x)
|
||||
{
|
||||
if(!kwsysEncodedWriteArrayProcessFwd9x(win9x))
|
||||
{
|
||||
/* Failed to create forwarding executable. Give up. */
|
||||
free(win9x);
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get a handle to the file that will delete it when closed. */
|
||||
cp->Win9xHandle = CreateFile(win9x, GENERIC_READ, FILE_SHARE_READ, 0,
|
||||
OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);
|
||||
if(cp->Win9xHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/* We were not able to get a read handle for the forwarding
|
||||
executable. It will not be deleted properly. Give up. */
|
||||
_unlink(win9x);
|
||||
free(win9x);
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed to find a place to put forwarding executable. */
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
/* Win9x no longer supported. */
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Save the path to the forwarding executable. */
|
||||
cp->Win9x = win9x;
|
||||
|
||||
/* Initially no thread owns the mutex. Initialize semaphore to 1. */
|
||||
if(!(cp->SharedIndexMutex = CreateSemaphore(0, 1, 1, 0)))
|
||||
{
|
||||
|
@ -446,30 +354,6 @@ kwsysProcess* kwsysProcess_New(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if(cp->Win9x)
|
||||
{
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
ZeroMemory(&sa, sizeof(sa));
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.bInheritHandle = TRUE;
|
||||
|
||||
/* Create an event to tell the forwarding executable to resume the
|
||||
child. */
|
||||
if(!(cp->Win9xResumeEvent = CreateEvent(&sa, TRUE, 0, 0)))
|
||||
{
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create an event to tell the forwarding executable to kill the
|
||||
child. */
|
||||
if(!(cp->Win9xKillEvent = CreateEvent(&sa, TRUE, 0, 0)))
|
||||
{
|
||||
kwsysProcess_Delete(cp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the thread to read each pipe. */
|
||||
for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
|
||||
{
|
||||
|
@ -620,13 +504,6 @@ void kwsysProcess_Delete(kwsysProcess* cp)
|
|||
kwsysProcessCleanupHandle(&cp->SharedIndexMutex);
|
||||
kwsysProcessCleanupHandle(&cp->Full);
|
||||
|
||||
/* Close the Win9x resume and kill event handles. */
|
||||
if(cp->Win9x)
|
||||
{
|
||||
kwsysProcessCleanupHandle(&cp->Win9xResumeEvent);
|
||||
kwsysProcessCleanupHandle(&cp->Win9xKillEvent);
|
||||
}
|
||||
|
||||
/* Free memory. */
|
||||
kwsysProcess_SetCommand(cp, 0);
|
||||
kwsysProcess_SetWorkingDirectory(cp, 0);
|
||||
|
@ -637,12 +514,6 @@ void kwsysProcess_Delete(kwsysProcess* cp)
|
|||
{
|
||||
free(cp->CommandExitCodes);
|
||||
}
|
||||
if(cp->Win9x)
|
||||
{
|
||||
/* Close our handle to the forwarding executable file. This will
|
||||
cause it to be deleted. */
|
||||
kwsysProcessCleanupHandle(&cp->Win9xHandle);
|
||||
}
|
||||
free(cp);
|
||||
}
|
||||
|
||||
|
@ -1017,21 +888,6 @@ void kwsysProcess_Execute(kwsysProcess* cp)
|
|||
SetCurrentDirectory(cp->WorkingDirectory);
|
||||
}
|
||||
|
||||
/* Reset the Win9x resume and kill events. */
|
||||
if(cp->Win9x)
|
||||
{
|
||||
if(!ResetEvent(cp->Win9xResumeEvent))
|
||||
{
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
if(!ResetEvent(cp->Win9xKillEvent))
|
||||
{
|
||||
kwsysProcessCleanup(cp, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize startup info data. */
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.StartupInfo.cb = sizeof(si.StartupInfo);
|
||||
|
@ -1130,8 +986,6 @@ void kwsysProcess_Execute(kwsysProcess* cp)
|
|||
STD_OUTPUT_HANDLE);
|
||||
kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError,
|
||||
STD_ERROR_HANDLE);
|
||||
kwsysProcessCleanupHandle(&si.ErrorPipeRead);
|
||||
kwsysProcessCleanupHandle(&si.ErrorPipeWrite);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1160,16 +1014,9 @@ void kwsysProcess_Execute(kwsysProcess* cp)
|
|||
|
||||
/* All processes in the pipeline have been started in suspended
|
||||
mode. Resume them all now. */
|
||||
if(cp->Win9x)
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
SetEvent(cp->Win9xResumeEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
ResumeThread(cp->ProcessInformation[i].hThread);
|
||||
}
|
||||
ResumeThread(cp->ProcessInformation[i].hThread);
|
||||
}
|
||||
|
||||
/* ---- It is no longer safe to call kwsysProcessCleanup. ----- */
|
||||
|
@ -1480,21 +1327,12 @@ void kwsysProcess_Kill(kwsysProcess* cp)
|
|||
|
||||
/* Kill the children. */
|
||||
cp->Killed = 1;
|
||||
if(cp->Win9x)
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
/* Windows 9x. Tell the forwarding executable to kill the child. */
|
||||
SetEvent(cp->Win9xKillEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not Windows 9x. Just terminate the children. */
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId);
|
||||
// close the handle if we kill it
|
||||
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
|
||||
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
|
||||
}
|
||||
kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId);
|
||||
// close the handle if we kill it
|
||||
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
|
||||
kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
|
||||
}
|
||||
|
||||
/* We are killing the children and ignoring all data. Do not wait
|
||||
|
@ -1815,97 +1653,13 @@ int kwsysProcessCreate(kwsysProcess* cp, int index,
|
|||
}
|
||||
}
|
||||
|
||||
/* Create the child process. */
|
||||
{
|
||||
BOOL r;
|
||||
char* realCommand;
|
||||
if(cp->Win9x)
|
||||
{
|
||||
/* Create an error reporting pipe for the forwarding executable.
|
||||
Neither end is directly inherited. */
|
||||
if(!CreatePipe(&si->ErrorPipeRead, &si->ErrorPipeWrite, 0, 0))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create an inherited duplicate of the write end. This also closes
|
||||
the non-inherited version. */
|
||||
if(!DuplicateHandle(GetCurrentProcess(), si->ErrorPipeWrite,
|
||||
GetCurrentProcess(), &si->ErrorPipeWrite,
|
||||
0, TRUE, (DUPLICATE_CLOSE_SOURCE |
|
||||
DUPLICATE_SAME_ACCESS)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The forwarding executable is given a handle to the error pipe
|
||||
and resume and kill events. */
|
||||
realCommand = (char*)malloc(strlen(cp->Win9x)+strlen(cp->Commands[index])+100);
|
||||
if(!realCommand)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
sprintf(realCommand, "%s %p %p %p %d %s", cp->Win9x,
|
||||
si->ErrorPipeWrite, cp->Win9xResumeEvent, cp->Win9xKillEvent,
|
||||
cp->HideWindow, cp->Commands[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
realCommand = cp->Commands[index];
|
||||
}
|
||||
|
||||
/* Create the child in a suspended state so we can wait until all
|
||||
children have been created before running any one. */
|
||||
r = CreateProcess(0, realCommand, 0, 0, TRUE,
|
||||
cp->Win9x? 0 : CREATE_SUSPENDED, 0, 0,
|
||||
&si->StartupInfo, &cp->ProcessInformation[index]);
|
||||
if(cp->Win9x)
|
||||
{
|
||||
/* Free memory. */
|
||||
free(realCommand);
|
||||
|
||||
/* Close the error pipe write end so we can detect when the
|
||||
forwarding executable closes it. */
|
||||
kwsysProcessCleanupHandle(&si->ErrorPipeWrite);
|
||||
if(r)
|
||||
{
|
||||
/* Wait for the forwarding executable to report an error or
|
||||
close the error pipe to report success. */
|
||||
DWORD total = 0;
|
||||
DWORD n = 1;
|
||||
while(total < KWSYSPE_PIPE_BUFFER_SIZE && n > 0)
|
||||
{
|
||||
if(ReadFile(si->ErrorPipeRead, cp->ErrorMessage+total,
|
||||
KWSYSPE_PIPE_BUFFER_SIZE-total, &n, 0))
|
||||
{
|
||||
total += n;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = 0;
|
||||
}
|
||||
}
|
||||
if(total > 0 || GetLastError() != ERROR_BROKEN_PIPE)
|
||||
{
|
||||
/* The forwarding executable could not run the process, or
|
||||
there was an error reading from its error pipe. Preserve
|
||||
the last error while cleaning up the forwarding executable
|
||||
so the cleanup our caller does reports the proper error. */
|
||||
DWORD error = GetLastError();
|
||||
kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hThread);
|
||||
kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
|
||||
SetLastError(error);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
kwsysProcessCleanupHandle(&si->ErrorPipeRead);
|
||||
}
|
||||
|
||||
if(!r)
|
||||
if(!CreateProcess(0, cp->Commands[index], 0, 0, TRUE, CREATE_SUSPENDED, 0,
|
||||
0, &si->StartupInfo, &cp->ProcessInformation[index]))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Successfully created this child process. Close the current
|
||||
process's copies of the inherited stdout and stdin handles. The
|
||||
|
@ -2152,19 +1906,12 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error)
|
|||
/* Cleanup any processes already started in a suspended state. */
|
||||
if(cp->ProcessInformation)
|
||||
{
|
||||
if(cp->Win9x)
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
{
|
||||
SetEvent(cp->Win9xKillEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
if(cp->ProcessInformation[i].hProcess)
|
||||
{
|
||||
if(cp->ProcessInformation[i].hProcess)
|
||||
{
|
||||
TerminateProcess(cp->ProcessInformation[i].hProcess, 255);
|
||||
WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE);
|
||||
}
|
||||
TerminateProcess(cp->ProcessInformation[i].hProcess, 255);
|
||||
WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE);
|
||||
}
|
||||
}
|
||||
for(i=0; i < cp->NumberOfCommands; ++i)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue