summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Hoffman <bill.hoffman@kitware.com>2008-09-03 09:43:33 -0400
committerBill Hoffman <bill.hoffman@kitware.com>2008-09-03 09:43:33 -0400
commit3497345c4141e2cd1a1505e7e09c19a9632c4d30 (patch)
tree0061ee4fe4484a653a1b44f4c8f4214846dab3ee
parent1243389ca49d111453a74f1a817297032b4837b1 (diff)
downloadcmake-3497345c4141e2cd1a1505e7e09c19a9632c4d30.tar.gz
ENH: 2.6.2 rc 2 merge from main tree
-rw-r--r--CMakeLists.txt2
-rw-r--r--ChangeLog.manual44
-rw-r--r--Docs/cmake-syntax.vim4
-rw-r--r--Modules/CMakeCCompilerABI.c20
-rw-r--r--Modules/CMakeCCompilerId.c.in21
-rw-r--r--Modules/CMakeCXXCompilerABI.cpp16
-rw-r--r--Modules/CMakeCXXCompilerId.cpp.in14
-rw-r--r--Modules/CheckTypeSizeC.c.in13
-rw-r--r--Modules/FindKDE3.cmake12
-rw-r--r--Modules/FindKDE4.cmake12
-rw-r--r--Modules/FindLibXml2.cmake13
-rw-r--r--Modules/FindLua50.cmake2
-rw-r--r--Modules/FindLua51.cmake2
-rw-r--r--Modules/FindOpenGL.cmake8
-rw-r--r--Modules/FindPHP4.cmake2
-rw-r--r--Modules/FindPNG.cmake2
-rw-r--r--Modules/FindQt3.cmake60
-rw-r--r--Modules/FindQt4.cmake69
-rw-r--r--Modules/FindTIFF.cmake6
-rw-r--r--Modules/FindX11.cmake6
-rw-r--r--Modules/MacOSXFrameworkInfo.plist.in26
-rw-r--r--Modules/NSIS.template.in57
-rw-r--r--Modules/Platform/Darwin.cmake2
-rw-r--r--Modules/Platform/Windows-icl.cmake2
-rw-r--r--Modules/TestEndianess.c.in13
-rw-r--r--Modules/UsePkgConfig.cmake16
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx2
-rw-r--r--Source/CursesDialog/cmCursesStringWidget.cxx11
-rw-r--r--Source/cmAddLibraryCommand.cxx16
-rw-r--r--Source/cmAddLibraryCommand.h2
-rw-r--r--Source/cmAddSubDirectoryCommand.h22
-rw-r--r--Source/cmCMakePolicyCommand.cxx61
-rw-r--r--Source/cmCMakePolicyCommand.h6
-rw-r--r--Source/cmCacheManager.cxx4
-rw-r--r--Source/cmComputeLinkDepends.cxx394
-rw-r--r--Source/cmComputeLinkDepends.h35
-rw-r--r--Source/cmComputeLinkInformation.cxx13
-rw-r--r--Source/cmComputeTargetDepends.cxx21
-rw-r--r--Source/cmComputeTargetDepends.h3
-rw-r--r--Source/cmDocumentVariables.cxx18
-rw-r--r--Source/cmDocumentation.cxx7
-rw-r--r--Source/cmDocumentation.h7
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx15
-rw-r--r--Source/cmFileCommand.cxx31
-rw-r--r--Source/cmFileCommand.h6
-rw-r--r--Source/cmFindPackageCommand.cxx36
-rw-r--r--Source/cmFindPackageCommand.h1
-rw-r--r--Source/cmGlobalGenerator.cxx12
-rw-r--r--Source/cmGlobalKdevelopGenerator.cxx19
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx1
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx28
-rw-r--r--Source/cmIfCommand.cxx18
-rw-r--r--Source/cmIfCommand.h2
-rw-r--r--Source/cmLocalGenerator.cxx105
-rw-r--r--Source/cmLocalGenerator.h8
-rw-r--r--Source/cmMakefile.cxx157
-rw-r--r--Source/cmMakefile.h1
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx2
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx13
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.h2
-rw-r--r--Source/cmPolicies.cxx152
-rw-r--r--Source/cmPolicies.h16
-rw-r--r--Source/cmReturnCommand.h14
-rw-r--r--Source/cmSetPropertyCommand.cxx3
-rw-r--r--Source/cmSetTargetPropertiesCommand.cxx1
-rw-r--r--Source/cmStringCommand.cxx2
-rw-r--r--Source/cmSystemTools.cxx360
-rw-r--r--Source/cmSystemTools.h3
-rw-r--r--Source/cmTarget.cxx141
-rw-r--r--Source/cmTarget.h7
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx170
-rw-r--r--Source/cmTargetLinkLibrariesCommand.h50
-rw-r--r--Source/cmXCodeObject.cxx58
-rw-r--r--Source/cmXCodeObject.h2
-rw-r--r--Source/cmake.cxx5
-rw-r--r--Source/cmakemain.cxx19
-rw-r--r--Source/kwsys/Glob.cxx10
-rw-r--r--Source/kwsys/Glob.hxx.in8
-rw-r--r--Source/kwsys/ProcessUNIX.c17
-rw-r--r--Tests/BundleTest/BundleLib.cxx7
-rw-r--r--Tests/BundleTest/BundleSubDir/CMakeLists.txt6
-rw-r--r--Tests/BundleTest/BundleTest.cxx11
-rw-r--r--Tests/BundleTest/CMakeLists.txt19
-rw-r--r--Tests/Complex/CMakeLists.txt5
-rw-r--r--Tests/Complex/Executable/CMakeLists.txt17
-rw-r--r--Tests/Complex/Library/CMakeLists.txt4
-rw-r--r--Tests/ComplexOneConfig/CMakeLists.txt5
-rw-r--r--Tests/ComplexOneConfig/Executable/CMakeLists.txt17
-rw-r--r--Tests/ComplexOneConfig/Library/CMakeLists.txt4
-rw-r--r--Tests/ComplexRelativePaths/CMakeLists.txt5
-rw-r--r--Tests/ComplexRelativePaths/Executable/CMakeLists.txt17
-rw-r--r--Tests/ComplexRelativePaths/Library/CMakeLists.txt4
-rw-r--r--Tests/CustomCommand/CMakeLists.txt2
-rw-r--r--Tests/Dependency/CMakeLists.txt1
-rw-r--r--Tests/Dependency/Case4/CMakeLists.txt23
-rw-r--r--Tests/Dependency/Case4/bar.c2
-rw-r--r--Tests/Dependency/Case4/foo.c1
-rw-r--r--Tests/ExportImport/Export/CMakeLists.txt26
-rw-r--r--Tests/ExportImport/Export/testLib4lib.c4
-rw-r--r--Tests/ExportImport/Export/testLib4libdbg.c14
-rw-r--r--Tests/ExportImport/Export/testLib4libdbg1.c1
-rw-r--r--Tests/ExportImport/Export/testLib4libopt.c14
-rw-r--r--Tests/ExportImport/Export/testLib4libopt1.c1
-rw-r--r--Tests/ExportImport/Import/CMakeLists.txt2
-rw-r--r--Tests/ExportImport/Import/imp_testExe1.c12
-rw-r--r--Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt7
-rw-r--r--Tests/ReturnTest/CMakeLists.txt8
-rw-r--r--Tests/ReturnTest/include_return.cmake3
-rw-r--r--Tests/SimpleInstall/CMakeLists.txt6
-rw-r--r--Tests/SimpleInstallS2/CMakeLists.txt6
110 files changed, 1998 insertions, 817 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 911f2ccdc5..899a78eef4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -354,7 +354,7 @@ ENDMACRO (CMAKE_BUILD_UTILITIES)
SET(CMake_VERSION_MAJOR 2)
SET(CMake_VERSION_MINOR 6)
SET(CMake_VERSION_PATCH 2)
-SET(CMake_VERSION_RC 1)
+SET(CMake_VERSION_RC 2)
# CVS versions are odd, if this is an odd minor version
# then set the CMake_VERSION_DATE variable
IF("${CMake_VERSION_MINOR}" MATCHES "[13579]$")
diff --git a/ChangeLog.manual b/ChangeLog.manual
index da3dbaf23c..055e630667 100644
--- a/ChangeLog.manual
+++ b/ChangeLog.manual
@@ -1,9 +1,51 @@
+Changes in CMake 2.6.2 RC 2
+- allow tool chains to limit object path length
+- add info.plist to frameworks
+- better preservation of user link lines
+- add a get command for cmake policies
+- support for imported libraries of unknown type
+- support link interface in target_link_libraries
+- Do not hang when select lies
+- .m compiled with gcc and g++ on mac
+- Fix issue when application bundle dir is removed cmake
+ needs to re-run automatically
+- Report an error when configure has one error
+- Fix bug where -E commands stole command line options
+- Fix infinite recursion bug with try-compile and change of compilers
+- Fix delete and backspace in ccmake
+- Fix coverage not to follow symlinks
+- Add more possible languages for NSIS in cpack
+- FindQt4.cmake fix bug #7433, add documentation that
+ directories also can be specified to update the translation files.
+- Add standard arg handling to FindPHP4.cmake
+- Add X11R6 to search path for FindOpenGL
+- update cmake-syntax.vim to have more keywords
+- BUG: fix #7477, set VERBOSE=1 in the kdevelop setting for
+ the environment, not together with the make executable
+- UsePkgConfig.cmake - clean up, add a status message in case
+ pkgconfig didn't find the package, sync with kde
+- FindX11 look in more places
+- FindTIFF look for more names
+- FindQt3, make sure qt4 is not found and some style stuff
+- FindPNG add more names of linpng (sync with the KDE version)
+- FindKDE3/KDE4 sanity checks on qt versions found
+- FindLibXMl2 also search for xmllint, which comes with libxml2
+ (sync with FindLibXml2.cmake from KDE)
+- Fix sizeof, and other compiler INFO string checks with
+ GNU linker's --gc-sections
+- Fix bogus dependency on executable targets when a linked library
+ happended to match the name of an executable target
+- Improve readability of circular depends error
+- Fix crash on circular target dependencies
+- find_package now knows about lib64 paths
+- Fix gentoo elf security issue with RPATH and RUNPATH
+
Changes in CMake 2.6.2 RC 1
- Fix abort in eclipse generator with empty EXECUTABLE_OUTPUT_PATH
- Fix FindKDE3.cmake syntax error
- Fix custom command output by relative path not always working
- Fix bug, Do not convert RPATH entries to full path.
-- Allow for "$ORIGIN" into the RPATH
+- Allow for "$ORIGIN" into the RPATH>
- Allow for static libraries with lots of objects using archive append
- Fix documentation for FindImageMagick.cmake
- Fix link error with MS compiler and comdef
diff --git a/Docs/cmake-syntax.vim b/Docs/cmake-syntax.vim
index 17c2b3285d..80b348eeff 100644
--- a/Docs/cmake-syntax.vim
+++ b/Docs/cmake-syntax.vim
@@ -41,7 +41,7 @@ syn region cmakeString start=/"/ end=/"/
syn region cmakeArguments start=/(/ end=/)/
\ contains=ALLBUT,cmakeArguments,cmakeTodo
syn keyword cmakeSystemVariables
- \ WIN32 UNIX APPLE CYGWIN BORLAND MINGW MSVC MSVC_IDE MSVC60 MSVC70 MSVC71 MSVC80
+ \ WIN32 UNIX APPLE CYGWIN BORLAND MINGW MSVC MSVC_IDE MSVC60 MSVC70 MSVC71 MSVC80 MSVC90
syn keyword cmakeOperators
\ ABSOLUTE AND BOOL CACHE COMMAND DEFINED DOC EQUAL EXISTS EXT FALSE GREATER INTERNAL LESS MATCHES NAME NAMES NAME_WE NOT OFF ON OR PATH PATHS PROGRAM STREQUAL STRGREATER STRING STRLESS TRUE
\ contained
@@ -50,7 +50,7 @@ syn keyword cmakeDeprecated ABSTRACT_FILES BUILD_NAME SOURCE_FILES SOURCE_FILES_
" The keywords are generated as: cmake --help-command-list | tr "\n" " "
syn keyword cmakeStatement
- \ ADD_CUSTOM_COMMAND ADD_CUSTOM_TARGET ADD_DEFINITIONS ADD_DEPENDENCIES ADD_EXECUTABLE ADD_LIBRARY ADD_SUBDIRECTORY ADD_TEST AUX_SOURCE_DIRECTORY BUILD_COMMAND BUILD_NAME CMAKE_MINIMUM_REQUIRED CONFIGURE_FILE CREATE_TEST_SOURCELIST ELSE ELSEIF ENABLE_LANGUAGE ENABLE_TESTING ENDFOREACH ENDFUNCTION ENDIF ENDMACRO ENDWHILE EXEC_PROGRAM EXECUTE_PROCESS EXPORT_LIBRARY_DEPENDENCIES FILE FIND_FILE FIND_LIBRARY FIND_PACKAGE FIND_PATH FIND_PROGRAM FLTK_WRAP_UI FOREACH FUNCTION GET_CMAKE_PROPERTY GET_DIRECTORY_PROPERTY GET_FILENAME_COMPONENT GET_SOURCE_FILE_PROPERTY GET_TARGET_PROPERTY GET_TEST_PROPERTY IF INCLUDE INCLUDE_DIRECTORIES INCLUDE_EXTERNAL_MSPROJECT INCLUDE_REGULAR_EXPRESSION INSTALL INSTALL_FILES INSTALL_PROGRAMS INSTALL_TARGETS LINK_DIRECTORIES LINK_LIBRARIES LIST LOAD_CACHE LOAD_COMMAND MACRO MAKE_DIRECTORY MARK_AS_ADVANCED MATH MESSAGE OPTION OUTPUT_REQUIRED_FILES PROJECT QT_WRAP_CPP QT_WRAP_UI REMOVE REMOVE_DEFINITIONS SEPARATE_ARGUMENTS SET SET_DIRECTORY_PROPERTIES SET_SOURCE_FILES_PROPERTIES SET_TARGET_PROPERTIES SET_TESTS_PROPERTIES SITE_NAME SOURCE_GROUP STRING SUBDIR_DEPENDS SUBDIRS TARGET_LINK_LIBRARIES TRY_COMPILE TRY_RUN USE_MANGLED_MESA UTILITY_SOURCE VARIABLE_REQUIRES VTK_MAKE_INSTANTIATOR VTK_WRAP_JAVA VTK_WRAP_PYTHON VTK_WRAP_TCL WHILE WRITE_FILE
+ \ ADD_CUSTOM_COMMAND ADD_CUSTOM_TARGET ADD_DEFINITIONS ADD_DEPENDENCIES ADD_EXECUTABLE ADD_LIBRARY ADD_SUBDIRECTORY ADD_TEST AUX_SOURCE_DIRECTORY BUILD_COMMAND BUILD_NAME CMAKE_MINIMUM_REQUIRED CONFIGURE_FILE CREATE_TEST_SOURCELIST ELSE ELSEIF ENABLE_LANGUAGE ENABLE_TESTING ENDFOREACH ENDFUNCTION ENDIF ENDMACRO ENDWHILE EXEC_PROGRAM EXECUTE_PROCESS EXPORT_LIBRARY_DEPENDENCIES FILE FIND_FILE FIND_LIBRARY FIND_PACKAGE FIND_PATH FIND_PROGRAM FLTK_WRAP_UI FOREACH FUNCTION GET_CMAKE_PROPERTY GET_DIRECTORY_PROPERTY GET_FILENAME_COMPONENT GET_SOURCE_FILE_PROPERTY GET_TARGET_PROPERTY GET_TEST_PROPERTY IF INCLUDE INCLUDE_DIRECTORIES INCLUDE_EXTERNAL_MSPROJECT INCLUDE_REGULAR_EXPRESSION INSTALL INSTALL_FILES INSTALL_PROGRAMS INSTALL_TARGETS LINK_DIRECTORIES LINK_LIBRARIES LIST LOAD_CACHE LOAD_COMMAND MACRO MAKE_DIRECTORY MARK_AS_ADVANCED MATH MESSAGE OPTION OUTPUT_REQUIRED_FILES PROJECT QT_WRAP_CPP QT_WRAP_UI REMOVE REMOVE_DEFINITIONS SEPARATE_ARGUMENTS SET SET_DIRECTORY_PROPERTIES SET_SOURCE_FILES_PROPERTIES SET_TARGET_PROPERTIES SET_TESTS_PROPERTIES SITE_NAME SOURCE_GROUP STRING SUBDIR_DEPENDS SUBDIRS TARGET_LINK_LIBRARIES TRY_COMPILE TRY_RUN UNSET USE_MANGLED_MESA UTILITY_SOURCE VARIABLE_REQUIRES VTK_MAKE_INSTANTIATOR VTK_WRAP_JAVA VTK_WRAP_PYTHON VTK_WRAP_TCL WHILE WRITE_FILE
\ nextgroup=cmakeArguments
syn keyword cmakeTodo
\ TODO FIXME XXX
diff --git a/Modules/CMakeCCompilerABI.c b/Modules/CMakeCCompilerABI.c
index f73e7fcc34..e6a07f4c4c 100644
--- a/Modules/CMakeCCompilerABI.c
+++ b/Modules/CMakeCCompilerABI.c
@@ -12,17 +12,17 @@
/*--------------------------------------------------------------------------*/
-/* Make sure the information strings are referenced. */
-#define REQUIRE(x) (&x[0] != &require)
-
-int main()
+#ifdef __CLASSIC_C__
+int main(argc, argv) int argc; char *argv[];
+#else
+int main(int argc, char *argv[])
+#endif
{
- const char require = 0;
- return
- (
- REQUIRE(info_sizeof_dptr)
+ int require = 0;
+ require += info_sizeof_dptr[argc];
#if defined(ABI_ID)
- && REQUIRE(info_abi)
+ require += info_abi[argc];
#endif
- );
+ (void)argv;
+ return require;
}
diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in
index ecbe431b70..35d7df77a8 100644
--- a/Modules/CMakeCCompilerId.c.in
+++ b/Modules/CMakeCCompilerId.c.in
@@ -2,15 +2,9 @@
# error "A C++ compiler has been selected for C."
#endif
-/* Provide main() so the program can link. */
#if defined(__18CXX)
# define ID_VOID_MAIN
#endif
-#ifdef ID_VOID_MAIN
-void main() {}
-#else
-int main() { return 0; }
-#endif
#if defined(__INTEL_COMPILER) || defined(__ICC)
# define COMPILER_ID "Intel"
@@ -82,3 +76,18 @@ int main() { return 0; }
char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
@CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef ID_VOID_MAIN
+void main() {}
+#else
+int main(int argc, char* argv[])
+{
+ int require = 0;
+ require += info_compiler[argc];
+ require += info_platform[argc];
+ (void)argv;
+ return require;
+}
+#endif
diff --git a/Modules/CMakeCXXCompilerABI.cpp b/Modules/CMakeCXXCompilerABI.cpp
index 7fb3618870..c9b0440b8e 100644
--- a/Modules/CMakeCXXCompilerABI.cpp
+++ b/Modules/CMakeCXXCompilerABI.cpp
@@ -8,17 +8,13 @@
/*--------------------------------------------------------------------------*/
-/* Make sure the information strings are referenced. */
-#define REQUIRE(x) (&x[0] != &require)
-
-int main()
+int main(int argc, char* argv[])
{
- const char require = 0;
- return
- (
- REQUIRE(info_sizeof_dptr)
+ int require = 0;
+ require += info_sizeof_dptr[argc];
#if defined(ABI_ID)
- && REQUIRE(info_abi)
+ require += info_abi[argc];
#endif
- );
+ (void)argv;
+ return require;
}
diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in
index 060c7e9c16..fa2178c0b9 100644
--- a/Modules/CMakeCXXCompilerId.cpp.in
+++ b/Modules/CMakeCXXCompilerId.cpp.in
@@ -5,9 +5,6 @@
# error "A C compiler has been selected for C++."
#endif
-/* Provide main() so the program can link. */
-int main() { return 0; }
-
#if defined(__COMO__)
# define COMPILER_ID "Comeau"
@@ -70,3 +67,14 @@ int main() { return 0; }
char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
@CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@
+
+/*--------------------------------------------------------------------------*/
+
+int main(int argc, char* argv[])
+{
+ int require = 0;
+ require += info_compiler[argc];
+ require += info_platform[argc];
+ (void)argv;
+ return require;
+}
diff --git a/Modules/CheckTypeSizeC.c.in b/Modules/CheckTypeSizeC.c.in
index c25b69dcbc..8bcf1a0cc4 100644
--- a/Modules/CheckTypeSizeC.c.in
+++ b/Modules/CheckTypeSizeC.c.in
@@ -29,15 +29,16 @@ const char info_sizeof[] = {'I', 'N', 'F', 'O', ':', 's','i','z','e','o','f','[
('0' + (SIZE % 10)),
']','\0'};
-
#ifdef __CLASSIC_C__
-int main(){
- int ac;
- char*av[];
+int main(argc, argv) int argc; char *argv[];
#else
-int main(int ac, char*av[]){
+int main(int argc, char *argv[])
#endif
- return (&info_sizeof[0] != &info_sizeof[0]);
+{
+ int require = 0;
+ require += info_sizeof[argc];
+ (void)argv;
+ return require;
}
#else /* CHECK_TYPE_SIZE_TYPE */
diff --git a/Modules/FindKDE3.cmake b/Modules/FindKDE3.cmake
index 3281f66dad..0cf8b2404c 100644
--- a/Modules/FindKDE3.cmake
+++ b/Modules/FindKDE3.cmake
@@ -67,6 +67,18 @@ IF(NOT UNIX AND KDE3_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Compiling KDE3 applications and libraries under Windows is not supported")
ENDIF(NOT UNIX AND KDE3_FIND_REQUIRED)
+# If Qt4 has already been found, fail.
+IF(QT4_FOUND)
+ IF(KDE3_FIND_REQUIRED)
+ MESSAGE( FATAL_ERROR "KDE3/Qt3 and Qt4 cannot be used together in one project.")
+ ELSE(KDE3_FIND_REQUIRED)
+ IF(NOT KDE3_FIND_QUIETLY)
+ MESSAGE( STATUS "KDE3/Qt3 and Qt4 cannot be used together in one project.")
+ ENDIF(NOT KDE3_FIND_QUIETLY)
+ RETURN()
+ ENDIF(KDE3_FIND_REQUIRED)
+ENDIF(QT4_FOUND)
+
SET(QT_MT_REQUIRED TRUE)
#SET(QT_MIN_VERSION "3.0.0")
diff --git a/Modules/FindKDE4.cmake b/Modules/FindKDE4.cmake
index 89924680f8..e6d0488bf3 100644
--- a/Modules/FindKDE4.cmake
+++ b/Modules/FindKDE4.cmake
@@ -9,6 +9,18 @@
#
# Author: Alexander Neundorf <neundorf@kde.org>
+# If Qt3 has already been found, fail.
+IF(QT_QT_LIBRARY)
+ IF(KDE4_FIND_REQUIRED)
+ MESSAGE( FATAL_ERROR "KDE4/Qt4 and Qt3 cannot be used together in one project.")
+ ELSE(KDE4_FIND_REQUIRED)
+ IF(NOT KDE4_FIND_QUIETLY)
+ MESSAGE( STATUS "KDE4/Qt4 and Qt3 cannot be used together in one project.")
+ ENDIF(NOT KDE_FIND_QUIETLY)
+ RETURN()
+ ENDIF(KDE4_FIND_REQUIRED)
+ENDIF(QT_QT_LIBRARY)
+
FILE(TO_CMAKE_PATH "$ENV{KDEDIRS}" _KDEDIRS)
# when cross compiling, searching kde4-config in order to run it later on
diff --git a/Modules/FindLibXml2.cmake b/Modules/FindLibXml2.cmake
index 0de0586ec8..42c554ce3b 100644
--- a/Modules/FindLibXml2.cmake
+++ b/Modules/FindLibXml2.cmake
@@ -1,10 +1,11 @@
# - Try to find LibXml2
# Once done this will define
#
-# LIBXML2_FOUND - system has LibXml2
-# LIBXML2_INCLUDE_DIR - the LibXml2 include directory
-# LIBXML2_LIBRARIES - the libraries needed to use LibXml2
+# LIBXML2_FOUND - System has LibXml2
+# LIBXML2_INCLUDE_DIR - The LibXml2 include directory
+# LIBXML2_LIBRARIES - The libraries needed to use LibXml2
# LIBXML2_DEFINITIONS - Compiler switches required for using LibXml2
+# LIBXML2_XMLLINT_EXECUTABLE - The XML checking tool xmllint coming with LibXml2
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
#
@@ -36,11 +37,15 @@ FIND_LIBRARY(LIBXML2_LIBRARIES NAMES xml2 libxml2
${_LibXml2LinkDir}
)
+FIND_PROGRAM(LIBXML2_XMLLINT_EXECUTABLE xmllint)
+# for backwards compat. with KDE 4.0.x:
+SET(XMLLINT_EXECUTABLE "${LIBXML2_XMLLINT_EXECUTABLE}")
+
INCLUDE(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBXML2_FOUND to TRUE if
# all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR)
-MARK_AS_ADVANCED(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARIES)
+MARK_AS_ADVANCED(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARIES LIBXML2_XMLLINT_EXECUTABLE)
diff --git a/Modules/FindLua50.cmake b/Modules/FindLua50.cmake
index a5e8c51656..6da7aa1348 100644
--- a/Modules/FindLua50.cmake
+++ b/Modules/FindLua50.cmake
@@ -1,7 +1,7 @@
# Locate Lua library
# This module defines
+# LUA50_FOUND, if false, do not try to link to Lua
# LUA_LIBRARIES, both lua and lualib
-# LUA_FOUND, if false, do not try to link to Lua
# LUA_INCLUDE_DIR, where to find lua.h and lualib.h (and probably lauxlib.h)
#
# Note that the expected include convention is
diff --git a/Modules/FindLua51.cmake b/Modules/FindLua51.cmake
index 04d7db62d4..5f50ec2ca2 100644
--- a/Modules/FindLua51.cmake
+++ b/Modules/FindLua51.cmake
@@ -1,7 +1,7 @@
# Locate Lua library
# This module defines
+# LUA51_FOUND, if false, do not try to link to Lua
# LUA_LIBRARIES
-# LUA_FOUND, if false, do not try to link to Lua
# LUA_INCLUDE_DIR, where to find lua.h
#
# Note that the expected include convention is
diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake
index edea06af5d..1c2648ab08 100644
--- a/Modules/FindOpenGL.cmake
+++ b/Modules/FindOpenGL.cmake
@@ -57,20 +57,20 @@ ELSE (WIN32)
FIND_PATH(OPENGL_INCLUDE_DIR GL/gl.h
/usr/share/doc/NVIDIA_GLX-1.0/include
/usr/openwin/share/include
- /opt/graphics/OpenGL/include
+ /opt/graphics/OpenGL/include /usr/X11R6/include
)
FIND_PATH(OPENGL_xmesa_INCLUDE_DIR GL/xmesa.h
/usr/share/doc/NVIDIA_GLX-1.0/include
/usr/openwin/share/include
- /opt/graphics/OpenGL/include
+ /opt/graphics/OpenGL/include /usr/X11R6/include
)
FIND_LIBRARY(OPENGL_gl_LIBRARY
NAMES GL MesaGL
PATHS /opt/graphics/OpenGL/lib
/usr/openwin/lib
- /usr/shlib
+ /usr/shlib /usr/X11R6/lib
)
# On Unix OpenGL most certainly always requires X11.
@@ -94,7 +94,7 @@ ELSE (WIN32)
PATHS ${OPENGL_gl_LIBRARY}
/opt/graphics/OpenGL/lib
/usr/openwin/lib
- /usr/shlib
+ /usr/shlib /usr/X11R6/lib
)
ENDIF(APPLE)
diff --git a/Modules/FindPHP4.cmake b/Modules/FindPHP4.cmake
index d4ccd1f008..185d6287d8 100644
--- a/Modules/FindPHP4.cmake
+++ b/Modules/FindPHP4.cmake
@@ -68,3 +68,5 @@ IF(APPLE)
ENDFOREACH(symbol)
ENDIF(APPLE)
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(PHP4 DEFAULT_MSG PHP4_EXECUTABLE PHP4_INCLUDE_PATH)
diff --git a/Modules/FindPNG.cmake b/Modules/FindPNG.cmake
index fa1bcd3efb..d64b074bb6 100644
--- a/Modules/FindPNG.cmake
+++ b/Modules/FindPNG.cmake
@@ -16,7 +16,7 @@ IF(ZLIB_FOUND)
/usr/local/include/libpng # OpenBSD
)
- SET(PNG_NAMES ${PNG_NAMES} png libpng)
+ SET(PNG_NAMES ${PNG_NAMES} png libpng png12 libpng12)
FIND_LIBRARY(PNG_LIBRARY NAMES ${PNG_NAMES} )
IF (PNG_LIBRARY AND PNG_PNG_INCLUDE_DIR)
diff --git a/Modules/FindQt3.cmake b/Modules/FindQt3.cmake
index 2ad6fec9cb..dcfaad30c2 100644
--- a/Modules/FindQt3.cmake
+++ b/Modules/FindQt3.cmake
@@ -20,6 +20,19 @@
# QT_WRAP_CPP, set true if QT_MOC_EXECUTABLE is found
# QT_WRAP_UI set true if QT_UIC_EXECUTABLE is found
+# If Qt4 has already been found, fail.
+IF(QT4_FOUND)
+ IF(Qt3_FIND_REQUIRED)
+ MESSAGE( FATAL_ERROR "Qt3 and Qt4 cannot be used together in one project.")
+ ELSE(Qt3_FIND_REQUIRED)
+ IF(NOT Qt3_FIND_QUIETLY)
+ MESSAGE( STATUS "Qt3 and Qt4 cannot be used together in one project.")
+ ENDIF(NOT Qt3_FIND_QUIETLY)
+ RETURN()
+ ENDIF(Qt3_FIND_REQUIRED)
+ENDIF(QT4_FOUND)
+
+
FILE(GLOB GLOB_PATHS_BIN /usr/lib/qt-3*/bin/)
FIND_PATH(QT_INCLUDE_DIR qt.h
"[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.1;InstallDir]/include/Qt"
@@ -34,13 +47,12 @@ FIND_PATH(QT_INCLUDE_DIR qt.h
/usr/share/qt3/include
C:/Progra~1/qt/include
/usr/include/qt3
- /usr/X11R6/include
)
# if qglobal.h is not in the qt_include_dir then set
# QT_INCLUDE_DIR to NOTFOUND
IF(NOT EXISTS ${QT_INCLUDE_DIR}/qglobal.h)
- SET(QT_INCLUDE_DIR QT_INCLUDE_DIR-NOTFOUND CACHE PATH "path to qt3 include directory" FORCE)
+ SET(QT_INCLUDE_DIR QT_INCLUDE_DIR-NOTFOUND CACHE PATH "path to Qt3 include directory" FORCE)
ENDIF(NOT EXISTS ${QT_INCLUDE_DIR}/qglobal.h)
IF(QT_INCLUDE_DIR)
@@ -52,7 +64,6 @@ IF(QT_INCLUDE_DIR)
# Under windows the qt library (MSVC) has the format qt-mtXYZ where XYZ is the
# version X.Y.Z, so we need to remove the dots from version
STRING(REGEX REPLACE "\\." "" qt_version_str_lib "${qt_version_str}")
-ELSE(QT_INCLUDE_DIR)
ENDIF(QT_INCLUDE_DIR)
FILE(GLOB GLOB_PATHS_LIB /usr/lib/qt-3*/lib/)
@@ -73,7 +84,6 @@ IF (QT_MT_REQUIRED)
/usr/lib/qt3/lib64
/usr/share/qt3/lib
C:/Progra~1/qt/lib
- /usr/X11R6/lib
)
ELSE (QT_MT_REQUIRED)
@@ -94,14 +104,9 @@ ELSE (QT_MT_REQUIRED)
/usr/lib/qt3/lib64
/usr/share/qt3/lib
C:/Progra~1/qt/lib
- /usr/X11R6/lib
)
ENDIF (QT_MT_REQUIRED)
-IF(QT_QT_LIBRARY)
-ELSE(QT_QT_LIBRARY)
-ENDIF(QT_QT_LIBRARY)
-
FIND_LIBRARY(QT_QASSISTANTCLIENT_LIBRARY
NAMES qassistantclient
@@ -116,7 +121,6 @@ FIND_LIBRARY(QT_QASSISTANTCLIENT_LIBRARY
/usr/lib/qt3/lib64
/usr/share/qt3/lib
C:/Progra~1/qt/lib
- /usr/X11R6/lib
)
# qt 3 should prefer QTDIR over the PATH
@@ -140,7 +144,6 @@ FIND_PROGRAM(QT_MOC_EXECUTABLE
IF(QT_MOC_EXECUTABLE)
SET ( QT_WRAP_CPP "YES")
-ELSE(QT_MOC_EXECUTABLE)
ENDIF(QT_MOC_EXECUTABLE)
# qt 3 should prefer QTDIR over the PATH
@@ -162,7 +165,6 @@ FIND_PROGRAM(QT_UIC_EXECUTABLE uic
IF(QT_UIC_EXECUTABLE)
SET ( QT_WRAP_UI "YES")
-ELSE(QT_UIC_EXECUTABLE)
ENDIF(QT_UIC_EXECUTABLE)
IF (WIN32)
@@ -194,28 +196,28 @@ IF (QT_MIN_VERSION)
STRING(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" req_qt_patch_vers "${QT_MIN_VERSION}")
# req = "6.5.4", qt = "3.2.1"
- macro(error_message msg)
+ MACRO(error_message msg)
IF(QT3_REQUIRED)
MESSAGE( FATAL_ERROR ${msg})
ELSE(QT3_REQUIRED)
MESSAGE( STATUS ${msg})
ENDIF(QT3_REQUIRED)
- endmacro(error_message)
+ ENDMACRO(error_message)
IF (req_qt_major_vers GREATER qt_major_vers) # (6 > 3) ?
- error_message( "Qt major version not matched (required: ${QT_MIN_VERSION}, found: ${qt_version_str})") # yes
+ ERROR_MESSAGE( "Qt major version not matched (required: ${QT_MIN_VERSION}, found: ${qt_version_str})") # yes
ELSE (req_qt_major_vers GREATER qt_major_vers) # no
IF (req_qt_major_vers LESS qt_major_vers) # (6 < 3) ?
SET( QT_VERSION_BIG_ENOUGH "YES" ) # yes
ELSE (req_qt_major_vers LESS qt_major_vers) # ( 6==3) ?
IF (req_qt_minor_vers GREATER qt_minor_vers) # (5>2) ?
- error_message( "Qt minor version not matched (required: ${QT_MIN_VERSION}, found: ${qt_version_str})") # yes
+ ERROR_MESSAGE( "Qt minor version not matched (required: ${QT_MIN_VERSION}, found: ${qt_version_str})") # yes
ELSE (req_qt_minor_vers GREATER qt_minor_vers) # no
IF (req_qt_minor_vers LESS qt_minor_vers) # (5<2) ?
SET( QT_VERSION_BIG_ENOUGH "YES" ) # yes
ELSE (req_qt_minor_vers LESS qt_minor_vers) # (5==2)
IF (req_qt_patch_vers GREATER qt_patch_vers) # (4>1) ?
- error_message( "Qt patch level not matched (required: ${QT_MIN_VERSION}, found: ${qt_version_str})") # yes
+ ERROR_MESSAGE( "Qt patch level not matched (required: ${QT_MIN_VERSION}, found: ${qt_version_str})") # yes
ELSE (req_qt_patch_vers GREATER qt_patch_vers) # (4>1) ?
SET( QT_VERSION_BIG_ENOUGH "YES" ) # yes
ENDIF (req_qt_patch_vers GREATER qt_patch_vers) # (4>1) ?
@@ -226,11 +228,9 @@ IF (QT_MIN_VERSION)
ENDIF (QT_MIN_VERSION)
# if the include a library are found then we have it
-IF(QT_INCLUDE_DIR)
- IF(QT_QT_LIBRARY)
- SET( QT_FOUND "YES" )
- ENDIF(QT_QT_LIBRARY)
-ENDIF(QT_INCLUDE_DIR)
+IF(QT_INCLUDE_DIR AND QT_QT_LIBRARY)
+ SET( QT_FOUND "YES" )
+ENDIF(QT_INCLUDE_DIR AND QT_QT_LIBRARY)
IF(QT_FOUND)
SET( QT_LIBRARIES ${QT_LIBRARIES} ${QT_QT_LIBRARY} )
@@ -293,18 +293,14 @@ IF("${QTVERSION_MOC}" MATCHES ".* 3..*")
ENDIF("${QTVERSION_MOC}" MATCHES ".* 3..*")
SET(QT_WRAP_CPP FALSE)
-IF (QT_MOC_EXECUTABLE)
- IF(_QT_MOC_VERSION_3)
- SET ( QT_WRAP_CPP TRUE)
- ENDIF(_QT_MOC_VERSION_3)
-ENDIF (QT_MOC_EXECUTABLE)
+IF (QT_MOC_EXECUTABLE AND _QT_MOC_VERSION_3)
+ SET ( QT_WRAP_CPP TRUE)
+ENDIF (QT_MOC_EXECUTABLE AND _QT_MOC_VERSION_3)
SET(QT_WRAP_UI FALSE)
-IF (QT_UIC_EXECUTABLE)
- IF(_QT_UIC_VERSION_3)
- SET ( QT_WRAP_UI TRUE)
- ENDIF(_QT_UIC_VERSION_3)
-ENDIF (QT_UIC_EXECUTABLE)
+IF (QT_UIC_EXECUTABLE AND _QT_UIC_VERSION_3)
+ SET ( QT_WRAP_UI TRUE)
+ENDIF (QT_UIC_EXECUTABLE AND _QT_UIC_VERSION_3)
MARK_AS_ADVANCED(
QT_INCLUDE_DIR
diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake
index da8594ca81..626232ff9e 100644
--- a/Modules/FindQt4.cmake
+++ b/Modules/FindQt4.cmake
@@ -48,8 +48,9 @@
#
# macro QT4_WRAP_CPP(outfiles inputfile ... OPTIONS ...)
# create moc code from a list of files containing Qt class with
-# the Q_OBJECT declaration. Options may be given to moc, such as those found
-# when executing "moc -help"
+# the Q_OBJECT declaration. Per-direcotry preprocessor definitions
+# are also added. Options may be given to moc, such as those found
+# when executing "moc -help".
#
# macro QT4_WRAP_UI(outfiles inputfile ... OPTIONS ...)
# create code from a list of Qt designer ui files.
@@ -102,11 +103,11 @@
# interface file is constructed from the basename of the header with
# the suffix .xml appended.
#
-# macro QT4_CREATE_TRANSLATION( qm_files sources ... ts_files ... )
+# macro QT4_CREATE_TRANSLATION( qm_files directories ... sources ... ts_files ... )
# out: qm_files
-# in: sources ts_files
+# in: directories sources ts_files
# generates commands to create .ts (vie lupdate) and .qm
-# (via lrelease) - files from sources. The ts files are
+# (via lrelease) - files from directories and/or sources. The ts files are
# created and/or updated in the source tree (unless given with full paths).
# The qm files are generated in the build tree.
# Updating the translations can be done by adding the qm_files
@@ -256,6 +257,19 @@
# (They make no sense in Qt4)
# QT_QT_LIBRARY Qt-Library is now split
+# If Qt3 has already been found, fail.
+IF(QT_QT_LIBRARY)
+ IF(Qt4_FIND_REQUIRED)
+ MESSAGE( FATAL_ERROR "Qt3 and Qt4 cannot be used together in one project.")
+ ELSE(Qt4_FIND_REQUIRED)
+ IF(NOT Qt4_FIND_QUIETLY)
+ MESSAGE( STATUS "Qt3 and Qt4 cannot be used together in one project.")
+ ENDIF(NOT Qt4_FIND_QUIETLY)
+ RETURN()
+ ENDIF(Qt4_FIND_REQUIRED)
+ENDIF(QT_QT_LIBRARY)
+
+
INCLUDE(CheckSymbolExists)
INCLUDE(MacroAddFileDependencies)
@@ -474,9 +488,9 @@ IF (QT4_QMAKE_FOUND)
ENDIF( QT_QTCORE_INCLUDE_DIR AND NOT QT_INCLUDE_DIR)
IF( NOT QT_INCLUDE_DIR)
- IF( NOT Qt4_FIND_QUIETLY AND Qt4_FIND_REQUIRED)
+ IF(Qt4_FIND_REQUIRED)
MESSAGE( FATAL_ERROR "Could NOT find QtGlobal header")
- ENDIF( NOT Qt4_FIND_QUIETLY AND Qt4_FIND_REQUIRED)
+ ENDIF(Qt4_FIND_REQUIRED)
ENDIF( NOT QT_INCLUDE_DIR)
#############################################
@@ -512,10 +526,6 @@ IF (QT4_QMAKE_FOUND)
#
#############################################
- IF (QT_USE_FRAMEWORKS)
- SET(QT_DEFINITIONS ${QT_DEFINITIONS} -F${QT_LIBRARY_DIR} -L${QT_LIBRARY_DIR} )
- ENDIF (QT_USE_FRAMEWORKS)
-
# Set QT_QT3SUPPORT_INCLUDE_DIR
FIND_PATH(QT_QT3SUPPORT_INCLUDE_DIR Qt3Support
PATHS
@@ -771,9 +781,9 @@ IF (QT4_QMAKE_FOUND)
ENDIF(EXISTS ${QT_LIBRARY_DIR}/libqtmain.a)
ENDIF(QT_LIBRARY_DIR AND MSVC)
- IF( NOT Qt4_FIND_QUIETLY AND Qt4_FIND_REQUIRED)
+ IF(Qt4_FIND_REQUIRED)
MESSAGE( FATAL_ERROR "Could NOT find QtCore. Check ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log for more details.")
- ENDIF( NOT Qt4_FIND_QUIETLY AND Qt4_FIND_REQUIRED)
+ ENDIF(Qt4_FIND_REQUIRED)
ENDIF( NOT QT_QTCORE_LIBRARY_DEBUG AND NOT QT_QTCORE_LIBRARY_RELEASE )
# Set QT_QTASSISTANT_LIBRARY
@@ -1028,18 +1038,27 @@ IF (QT4_QMAKE_FOUND)
SET(${outfile} ${outpath}/${prefix}${_outfile}.${ext})
ENDMACRO (QT4_MAKE_OUTPUT_FILE )
- MACRO (QT4_GET_MOC_INC_DIRS _moc_INC_DIRS)
- SET(${_moc_INC_DIRS})
+ MACRO (QT4_GET_MOC_FLAGS _moc_flags)
+ SET(${_moc_flags})
GET_DIRECTORY_PROPERTY(_inc_DIRS INCLUDE_DIRECTORIES)
FOREACH(_current ${_inc_DIRS})
- SET(${_moc_INC_DIRS} ${${_moc_INC_DIRS}} "-I" ${_current})
+ SET(${_moc_flags} ${${_moc_flags}} "-I${_current}")
ENDFOREACH(_current ${_inc_DIRS})
+
+ GET_DIRECTORY_PROPERTY(_defines COMPILE_DEFINITIONS)
+ FOREACH(_current ${_defines})
+ SET(${_moc_flags} ${${_moc_flags}} "-D${_current}")
+ ENDFOREACH(_current ${_defines})
+
+ IF(Q_WS_WIN)
+ SET(${_moc_flags} ${${_moc_flags}} -DWIN32)
+ ENDIF(Q_WS_WIN)
- ENDMACRO(QT4_GET_MOC_INC_DIRS)
+ ENDMACRO(QT4_GET_MOC_FLAGS)
# helper macro to set up a moc rule
- MACRO (QT4_CREATE_MOC_COMMAND infile outfile moc_includes moc_options)
+ MACRO (QT4_CREATE_MOC_COMMAND infile outfile moc_flags moc_options)
# For Windows, create a parameters file to work around command line length limit
IF (WIN32)
# Pass the parameters in a file. Set the working directory to
@@ -1053,7 +1072,7 @@ IF (QT4_QMAKE_FOUND)
SET(_moc_working_dir WORKING_DIRECTORY ${_moc_outfile_dir})
ENDIF(_moc_outfile_dir)
SET (_moc_parameters_file ${outfile}_parameters)
- SET (_moc_parameters ${moc_includes} ${moc_options} -o "${outfile}" "${infile}")
+ SET (_moc_parameters ${moc_flags} ${moc_options} -o "${outfile}" "${infile}")
FILE (REMOVE ${_moc_parameters_file})
FOREACH(arg ${_moc_parameters})
FILE (APPEND ${_moc_parameters_file} "${arg}\n")
@@ -1066,16 +1085,16 @@ IF (QT4_QMAKE_FOUND)
ELSE (WIN32)
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${QT_MOC_EXECUTABLE}
- ARGS ${moc_includes} ${moc_options} -o ${outfile} ${infile}
+ ARGS ${moc_flags} ${moc_options} -o ${outfile} ${infile}
DEPENDS ${infile})
ENDIF (WIN32)
ENDMACRO (QT4_CREATE_MOC_COMMAND)
MACRO (QT4_GENERATE_MOC infile outfile )
- QT4_GET_MOC_INC_DIRS(moc_includes)
+ QT4_GET_MOC_FLAGS(moc_flags)
GET_FILENAME_COMPONENT(abs_infile ${infile} ABSOLUTE)
- QT4_CREATE_MOC_COMMAND(${abs_infile} ${outfile} "${moc_includes}" "")
+ QT4_CREATE_MOC_COMMAND(${abs_infile} ${outfile} "${moc_flags}" "")
SET_SOURCE_FILES_PROPERTIES(${outfile} PROPERTIES SKIP_AUTOMOC TRUE) # dont run automoc on this file
ENDMACRO (QT4_GENERATE_MOC)
@@ -1084,13 +1103,13 @@ IF (QT4_QMAKE_FOUND)
MACRO (QT4_WRAP_CPP outfiles )
# get include dirs
- QT4_GET_MOC_INC_DIRS(moc_includes)
+ QT4_GET_MOC_FLAGS(moc_flags)
QT4_EXTRACT_OPTIONS(moc_files moc_options ${ARGN})
FOREACH (it ${moc_files})
GET_FILENAME_COMPONENT(it ${it} ABSOLUTE)
QT4_MAKE_OUTPUT_FILE(${it} moc_ cxx outfile)
- QT4_CREATE_MOC_COMMAND(${it} ${outfile} "${moc_includes}" "${moc_options}")
+ QT4_CREATE_MOC_COMMAND(${it} ${outfile} "${moc_flags}" "${moc_options}")
SET(${outfiles} ${${outfiles}} ${outfile})
ENDFOREACH(it)
@@ -1234,7 +1253,7 @@ IF (QT4_QMAKE_FOUND)
ENDMACRO(QT4_ADD_DBUS_ADAPTOR)
MACRO(QT4_AUTOMOC)
- QT4_GET_MOC_INC_DIRS(_moc_INCS)
+ QT4_GET_MOC_FLAGS(_moc_INCS)
SET(_matching_FILES )
FOREACH (_current_FILE ${ARGN})
diff --git a/Modules/FindTIFF.cmake b/Modules/FindTIFF.cmake
index fbf8044687..2868bb9f34 100644
--- a/Modules/FindTIFF.cmake
+++ b/Modules/FindTIFF.cmake
@@ -9,14 +9,16 @@
FIND_PATH(TIFF_INCLUDE_DIR tiff.h)
-SET(TIFF_NAMES ${TIFF_NAMES} tiff)
+SET(TIFF_NAMES ${TIFF_NAMES} tiff libtiff libtiff3)
FIND_LIBRARY(TIFF_LIBRARY NAMES ${TIFF_NAMES} )
# handle the QUIETLY and REQUIRED arguments and set TIFF_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(TIFF DEFAULT_MSG TIFF_LIBRARY TIFF_INCLUDE_DIR)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(TIFF DEFAULT_MSG TIFF_LIBRARY TIFF_INCLUDE_DIR)
IF(TIFF_FOUND)
SET( TIFF_LIBRARIES ${TIFF_LIBRARY} )
ENDIF(TIFF_FOUND)
+
+MARK_AS_ADVANCED(TIFF_INCLUDE_DIR TIFF_LIBRARY)
diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake
index 0db6abed16..3155aac824 100644
--- a/Modules/FindX11.cmake
+++ b/Modules/FindX11.cmake
@@ -46,20 +46,18 @@ IF (UNIX)
SET(X11_INC_SEARCH_PATH
/usr/pkg/xorg/include
/usr/X11R6/include
- /usr/local/include
+ /usr/X11R7/include
/usr/include/X11
/usr/openwin/include
/usr/openwin/share/include
/opt/graphics/OpenGL/include
- /usr/include
)
SET(X11_LIB_SEARCH_PATH
/usr/pkg/xorg/lib
/usr/X11R6/lib
- /usr/local/lib
+ /usr/X11R7/lib
/usr/openwin/lib
- /usr/lib
)
FIND_PATH(X11_X11_INCLUDE_PATH X11/X.h ${X11_INC_SEARCH_PATH})
diff --git a/Modules/MacOSXFrameworkInfo.plist.in b/Modules/MacOSXFrameworkInfo.plist.in
new file mode 100644
index 0000000000..18eaef2f7d
--- /dev/null
+++ b/Modules/MacOSXFrameworkInfo.plist.in
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${MACOSX_FRAMEWORK_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_FRAMEWORK_ICON_FILE}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_FRAMEWORK_IDENTIFIER}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>FMWK</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${MACOSX_FRAMEWORK_BUNDLE_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_FRAMEWORK_SHORT_VERSION_STRING}</string>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+</dict>
+</plist>
diff --git a/Modules/NSIS.template.in b/Modules/NSIS.template.in
index 96598d9eac..19017c89b4 100644
--- a/Modules/NSIS.template.in
+++ b/Modules/NSIS.template.in
@@ -533,11 +533,62 @@ FunctionEnd
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
-
+
;--------------------------------
;Languages
-
- !insertmacro MUI_LANGUAGE "English"
+
+ !insertmacro MUI_LANGUAGE "English" ;first language is the default language
+ !insertmacro MUI_LANGUAGE "Albanian"
+ !insertmacro MUI_LANGUAGE "Arabic"
+ !insertmacro MUI_LANGUAGE "Basque"
+ !insertmacro MUI_LANGUAGE "Belarusian"
+ !insertmacro MUI_LANGUAGE "Bosnian"
+ !insertmacro MUI_LANGUAGE "Breton"
+ !insertmacro MUI_LANGUAGE "Bulgarian"
+ !insertmacro MUI_LANGUAGE "Croatian"
+ !insertmacro MUI_LANGUAGE "Czech"
+ !insertmacro MUI_LANGUAGE "Danish"
+ !insertmacro MUI_LANGUAGE "Dutch"
+ !insertmacro MUI_LANGUAGE "Estonian"
+ !insertmacro MUI_LANGUAGE "Farsi"
+ !insertmacro MUI_LANGUAGE "Finnish"
+ !insertmacro MUI_LANGUAGE "French"
+ !insertmacro MUI_LANGUAGE "German"
+ !insertmacro MUI_LANGUAGE "Greek"
+ !insertmacro MUI_LANGUAGE "Hebrew"
+ !insertmacro MUI_LANGUAGE "Hungarian"
+ !insertmacro MUI_LANGUAGE "Icelandic"
+ !insertmacro MUI_LANGUAGE "Indonesian"
+ !insertmacro MUI_LANGUAGE "Irish"
+ !insertmacro MUI_LANGUAGE "Italian"
+ !insertmacro MUI_LANGUAGE "Japanese"
+ !insertmacro MUI_LANGUAGE "Korean"
+ !insertmacro MUI_LANGUAGE "Kurdish"
+ !insertmacro MUI_LANGUAGE "Latvian"
+ !insertmacro MUI_LANGUAGE "Lithuanian"
+ !insertmacro MUI_LANGUAGE "Luxembourgish"
+ !insertmacro MUI_LANGUAGE "Macedonian"
+ !insertmacro MUI_LANGUAGE "Malay"
+ !insertmacro MUI_LANGUAGE "Mongolian"
+ !insertmacro MUI_LANGUAGE "Norwegian"
+ !insertmacro MUI_LANGUAGE "Polish"
+ !insertmacro MUI_LANGUAGE "Portuguese"
+ !insertmacro MUI_LANGUAGE "PortugueseBR"
+ !insertmacro MUI_LANGUAGE "Romanian"
+ !insertmacro MUI_LANGUAGE "Russian"
+ !insertmacro MUI_LANGUAGE "Serbian"
+ !insertmacro MUI_LANGUAGE "SerbianLatin"
+ !insertmacro MUI_LANGUAGE "SimpChinese"
+ !insertmacro MUI_LANGUAGE "Slovak"
+ !insertmacro MUI_LANGUAGE "Slovenian"
+ !insertmacro MUI_LANGUAGE "Spanish"
+ !insertmacro MUI_LANGUAGE "Swedish"
+ !insertmacro MUI_LANGUAGE "Thai"
+ !insertmacro MUI_LANGUAGE "TradChinese"
+ !insertmacro MUI_LANGUAGE "Turkish"
+ !insertmacro MUI_LANGUAGE "Ukrainian"
+ !insertmacro MUI_LANGUAGE "Welsh"
+
;--------------------------------
;Reserve Files
diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake
index edd698cfc4..97472cb961 100644
--- a/Modules/Platform/Darwin.cmake
+++ b/Modules/Platform/Darwin.cmake
@@ -67,7 +67,7 @@ IF(_CMAKE_OSX_SDKS)
IF(NOT "$ENV{CMAKE_OSX_SYSROOT}" STREQUAL "")
SET(_CMAKE_OSX_SDKS "$ENV{CMAKE_OSX_SYSROOT}")
ENDIF(NOT "$ENV{CMAKE_OSX_SYSROOT}" STREQUAL "")
- SET(CMAKE_OSX_SYSROOT ${_CMAKE_OSX_SDKS} CACHE STRING
+ SET(CMAKE_OSX_SYSROOT ${_CMAKE_OSX_SDKS} CACHE PATH
"isysroot used for universal binary support")
# set _CMAKE_OSX_MACHINE to umame -m
EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE _CMAKE_OSX_MACHINE)
diff --git a/Modules/Platform/Windows-icl.cmake b/Modules/Platform/Windows-icl.cmake
index d6db61bd71..dc40c87c1f 100644
--- a/Modules/Platform/Windows-icl.cmake
+++ b/Modules/Platform/Windows-icl.cmake
@@ -8,7 +8,7 @@ ELSE(CMAKE_VERBOSE_MAKEFILE)
ENDIF(CMAKE_VERBOSE_MAKEFILE)
# create a shared C++ library
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
- "link ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out:<TARGET> /dll <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+ "xilink ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out:<TARGET> /dll <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
SET(CMAKE_CXX_CREATE_SHARED_MODULE ${CMAKE_CXX_CREATE_SHARED_LIBRARY})
diff --git a/Modules/TestEndianess.c.in b/Modules/TestEndianess.c.in
index 68094d4ac6..c924f7858a 100644
--- a/Modules/TestEndianess.c.in
+++ b/Modules/TestEndianess.c.in
@@ -10,11 +10,14 @@ const cmakeint16 info_little[] = {0x4854, 0x5349, 0x4920, 0x2053, 0x494c, 0x545
const cmakeint16 info_big[] = {0x5448, 0x4953, 0x2049, 0x5320, 0x4249, 0x4720, 0x454e, 0x4449, 0x414e, 0x2e2e, 0x0000};
#ifdef __CLASSIC_C__
-int main(){
- int ac;
- char*av[];
+int main(argc, argv) int argc; char *argv[];
#else
-int main(int ac, char*av[]){
+int main(int argc, char *argv[])
#endif
- return (&info_little[0] != &info_big[0]);
+{
+ int require = 0;
+ require += info_little[argc];
+ require += info_big[argc];
+ (void)argv;
+ return require;
}
diff --git a/Modules/UsePkgConfig.cmake b/Modules/UsePkgConfig.cmake
index 23519e80e0..5d7d65c083 100644
--- a/Modules/UsePkgConfig.cmake
+++ b/Modules/UsePkgConfig.cmake
@@ -12,10 +12,10 @@
-FIND_PROGRAM(PKGCONFIG_EXECUTABLE NAMES pkg-config PATHS /usr/local/bin )
+FIND_PROGRAM(PKGCONFIG_EXECUTABLE NAMES pkg-config )
MACRO(PKGCONFIG _package _include_DIR _link_DIR _link_FLAGS _cflags)
- message(STATUS
+ MESSAGE(STATUS
"WARNING: you are using the obsolete 'PKGCONFIG' macro use FindPkgConfig")
# reset the variables at the beginning
SET(${_include_DIR})
@@ -33,20 +33,24 @@ MACRO(PKGCONFIG _package _include_DIR _link_DIR _link_FLAGS _cflags)
EXEC_PROGRAM(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --variable=includedir
OUTPUT_VARIABLE ${_include_DIR} )
- string(REGEX REPLACE "[\r\n]" " " ${_include_DIR} "${${_include_DIR}}")
+ STRING(REGEX REPLACE "[\r\n]" " " ${_include_DIR} "${${_include_DIR}}")
EXEC_PROGRAM(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --variable=libdir
OUTPUT_VARIABLE ${_link_DIR} )
- string(REGEX REPLACE "[\r\n]" " " ${_link_DIR} "${${_link_DIR}}")
+ STRING(REGEX REPLACE "[\r\n]" " " ${_link_DIR} "${${_link_DIR}}")
EXEC_PROGRAM(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --libs
OUTPUT_VARIABLE ${_link_FLAGS} )
- string(REGEX REPLACE "[\r\n]" " " ${_link_FLAGS} "${${_link_FLAGS}}")
+ STRING(REGEX REPLACE "[\r\n]" " " ${_link_FLAGS} "${${_link_FLAGS}}")
EXEC_PROGRAM(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --cflags
OUTPUT_VARIABLE ${_cflags} )
- string(REGEX REPLACE "[\r\n]" " " ${_cflags} "${${_cflags}}")
+ STRING(REGEX REPLACE "[\r\n]" " " ${_cflags} "${${_cflags}}")
+
+ ELSE( NOT _return_VALUE)
+
+ MESSAGE(STATUS "PKGCONFIG() indicates that ${_package} is not installed (install the package which contains ${_package}.pc if you want to support this feature)")
ENDIF(NOT _return_VALUE)
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index cae9220efd..e1b70ecae1 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -685,6 +685,7 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
cmsys::Glob gl;
gl.RecurseOn();
+ gl.RecurseThroughSymlinksOff();
std::string daGlob = cont->BinaryDir + "/*.da";
gl.FindFiles(daGlob);
std::vector<std::string> files = gl.GetFiles();
@@ -1054,6 +1055,7 @@ int cmCTestCoverageHandler::HandleTracePyCoverage(
{
cmsys::Glob gl;
gl.RecurseOn();
+ gl.RecurseThroughSymlinksOff();
std::string daGlob = cont->BinaryDir + "/*.cover";
gl.FindFiles(daGlob);
std::vector<std::string> files = gl.GetFiles();
diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx
index 3007216cd9..5a8b80d932 100644
--- a/Source/CursesDialog/cmCursesStringWidget.cxx
+++ b/Source/CursesDialog/cmCursesStringWidget.cxx
@@ -170,14 +170,21 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm,
{
form_driver(form, REQ_END_FIELD);
}
- else if ( key == ctrl('d') || key == 127 ||
- key == KEY_BACKSPACE || key == KEY_DC )
+ else if ( key == 127 ||
+ key == KEY_BACKSPACE )
{
if ( form->curcol > 0 )
{
form_driver(form, REQ_DEL_PREV);
}
}
+ else if ( key == ctrl('d') ||key == KEY_DC )
+ {
+ if ( form->curcol > 0 )
+ {
+ form_driver(form, REQ_DEL_CHAR);
+ }
+ }
else
{
this->OnType(key, fm, w);
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 575dd04f22..2bc65ceba5 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -68,6 +68,12 @@ bool cmAddLibraryCommand
type = cmTarget::MODULE_LIBRARY;
haveSpecifiedType = true;
}
+ else if(libType == "UNKNOWN")
+ {
+ ++s;
+ type = cmTarget::UNKNOWN_LIBRARY;
+ haveSpecifiedType = true;
+ }
else if(*s == "EXCLUDE_FROM_ALL")
{
++s;
@@ -127,6 +133,16 @@ bool cmAddLibraryCommand
return true;
}
+ // A non-imported target may not have UNKNOWN type.
+ if(type == cmTarget::UNKNOWN_LIBRARY)
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "The UNKNOWN library type may be used only for IMPORTED libraries."
+ );
+ return true;
+ }
+
// Enforce name uniqueness.
{
std::string msg;
diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h
index ad23ffc5b2..6cad681a9d 100644
--- a/Source/cmAddLibraryCommand.h
+++ b/Source/cmAddLibraryCommand.h
@@ -100,7 +100,7 @@ public:
"\n"
"The add_library command can also create IMPORTED library "
"targets using this signature:\n"
- " add_library(<name> <SHARED|STATIC|MODULE> IMPORTED)\n"
+ " add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED)\n"
"An IMPORTED library target references a library file located "
"outside the project. "
"No rules are generated to build it. "
diff --git a/Source/cmAddSubDirectoryCommand.h b/Source/cmAddSubDirectoryCommand.h
index 813f30bca1..f926883040 100644
--- a/Source/cmAddSubDirectoryCommand.h
+++ b/Source/cmAddSubDirectoryCommand.h
@@ -79,13 +79,21 @@ public:
"be processed immediately by CMake before processing in the current "
"input file continues beyond this command.\n"
- "If the EXCLUDE_FROM_ALL argument is provided then this subdirectory "
- "will not be included in build by default. Users will have to "
- "explicitly start a build in the generated output directory. "
- "This is useful for having cmake create a build system for a "
- "set of examples in a project. One would want cmake to generate "
- "a single build system for all the examples, but one may not want "
- "the targets to show up in the main build system.";
+ "If the EXCLUDE_FROM_ALL argument is provided then targets in the "
+ "subdirectory will not be included in the ALL target of the parent "
+ "directory by default, and will be excluded from IDE project files. "
+ "Users must explicitly build targets in the subdirectory. "
+ "This is meant for use when the subdirectory contains a separate part "
+ "of the project that is useful but not necessary, such as a set of "
+ "examples. "
+ "Typically the subdirectory should contain its own project() command "
+ "invocation so that a full build system will be generated in the "
+ "subdirectory (such as a VS IDE solution file). "
+ "Note that inter-target dependencies supercede this exclusion. "
+ "If a target built by the parent project depends on a target in the "
+ "subdirectory, the dependee target will be included in the parent "
+ "project build system to satisfy the dependency."
+ ;
}
cmTypeMacro(cmAddSubDirectoryCommand, cmCommand);
diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx
index d6f1b3e9d8..7672a6ceec 100644
--- a/Source/cmCMakePolicyCommand.cxx
+++ b/Source/cmCMakePolicyCommand.cxx
@@ -32,6 +32,10 @@ bool cmCMakePolicyCommand
{
return this->HandleSetMode(args);
}
+ else if(args[0] == "GET")
+ {
+ return this->HandleGetMode(args);
+ }
else if(args[0] == "PUSH")
{
if(args.size() > 1)
@@ -104,6 +108,63 @@ bool cmCMakePolicyCommand::HandleSetMode(std::vector<std::string> const& args)
}
//----------------------------------------------------------------------------
+bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args)
+{
+ if(args.size() != 3)
+ {
+ this->SetError("GET must be given exactly 2 additional arguments.");
+ return false;
+ }
+
+ // Get arguments.
+ std::string const& id = args[1];
+ std::string const& var = args[2];
+
+ // Lookup the policy number.
+ cmPolicies::PolicyID pid;
+ if(!this->Makefile->GetPolicies()->GetPolicyID(id.c_str(), pid))
+ {
+ cmOStringStream e;
+ e << "GET given policy \"" << id << "\" which is not known to this "
+ << "version of CMake.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Lookup the policy setting.
+ cmPolicies::PolicyStatus status = this->Makefile->GetPolicyStatus(pid);
+ switch (status)
+ {
+ case cmPolicies::OLD:
+ // Report that the policy is set to OLD.
+ this->Makefile->AddDefinition(var.c_str(), "OLD");
+ break;
+ case cmPolicies::WARN:
+ // Report that the policy is not set.
+ this->Makefile->AddDefinition(var.c_str(), "");
+ break;
+ case cmPolicies::NEW:
+ // Report that the policy is set to NEW.
+ this->Makefile->AddDefinition(var.c_str(), "NEW");
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ // The policy is required to be set before anything needs it.
+ {
+ cmOStringStream e;
+ e << this->Makefile->GetPolicies()->GetRequiredPolicyError(pid)
+ << "\n"
+ << "The call to cmake_policy(GET " << id << " ...) at which this "
+ << "error appears requests the policy, and this version of CMake "
+ << "requires that the policy be set to NEW before it is checked.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
bool
cmCMakePolicyCommand::HandleVersionMode(std::vector<std::string> const& args)
{
diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h
index 54c494c66d..e4788111f4 100644
--- a/Source/cmCMakePolicyCommand.h
+++ b/Source/cmCMakePolicyCommand.h
@@ -108,6 +108,11 @@ public:
"Alternatively one may fix the project to work with the new behavior "
"and set the policy state to NEW."
"\n"
+ " cmake_policy(GET CMP<NNNN> <variable>)\n"
+ "Check whether a given policy is set to OLD or NEW behavior. "
+ "The output variable value will be \"OLD\" or \"NEW\" if the "
+ "policy is set, and empty otherwise."
+ "\n"
" cmake_policy(PUSH)\n"
" cmake_policy(POP)\n"
"Push and pop the current policy setting state on a stack. "
@@ -123,6 +128,7 @@ public:
cmTypeMacro(cmCMakePolicyCommand, cmCommand);
private:
bool HandleSetMode(std::vector<std::string> const& args);
+ bool HandleGetMode(std::vector<std::string> const& args);
bool HandleVersionMode(std::vector<std::string> const& args);
};
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index bd95354564..52cb44859c 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -714,10 +714,6 @@ void cmCacheManager::RemoveCacheEntry(const char* key)
{
this->Cache.erase(i);
}
- else
- {
- std::cerr << "Failed to remove entry:" << key << std::endl;
- }
}
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 72dd1982be..cc60e09293 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -33,10 +33,10 @@ This file computes an ordered list of link items to use when linking a
single target in one configuration. Each link item is identified by
the string naming it. A graph of dependencies is created in which
each node corresponds to one item and directed eges lead from nodes to
-those which must *precede* them on the link line. For example, the
+those which must *follow* them on the link line. For example, the
graph
- C -> B -> A
+ A -> B -> C
will lead to the link line order
@@ -50,7 +50,9 @@ those without known dependencies. We will call the two types "known
items" and "unknown items", respecitvely. Known items are those whose
names correspond to targets (built or imported) and those for which an
old-style <item>_LIB_DEPENDS variable is defined. All other items are
-unknown and we must infer dependencies for them.
+unknown and we must infer dependencies for them. For items that look
+like flags (beginning with '-') we trivially infer no dependencies,
+and do not include them in the dependencies of other items.
Known items have dependency lists ordered based on how the user
specified them. We can use this order to infer potential dependencies
@@ -63,11 +65,11 @@ lists:
The explicitly known dependencies form graph edges
- X <- Y , X <- A , X <- B , Y <- A , Y <- B
+ X -> Y , X -> A , X -> B , Y -> A , Y -> B
We can also infer the edge
- A <- B
+ A -> B
because *every* time A appears B is seen on its right. We do not know
whether A really needs symbols from B to link, but it *might* so we
@@ -91,12 +93,12 @@ considering these dependency lists:
The explicit edges are
- X <- Y , X <- A , X <- B , X <- C , Y <- A , Y <- B , Y <- C
+ X -> Y , X -> A , X -> B , X -> C , Y -> A , Y -> B , Y -> C
For the unknown items, we infer dependencies by looking at the
"follow" sets:
- A: intersect( {B,Y,C} , {C,B} ) = {B,C} ; infer edges A <- B , A <- C
+ A: intersect( {B,Y,C} , {C,B} ) = {B,C} ; infer edges A -> B , A -> C
B: intersect( {Y,C} , {} ) = {} ; infer no edges
C: intersect( {} , {B} ) = {} ; infer no edges
@@ -105,57 +107,71 @@ libraries should not depend on them.
------------------------------------------------------------------------------
-Once the complete graph is formed from all known and inferred
-dependencies we must use it to produce a valid link line. If the
-dependency graph were known to be acyclic a simple depth-first-search
-would produce a correct link line. Unfortunately we cannot make this
-assumption so the following technique is used.
+The initial exploration of dependencies using a BFS associates an
+integer index with each link item. When the graph is built outgoing
+edges are sorted by this index.
+
+After the initial exploration of the link interface tree, any
+transitive (dependent) shared libraries that were encountered and not
+included in the interface are processed in their own BFS. This BFS
+follows only the dependent library lists and not the link interfaces.
+They are added to the link items with a mark indicating that the are
+transitive dependencies. Then cmComputeLinkInformation deals with
+them on a per-platform basis.
+The complete graph formed from all known and inferred dependencies may
+not be acyclic, so an acyclic version must be created.
The original graph is converted to a directed acyclic graph in which
each node corresponds to a strongly connected component of the
original graph. For example, the dependency graph
- X <- A <- B <- C <- A <- Y
+ X -> A -> B -> C -> A -> Y
contains strongly connected components {X}, {A,B,C}, and {Y}. The
implied directed acyclic graph (DAG) is
- {X} <- {A,B,C} <- {Y}
-
-The final list of link items is constructed by a series of
-depth-first-searches through this DAG of components. When visiting a
-component all outgoing edges are followed first because the neighbors
-must precede it. Once neighbors across all edges have been emitted it
-is safe to emit the current component.
+ {X} -> {A,B,C} -> {Y}
-Trivial components (those with one item) are handled simply by
-emitting the item. Non-trivial components (those with more than one
-item) are assumed to consist only of static libraries that may be
-safely repeated on the link line. We emit members of the component
-multiple times (see code below for details). The final link line for
-the example graph might be
-
- X A B C A B C Y
+We then compute a topological order for the DAG nodes to serve as a
+reference for satisfying dependencies efficiently. We perform the DFS
+in reverse order and assign topological order indices counting down so
+that the result is as close to the original BFS order as possible
+without violating dependencies.
------------------------------------------------------------------------------
-The initial exploration of dependencies using a BFS associates an
-integer index with each link item. When the graph is built outgoing
-edges are sorted by this index.
-
-This preserves the original link order as much as possible subject to
-the dependencies. We then further preserve the original link line by
-appending items to make sure all those that might be static libraries
-appear in the order and multiplicity that they do in the original
-line.
-
-After the initial exploration of the link interface tree, any
-transitive (dependent) shared libraries that were encountered and not
-included in the interface are processed in their own BFS. This BFS
-follows only the dependent library lists and not the link interfaces.
-They are added to the link items with a mark indicating that the are
-transitive dependencies. Then cmComputeLinkInformation deals with
-them on a per-platform basis.
+The final link entry order is constructed as follows. We first walk
+through and emit the *original* link line as specified by the user.
+As each item is emitted, a set of pending nodes in the component DAG
+is maintained. When a pending component has been completely seen, it
+is removed from the pending set and its dependencies (following edges
+of the DAG) are added. A trivial component (those with one item) is
+complete as soon as its item is seen. A non-trivial component (one
+with more than one item; assumed to be static libraries) is complete
+when *all* its entries have been seen *twice* (all entries seen once,
+then all entries seen again, not just each entry twice). A pending
+component tracks which items have been seen and a count of how many
+times the component needs to be seen (once for trivial components,
+twice for non-trivial). If at any time another component finishes and
+re-adds an already pending component, the pending component is reset
+so that it needs to be seen in its entirety again. This ensures that
+all dependencies of a component are satisified no matter where it
+appears.
+
+After the original link line has been completed, we append to it the
+remaining pending components and their dependencies. This is done by
+repeatedly emitting the first item from the first pending component
+and following the same update rules as when traversing the original
+link line. Since the pending components are kept in topological order
+they are emitted with minimal repeats (we do not want to emit a
+component just to have it added again when another component is
+completed later). This process continues until no pending components
+remain. We know it will terminate because the component graph is
+guaranteed to be acyclic.
+
+The final list of items produced by this procedure consists of the
+original user link line followed by minimal additional items needed to
+satisfy dependencies.
*/
@@ -171,13 +187,16 @@ cmComputeLinkDepends
this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
// The configuration being linked.
- this->Config = config;
+ this->Config = (config && *config)? config : 0;
// Enable debug mode if requested.
this->DebugMode = this->Makefile->IsOn("CMAKE_LINK_DEPENDS_DEBUG_MODE");
// Assume no compatibility until set.
this->OldLinkDirMode = false;
+
+ // No computation has been done.
+ this->CCG = 0;
}
//----------------------------------------------------------------------------
@@ -189,6 +208,7 @@ cmComputeLinkDepends::~cmComputeLinkDepends()
{
delete *i;
}
+ delete this->CCG;
}
//----------------------------------------------------------------------------
@@ -242,7 +262,6 @@ cmComputeLinkDepends::Compute()
// Compute the final ordering.
this->OrderLinkEntires();
- this->PreserveOriginalEntries();
// Compute the final set of link entries.
for(std::vector<int>::const_iterator li = this->FinalLinkOrder.begin();
@@ -292,7 +311,9 @@ int cmComputeLinkDepends::AddLinkEntry(std::string const& item)
int index = lei->second;
LinkEntry& entry = this->EntryList[index];
entry.Item = item;
- entry.Target = this->Makefile->FindTargetToUse(entry.Item.c_str());
+ entry.Target = this->FindTargetToLink(entry.Item.c_str());
+ entry.IsFlag = (!entry.Target && item[0] == '-' && item[1] != 'l' &&
+ item.substr(0, 10) != "-framework");
// If the item has dependencies queue it to follow them.
if(entry.Target)
@@ -312,7 +333,7 @@ int cmComputeLinkDepends::AddLinkEntry(std::string const& item)
BFSEntry qe = {index, val};
this->BFSQueue.push(qe);
}
- else
+ else if(!entry.IsFlag)
{
// The item dependencies are not known. We need to infer them.
this->InferredDependSets[index] = new DependSetList;
@@ -387,7 +408,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
// Initialize the item entry.
LinkEntry& entry = this->EntryList[lei->second];
entry.Item = dep.Item;
- entry.Target = this->Makefile->FindTargetToUse(dep.Item.c_str());
+ entry.Target = this->FindTargetToLink(dep.Item.c_str());
// This item was added specifically because it is a dependent
// shared library. It may get special treatment
@@ -399,9 +420,9 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
int index = lei->second;
LinkEntry& entry = this->EntryList[index];
- // This shared library dependency must be preceded by the item that
- // listed it.
- this->EntryConstraintGraph[index].push_back(dep.DependerIndex);
+ // This shared library dependency must follow the item that listed
+ // it.
+ this->EntryConstraintGraph[dep.DependerIndex].push_back(index);
// Target items may have their own dependencies.
if(entry.Target)
@@ -552,10 +573,10 @@ cmComputeLinkDepends::AddLinkEntries(int depender_index,
// Add a link entry for this item.
int dependee_index = this->AddLinkEntry(item);
- // The depender must come before the dependee.
+ // The dependee must come after the depender.
if(depender_index >= 0)
{
- this->EntryConstraintGraph[dependee_index].push_back(depender_index);
+ this->EntryConstraintGraph[depender_index].push_back(dependee_index);
}
else
{
@@ -572,6 +593,7 @@ cmComputeLinkDepends::AddLinkEntries(int depender_index,
// items are outside libraries that should not be depending on
// targets.
if(!this->EntryList[dependee_index].Target &&
+ !this->EntryList[dependee_index].IsFlag &&
dependee_index != dsi->first)
{
dsi->second.insert(dependee_index);
@@ -655,6 +677,25 @@ std::string cmComputeLinkDepends::CleanItemName(std::string const& item)
}
//----------------------------------------------------------------------------
+cmTarget* cmComputeLinkDepends::FindTargetToLink(const char* name)
+{
+ // Look for a target.
+ cmTarget* tgt = this->Makefile->FindTargetToUse(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(tgt && tgt->GetType() == cmTarget::EXECUTABLE &&
+ !tgt->IsExecutableWithExports())
+ {
+ tgt = 0;
+ }
+
+ // Return the target found, if any.
+ return tgt;
+}
+
+//----------------------------------------------------------------------------
void cmComputeLinkDepends::InferDependencies()
{
// The inferred dependency sets for each item list the possible
@@ -687,7 +728,7 @@ void cmComputeLinkDepends::InferDependencies()
for(DependSet::const_iterator j = common.begin(); j != common.end(); ++j)
{
int dependee_index = *j;
- this->EntryConstraintGraph[dependee_index].push_back(depender_index);
+ this->EntryConstraintGraph[depender_index].push_back(dependee_index);
}
}
}
@@ -719,7 +760,7 @@ void cmComputeLinkDepends::DisplayConstraintGraph()
e << "item " << i << " is [" << this->EntryList[i].Item << "]\n";
for(NodeList::const_iterator j = nl.begin(); j != nl.end(); ++j)
{
- e << " item " << *j << " must precede it\n";
+ e << " item " << *j << " must follow it\n";
}
}
fprintf(stderr, "%s\n", e.str().c_str());
@@ -733,30 +774,55 @@ void cmComputeLinkDepends::OrderLinkEntires()
// the same order in which the items were originally discovered in
// the BFS. This should preserve the original order when no
// constraints disallow it.
- cmComputeComponentGraph ccg(this->EntryConstraintGraph);
- Graph const& cgraph = ccg.GetComponentGraph();
+ this->CCG = new cmComputeComponentGraph(this->EntryConstraintGraph);
+
+ // The component graph is guaranteed to be acyclic. Start a DFS
+ // from every entry to compute a topological order for the
+ // components.
+ Graph const& cgraph = this->CCG->GetComponentGraph();
+ int n = static_cast<int>(cgraph.size());
+ this->ComponentVisited.resize(cgraph.size(), 0);
+ this->ComponentOrder.resize(cgraph.size(), n);
+ this->ComponentOrderId = n;
+ // Run in reverse order so the topological order will preserve the
+ // original order where there are no constraints.
+ for(int c = n-1; c >= 0; --c)
+ {
+ this->VisitComponent(c);
+ }
+
+ // Display the component graph.
if(this->DebugMode)
{
- this->DisplayComponents(ccg);
+ this->DisplayComponents();
}
- // Setup visit tracking.
- this->ComponentVisited.resize(cgraph.size(), 0);
+ // Start with the original link line.
+ for(std::vector<int>::const_iterator i = this->OriginalEntries.begin();
+ i != this->OriginalEntries.end(); ++i)
+ {
+ this->VisitEntry(*i);
+ }
- // The component graph is guaranteed to be acyclic. Start a DFS
- // from every entry.
- for(unsigned int c=0; c < cgraph.size(); ++c)
+ // Now explore anything left pending. Since the component graph is
+ // guaranteed to be acyclic we know this will terminate.
+ while(!this->PendingComponents.empty())
{
- this->VisitComponent(ccg, c);
+ // Visit one entry from the first pending component. The visit
+ // logic will update the pending components accordingly. Since
+ // the pending components are kept in topological order this will
+ // not repeat one.
+ int e = *this->PendingComponents.begin()->second.Entries.begin();
+ this->VisitEntry(e);
}
}
//----------------------------------------------------------------------------
void
-cmComputeLinkDepends::DisplayComponents(cmComputeComponentGraph const& ccg)
+cmComputeLinkDepends::DisplayComponents()
{
fprintf(stderr, "The strongly connected components are:\n");
- std::vector<NodeList> const& components = ccg.GetComponents();
+ std::vector<NodeList> const& components = this->CCG->GetComponents();
for(unsigned int c=0; c < components.size(); ++c)
{
fprintf(stderr, "Component (%u):\n", c);
@@ -767,14 +833,19 @@ cmComputeLinkDepends::DisplayComponents(cmComputeComponentGraph const& ccg)
fprintf(stderr, " item %d [%s]\n", i,
this->EntryList[i].Item.c_str());
}
+ NodeList const& ol = this->CCG->GetComponentGraphEdges(c);
+ for(NodeList::const_iterator oi = ol.begin(); oi != ol.end(); ++oi)
+ {
+ fprintf(stderr, " followed by Component (%d)\n", *oi);
+ }
+ fprintf(stderr, " topo order index %d\n",
+ this->ComponentOrder[c]);
}
fprintf(stderr, "\n");
}
//----------------------------------------------------------------------------
-void
-cmComputeLinkDepends::VisitComponent(cmComputeComponentGraph const& ccg,
- unsigned int c)
+void cmComputeLinkDepends::VisitComponent(unsigned int c)
{
// Check if the node has already been visited.
if(this->ComponentVisited[c])
@@ -786,49 +857,126 @@ cmComputeLinkDepends::VisitComponent(cmComputeComponentGraph const& ccg,
this->ComponentVisited[c] = 1;
// Visit the neighbors of the component first.
- NodeList const& nl = ccg.GetComponentGraphEdges(c);
- for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
+ // Run in reverse order so the topological order will preserve the
+ // original order where there are no constraints.
+ NodeList const& nl = this->CCG->GetComponentGraphEdges(c);
+ for(NodeList::const_reverse_iterator ni = nl.rbegin();
+ ni != nl.rend(); ++ni)
{
- this->VisitComponent(ccg, *ni);
+ this->VisitComponent(*ni);
}
- // Now that all items required to come before this one have been
- // emmitted, emit this component's items.
- this->EmitComponent(ccg.GetComponent(c));
+ // Assign an ordering id to this component.
+ this->ComponentOrder[c] = --this->ComponentOrderId;
}
//----------------------------------------------------------------------------
-void cmComputeLinkDepends::EmitComponent(NodeList const& nl)
+void cmComputeLinkDepends::VisitEntry(int index)
{
- assert(!nl.empty());
+ // Include this entry on the link line.
+ this->FinalLinkOrder.push_back(index);
+
+ // This entry has now been seen. Update its component.
+ bool completed = false;
+ int component = this->CCG->GetComponentMap()[index];
+ std::map<int, PendingComponent>::iterator mi =
+ this->PendingComponents.find(this->ComponentOrder[component]);
+ if(mi != this->PendingComponents.end())
+ {
+ // The entry is in an already pending component.
+ PendingComponent& pc = mi->second;
+
+ // Remove the entry from those pending in its component.
+ pc.Entries.erase(index);
+ if(pc.Entries.empty())
+ {
+ // The complete component has been seen since it was last needed.
+ --pc.Count;
- // Handle trivial components.
- if(nl.size() == 1)
+ if(pc.Count == 0)
+ {
+ // The component has been completed.
+ this->PendingComponents.erase(mi);
+ completed = true;
+ }
+ else
+ {
+ // The whole component needs to be seen again.
+ NodeList const& nl = this->CCG->GetComponent(component);
+ assert(nl.size() > 1);
+ pc.Entries.insert(nl.begin(), nl.end());
+ }
+ }
+ }
+ else
{
- this->FinalLinkOrder.push_back(nl[0]);
- return;
+ // The entry is not in an already pending component.
+ NodeList const& nl = this->CCG->GetComponent(component);
+ if(nl.size() > 1)
+ {
+ // This is a non-trivial component. It is now pending.
+ PendingComponent& pc = this->MakePendingComponent(component);
+
+ // The starting entry has already been seen.
+ pc.Entries.erase(index);
+ }
+ else
+ {
+ // This is a trivial component, so it is already complete.
+ completed = true;
+ }
}
- // This is a non-trivial strongly connected component of the
- // original graph. It consists of two or more libraries (archives)
- // that mutually require objects from one another. In the worst
- // case we may have to repeat the list of libraries as many times as
- // there are object files in the biggest archive. For now we just
- // list them twice.
- //
- // The list of items in the component has been sorted by the order
- // of discovery in the original BFS of dependencies. This has the
- // advantage that the item directly linked by a target requiring
- // this component will come first which minimizes the number of
- // repeats needed.
- for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
+ // If the entry completed a component, the component's dependencies
+ // are now pending.
+ if(completed)
{
- this->FinalLinkOrder.push_back(*ni);
+ NodeList const& ol = this->CCG->GetComponentGraphEdges(component);
+ for(NodeList::const_iterator oi = ol.begin(); oi != ol.end(); ++oi)
+ {
+ // This entire component is now pending no matter whether it has
+ // been partially seen already.
+ this->MakePendingComponent(*oi);
+ }
}
- for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
+}
+
+//----------------------------------------------------------------------------
+cmComputeLinkDepends::PendingComponent&
+cmComputeLinkDepends::MakePendingComponent(unsigned int component)
+{
+ // Create an entry (in topological order) for the component.
+ PendingComponent& pc =
+ this->PendingComponents[this->ComponentOrder[component]];
+ pc.Id = component;
+ NodeList const& nl = this->CCG->GetComponent(component);
+
+ if(nl.size() == 1)
{
- this->FinalLinkOrder.push_back(*ni);
+ // Trivial components need be seen only once.
+ pc.Count = 1;
}
+ else
+ {
+ // This is a non-trivial strongly connected component of the
+ // original graph. It consists of two or more libraries
+ // (archives) that mutually require objects from one another. In
+ // the worst case we may have to repeat the list of libraries as
+ // many times as there are object files in the biggest archive.
+ // For now we just list them twice.
+ //
+ // The list of items in the component has been sorted by the order
+ // of discovery in the original BFS of dependencies. This has the
+ // advantage that the item directly linked by a target requiring
+ // this component will come first which minimizes the number of
+ // repeats needed.
+ pc.Count = 2;
+ }
+
+ // Store the entries to be seen.
+ pc.Entries.insert(nl.begin(), nl.end());
+
+ return pc;
}
//----------------------------------------------------------------------------
@@ -862,7 +1010,7 @@ void cmComputeLinkDepends::CheckWrongConfigItem(std::string const& item)
// For CMake 2.4 bug-compatibility we need to consider the output
// directories of targets linked in another configuration as link
// directories.
- if(cmTarget* tgt = this->Makefile->FindTargetToUse(item.c_str()))
+ if(cmTarget* tgt = this->FindTargetToLink(item.c_str()))
{
if(!tgt->IsImported())
{
@@ -870,49 +1018,3 @@ void cmComputeLinkDepends::CheckWrongConfigItem(std::string const& item)
}
}
}
-
-//----------------------------------------------------------------------------
-void cmComputeLinkDepends::PreserveOriginalEntries()
-{
- // Skip the part of the input sequence that already appears in the
- // output.
- std::vector<int>::const_iterator in = this->OriginalEntries.begin();
- std::vector<int>::const_iterator out = this->FinalLinkOrder.begin();
- while(in != this->OriginalEntries.end() &&
- out != this->FinalLinkOrder.end())
- {
- cmTarget* tgt = this->EntryList[*in].Target;
- if(tgt && tgt->GetType() != cmTarget::STATIC_LIBRARY)
- {
- // Skip input items known to not be static libraries.
- ++in;
- }
- else if(*in == *out)
- {
- // The input and output items match. Move on to the next items.
- ++in;
- ++out;
- }
- else
- {
- // The output item does not match the next input item. Skip it.
- ++out;
- }
- }
-
- // Append the part of the input sequence that does not already
- // appear in the output.
- while(in != this->OriginalEntries.end())
- {
- cmTarget* tgt = this->EntryList[*in].Target;
- if(tgt && tgt->GetType() != cmTarget::STATIC_LIBRARY)
- {
- // Skip input items known to not be static libraries.
- ++in;
- }
- else
- {
- this->FinalLinkOrder.push_back(*in++);
- }
- }
-}
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 3e42580df8..3cbb99a903 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -46,9 +46,11 @@ public:
std::string Item;
cmTarget* Target;
bool IsSharedDep;
- LinkEntry(): Item(), Target(0), IsSharedDep(false) {}
+ bool IsFlag;
+ LinkEntry(): Item(), Target(0), IsSharedDep(false), IsFlag(false) {}
LinkEntry(LinkEntry const& r):
- Item(r.Item), Target(r.Target), IsSharedDep(r.IsSharedDep) {}
+ Item(r.Item), Target(r.Target), IsSharedDep(r.IsSharedDep),
+ IsFlag(r.IsFlag) {}
};
typedef std::vector<LinkEntry> EntryVector;
@@ -85,6 +87,7 @@ private:
void AddLinkEntries(int depender_index,
std::vector<std::string> const& libs);
std::string CleanItemName(std::string const& item);
+ cmTarget* FindTargetToLink(const char* name);
// One entry for each unique item.
std::vector<LinkEntry> EntryList;
@@ -128,15 +131,33 @@ private:
// Ordering algorithm.
void OrderLinkEntires();
std::vector<char> ComponentVisited;
+ std::vector<int> ComponentOrder;
+ int ComponentOrderId;
+ struct PendingComponent
+ {
+ // The real component id. Needed because the map is indexed by
+ // component topological index.
+ int Id;
+
+ // The number of times the component needs to be seen. This is
+ // always 1 for trivial components and is initially 2 for
+ // non-trivial components.
+ int Count;
+
+ // The entries yet to be seen to complete the component.
+ std::set<int> Entries;
+ };
+ std::map<int, PendingComponent> PendingComponents;
+ cmComputeComponentGraph* CCG;
std::vector<int> FinalLinkOrder;
- void DisplayComponents(cmComputeComponentGraph const& ccg);
- void VisitComponent(cmComputeComponentGraph const& ccg, unsigned int i);
- void EmitComponent(NodeList const& nl);
+ void DisplayComponents();
+ void VisitComponent(unsigned int c);
+ void VisitEntry(int index);
+ PendingComponent& MakePendingComponent(unsigned int component);
void DisplayFinalEntries();
- // Preservation of original link line.
+ // Record of the original link line.
std::vector<int> OriginalEntries;
- void PreserveOriginalEntries();
// Compatibility help.
bool OldLinkDirMode;
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 6e0f10bf78..0b02ae12f3 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -581,10 +581,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
return;
}
- if(tgt && (tgt->GetType() == cmTarget::STATIC_LIBRARY ||
- tgt->GetType() == cmTarget::SHARED_LIBRARY ||
- tgt->GetType() == cmTarget::MODULE_LIBRARY ||
- impexe))
+ if(tgt && tgt->IsLinkable())
{
// This is a CMake target. Ask the target for its real name.
if(impexe && this->LoaderFlag)
@@ -1555,6 +1552,14 @@ void
cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
cmTarget* target)
{
+ // Libraries with unknown type must be handled using just the file
+ // on disk.
+ if(target->GetType() == cmTarget::UNKNOWN_LIBRARY)
+ {
+ this->AddLibraryRuntimeInfo(fullPath);
+ return;
+ }
+
// Skip targets that are not shared libraries (modules cannot be linked).
if(target->GetType() != cmTarget::SHARED_LIBRARY)
{
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index d13a6db8b1..7a6e81ffa1 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -214,7 +214,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
// Don't emit the same library twice for this target.
if(emitted.insert(lib->first).second)
{
- this->AddTargetDepend(depender_index, lib->first.c_str());
+ this->AddTargetDepend(depender_index, lib->first.c_str(), true);
}
}
@@ -226,14 +226,15 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
// Don't emit the same utility twice for this target.
if(emitted.insert(*util).second)
{
- this->AddTargetDepend(depender_index, util->c_str());
+ this->AddTargetDepend(depender_index, util->c_str(), false);
}
}
}
//----------------------------------------------------------------------------
void cmComputeTargetDepends::AddTargetDepend(int depender_index,
- const char* dependee_name)
+ const char* dependee_name,
+ bool linking)
{
// Get the depender.
cmTarget* depender = this->Targets[depender_index];
@@ -248,6 +249,16 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
dependee = this->GlobalGenerator->FindTarget(0, 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 not found then skip then the dependee.
if(!dependee)
{
@@ -365,7 +376,7 @@ cmComputeTargetDepends
cmTarget* depender = this->Targets[i];
// Describe the depender.
- e << " " << depender->GetName() << " of type "
+ e << " \"" << depender->GetName() << "\" of type "
<< cmTarget::TargetTypeNames[depender->GetType()] << "\n";
// List its dependencies that are inside the component.
@@ -376,7 +387,7 @@ cmComputeTargetDepends
if(cmap[j] == c)
{
cmTarget* dependee = this->Targets[j];
- e << " depends on " << dependee->GetName() << "\n";
+ e << " depends on \"" << dependee->GetName() << "\"\n";
}
}
}
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
index 707256e1d9..e3e15e1905 100644
--- a/Source/cmComputeTargetDepends.h
+++ b/Source/cmComputeTargetDepends.h
@@ -48,7 +48,8 @@ private:
void CollectTargets();
void CollectDepends();
void CollectTargetDepends(int depender_index);
- void AddTargetDepend(int depender_index, const char* dependee_name);
+ void AddTargetDepend(int depender_index, const char* dependee_name,
+ bool linking);
void ComputeFinalDepends(cmComputeComponentGraph const& ccg);
cmGlobalGenerator* GlobalGenerator;
diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx
index cf228f1c08..25ef0b2ab1 100644
--- a/Source/cmDocumentVariables.cxx
+++ b/Source/cmDocumentVariables.cxx
@@ -736,6 +736,24 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
"Set to true when the host system is Windows and on cygwin.",false,
"Variables That Describe the System");
+ cm->DefineProperty
+ ("CMAKE_OBJECT_PATH_MAX", cmProperty::VARIABLE,
+ "Maximum object file full-path length allowed by native build tools.",
+ "CMake computes for every source file an object file name that is "
+ "unique to the source file and deterministic with respect to the "
+ "full path to the source file. "
+ "This allows multiple source files in a target to share the same name "
+ "if they lie in different directories without rebuilding when one is "
+ "added or removed. "
+ "However, it can produce long full paths in a few cases, so CMake "
+ "shortens the path using a hashing scheme when the full path to an "
+ "object file exceeds a limit. "
+ "CMake has a built-in limit for each platform that is sufficient for "
+ "common tools, but some native tools may have a lower limit. "
+ "This variable may be set to specify the limit explicitly. "
+ "The value must be an integer no less than 128.",false,
+ "Variables That Describe the System");
+
// Variables that affect the building of object files and
// targets.
//
diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx
index 72a819225f..8b6f69ee60 100644
--- a/Source/cmDocumentation.cxx
+++ b/Source/cmDocumentation.cxx
@@ -656,7 +656,8 @@ cmDocumentation::Form cmDocumentation::GetFormFromFilename(
}
//----------------------------------------------------------------------------
-bool cmDocumentation::CheckOptions(int argc, const char* const* argv)
+bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
+ const char* exitOpt)
{
// Providing zero arguments gives usage information.
if(argc == 1)
@@ -673,6 +674,10 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv)
bool result = false;
for(int i=1; i < argc; ++i)
{
+ if(exitOpt && strcmp(argv[i], exitOpt) == 0)
+ {
+ return result;
+ }
RequestedHelpItem help;
// Check if this is a supported help option.
if((strcmp(argv[i], "-help") == 0) ||
diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h
index 526da585b2..c1b98d36d0 100644
--- a/Source/cmDocumentation.h
+++ b/Source/cmDocumentation.h
@@ -45,9 +45,12 @@ public:
* Check command line arguments for documentation options. Returns
* true if documentation options are found, and false otherwise.
* When true is returned, PrintRequestedDocumentation should be
- * called.
+ * called. exitOpt can be used for things like cmake -E, so that
+ * all arguments after the -E are ignored and not searched for
+ * help arguments.
*/
- bool CheckOptions(int argc, const char* const* argv);
+ bool CheckOptions(int argc, const char* const* argv,
+ const char* exitOpt =0);
/**
* Print help requested on the command line. Call after
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 9389584474..9995b51c8c 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -93,14 +93,12 @@ void cmExtraCodeBlocksGenerator::Generate()
}
-/* create the project file, if it already exists, merge it with the
-existing one, otherwise create a new one */
+/* create the project file */
void cmExtraCodeBlocksGenerator::CreateProjectFile(
const std::vector<cmLocalGenerator*>& lgs)
{
const cmMakefile* mf=lgs[0]->GetMakefile();
std::string outputDir=mf->GetStartOutputDirectory();
- std::string projectDir=mf->GetHomeDirectory();
std::string projectName=mf->GetProjectName();
std::string filename=outputDir+"/";
@@ -108,16 +106,7 @@ void cmExtraCodeBlocksGenerator::CreateProjectFile(
std::string sessionFilename=outputDir+"/";
sessionFilename+=projectName+".layout";
-/* if (cmSystemTools::FileExists(filename.c_str()))
- {
- this->MergeProjectFiles(outputDir, projectDir, filename,
- cmakeFilePattern, sessionFilename);
- }
- else */
- {
- this->CreateNewProjectFile(lgs, filename);
- }
-
+ this->CreateNewProjectFile(lgs, filename);
}
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 6ac6bccaed..bbd8396978 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -672,6 +672,18 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
bool first = true;
for ( ; i != args.end(); ++i )
{
+ if ( *i == "RECURSE_SYMLINKS_OFF" )
+ {
+ g.RecurseThroughSymlinksOff();
+ ++i;
+ if ( i == args.end() )
+ {
+ this->SetError(
+ "GLOB requires a glob expression after RECURSE_SYMLINKS_OFF");
+ return false;
+ }
+ }
+
if ( *i == "RELATIVE" )
{
++i; // skip RELATIVE
@@ -688,6 +700,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
return false;
}
}
+
if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) )
{
std::string expr = this->Makefile->GetCurrentDirectory();
@@ -706,6 +719,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
{
g.FindFiles(*i);
}
+
std::vector<std::string>::size_type cc;
std::vector<std::string>& files = g.GetFiles();
for ( cc = 0; cc < files.size(); cc ++ )
@@ -1486,7 +1500,8 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
bool have_ft = cmSystemTools::FileTimeGet(file, ft);
std::string emsg;
- if(!cmSystemTools::RemoveRPath(file, &emsg))
+ bool removed;
+ if(!cmSystemTools::RemoveRPath(file, &emsg, &removed))
{
cmOStringStream e;
e << "RPATH_REMOVE could not remove RPATH from file:\n"
@@ -1495,9 +1510,19 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
this->SetError(e.str().c_str());
success = false;
}
- if(success && have_ft)
+ if(success)
{
- cmSystemTools::FileTimeSet(file, ft);
+ if(removed)
+ {
+ std::string message = "Removed runtime path from \"";
+ message += file;
+ message += "\"";
+ this->Makefile->DisplayStatus(message.c_str(), -1);
+ }
+ if(have_ft)
+ {
+ cmSystemTools::FileTimeSet(file, ft);
+ }
}
cmSystemTools::FileTimeDelete(ft);
return success;
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index 4173859876..9343a63acf 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -77,7 +77,7 @@ public:
" [NO_HEX_CONVERSION])\n"
" file(GLOB variable [RELATIVE path] [globbing expressions]...)\n"
" file(GLOB_RECURSE variable [RELATIVE path] \n"
- " [globbing expressions]...)\n"
+ " [RECURSE_SYMLINKS_OFF] [globbing expressions]...)\n"
" file(REMOVE [file1 ...])\n"
" file(REMOVE_RECURSE [file1 ...])\n"
" file(MAKE_DIRECTORY [directory1 directory2 ...])\n"
@@ -126,7 +126,9 @@ public:
" f[3-5].txt - match files f3.txt, f4.txt, f5.txt\n"
"GLOB_RECURSE will generate similar list as the regular GLOB, except "
"it will traverse all the subdirectories of the matched directory and "
- "match the files.\n"
+ "match the files. Subdirectories that are symlinks are traversed by "
+ "default to match the behavior of older CMake releases. Use "
+ "RECURSE_SYMLINKS_OFF to prevent recursion through symlinks.\n"
"Examples of recursive globbing include:\n"
" /dir/*.py - match all python files in /dir and subdirectories\n"
"MAKE_DIRECTORY will create the given directories, also if their parent "
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index f4e36e077e..f130ba2275 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -63,6 +63,7 @@ cmFindPackageCommand::cmFindPackageCommand()
this->NoBuilds = false;
this->NoModule = false;
this->DebugMode = false;
+ this->UseLib64Paths = false;
this->VersionMajor = 0;
this->VersionMinor = 0;
this->VersionPatch = 0;
@@ -298,6 +299,18 @@ bool cmFindPackageCommand
// Check for debug mode.
this->DebugMode = this->Makefile->IsOn("CMAKE_FIND_DEBUG_MODE");
+ // Lookup whether lib64 paths should be used.
+ if(const char* sizeof_dptr =
+ this->Makefile->GetDefinition("CMAKE_SIZEOF_VOID_P"))
+ {
+ if(atoi(sizeof_dptr) == 8 &&
+ this->Makefile->GetCMakeInstance()
+ ->GetPropertyAsBool("FIND_LIBRARY_USE_LIB64_PATHS"))
+ {
+ this->UseLib64Paths = true;
+ }
+ }
+
// Find the current root path mode.
this->SelectDefaultRootPathMode();
@@ -1457,16 +1470,12 @@ private:
class cmFileListGeneratorEnumerate: public cmFileListGeneratorBase
{
public:
- cmFileListGeneratorEnumerate(const char* p1, const char* p2):
- cmFileListGeneratorBase()
- {
- this->Vector.push_back(p1);
- this->Vector.push_back(p2);
- }
+ cmFileListGeneratorEnumerate(std::vector<std::string> const& v):
+ cmFileListGeneratorBase(), Vector(v) {}
cmFileListGeneratorEnumerate(cmFileListGeneratorEnumerate const& r):
cmFileListGeneratorBase(), Vector(r.Vector) {}
private:
- std::vector<std::string> Vector;
+ std::vector<std::string> const& Vector;
virtual bool Search(std::string const& parent, cmFileList& lister)
{
for(std::vector<std::string>::const_iterator i = this->Vector.begin();
@@ -1716,12 +1725,21 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
}
}
+ // Construct list of common install locations (lib and share).
+ std::vector<std::string> common;
+ if(this->UseLib64Paths)
+ {
+ common.push_back("lib64");
+ }
+ common.push_back("lib");
+ common.push_back("share");
+
// PREFIX/(share|lib)/(Foo|foo|FOO).*/
{
cmFindPackageFileList lister(this);
lister
/ cmFileListGeneratorFixed(prefix)
- / cmFileListGeneratorEnumerate("lib", "share")
+ / cmFileListGeneratorEnumerate(common)
/ cmFileListGeneratorProject(this->Names);
if(lister.Search())
{
@@ -1734,7 +1752,7 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
cmFindPackageFileList lister(this);
lister
/ cmFileListGeneratorFixed(prefix)
- / cmFileListGeneratorEnumerate("lib", "share")
+ / cmFileListGeneratorEnumerate(common)
/ cmFileListGeneratorProject(this->Names)
/ cmFileListGeneratorCaseInsensitive("cmake");
if(lister.Search())
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 9f3a59fdce..d5fe703dd0 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -124,6 +124,7 @@ private:
bool NoModule;
bool NoBuilds;
bool DebugMode;
+ bool UseLib64Paths;
std::vector<std::string> Names;
std::vector<std::string> Configs;
};
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index cf4abdd5e9..34f544cac3 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -764,7 +764,12 @@ void cmGlobalGenerator::Configure()
if ( !this->CMakeInstance->GetScriptMode() )
{
- this->CMakeInstance->UpdateProgress("Configuring done", -1);
+ const char* msg = "Configuring done";
+ if(cmSystemTools::GetErrorOccuredFlag())
+ {
+ msg = "Configuring incomplete, errors occurred!";
+ }
+ this->CMakeInstance->UpdateProgress(msg, -1);
}
}
@@ -860,7 +865,10 @@ void cmGlobalGenerator::Generate()
// Compute the inter-target dependencies.
{
cmComputeTargetDepends ctd(this);
- ctd.Compute();
+ if(!ctd.Compute())
+ {
+ return;
+ }
std::vector<cmTarget*> const& targets = ctd.GetTargets();
for(std::vector<cmTarget*>::const_iterator ti = targets.begin();
ti != targets.end(); ++ti)
diff --git a/Source/cmGlobalKdevelopGenerator.cxx b/Source/cmGlobalKdevelopGenerator.cxx
index eb760c8e4c..cdc4f42daa 100644
--- a/Source/cmGlobalKdevelopGenerator.cxx
+++ b/Source/cmGlobalKdevelopGenerator.cxx
@@ -280,9 +280,9 @@ void cmGlobalKdevelopGenerator
}
else
{
- // add all subdirectories to the kdevelop blacklist
- // so they are not monitored for added or removed files
- // since this is basically handled by adding files to the cmake files
+ // add all subdirectories which are cmake build directories to the
+ // kdevelop blacklist so they are not monitored for added or removed files
+ // since this is handled by adding files to the cmake files
cmsys::Directory d;
if (d.Load(projectDir.c_str()))
{
@@ -297,7 +297,12 @@ void cmGlobalKdevelopGenerator
tmp += nextFile;
if (cmSystemTools::FileIsDirectory(tmp.c_str()))
{
- this->Blacklist.push_back(nextFile);
+ tmp += "/CMakeCache.txt";
+ if ((nextFile == "CMakeFiles")
+ || (cmSystemTools::FileExists(tmp.c_str())))
+ {
+ this->Blacklist.push_back(nextFile);
+ }
}
}
}
@@ -471,10 +476,12 @@ void cmGlobalKdevelopGenerator
" <dontact>false</dontact>\n"
" <makebin>" << this->GlobalGenerator->GetLocalGenerators()[0]->
GetMakefile()->GetRequiredDefinition("CMAKE_BUILD_TOOL")
- << " VERBOSE=1 </makebin>\n"
+ << " </makebin>\n"
" <selectedenvironment>default</selectedenvironment>\n"
" <environments>\n"
- " <default/>\n"
+ " <default>\n"
+ " <envvar value=\"1\" name=\"VERBOSE\" />\n"
+ " </default>\n"
" </environments>\n"
" </make>\n";
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index fa883392de..918f6ad344 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -743,6 +743,7 @@ static cmVS7FlagTable cmVS7ExtraFlagTable[] =
cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
{"PrecompiledHeaderThrough", "Yu", "Precompiled Header Name", "",
cmVS7FlagTable::UserValueRequired},
+ {"WholeProgramOptimization", "LTCG", "WholeProgramOptimization", "TRUE", 0},
// Exception handling mode. If no entries match, it will be FALSE.
{"ExceptionHandling", "GX", "enable c++ exceptions", "TRUE", 0},
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 4ca55c53da..f9d4445577 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -689,7 +689,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
cmTarget::SourceFileFlags tsFlags =
cmtarget.GetTargetSourceFileFlags(*i);
- if(strcmp(filetype->GetString(), "\"compiled.mach-o.objfile\"") == 0)
+ if(strcmp(filetype->GetString(), "compiled.mach-o.objfile") == 0)
{
externalObjFiles.push_back(xsf);
}
@@ -1436,6 +1436,18 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
std::string version = target.GetFrameworkVersion();
buildSettings->AddAttribute("FRAMEWORK_VERSION",
this->CreateString(version.c_str()));
+
+ std::string plist = this->ComputeInfoPListLocation(target);
+ // Xcode will create the final version of Info.plist at build time,
+ // so let it replace the framework name. This avoids creating
+ // a per-configuration Info.plist file.
+ this->CurrentLocalGenerator
+ ->GenerateFrameworkInfoPList(&target, "$(EXECUTABLE_NAME)",
+ plist.c_str());
+ std::string path =
+ this->ConvertToRelativeForXCode(plist.c_str());
+ buildSettings->AddAttribute("INFOPLIST_FILE",
+ this->CreateString(path.c_str()));
}
else
{
@@ -1957,22 +1969,8 @@ void cmGlobalXCodeGenerator::AppendOrAddBuildSetting(cmXCodeObject* settings,
else
{
std::string oldValue = attr->GetString();
-
- // unescape escaped quotes internal to the string:
- cmSystemTools::ReplaceString(oldValue, "\\\"", "\"");
-
- // remove surrounding quotes, if any:
- std::string::size_type len = oldValue.length();
- if(oldValue[0] == '\"' && oldValue[len-1] == '\"')
- {
- oldValue = oldValue.substr(1, len-2);
- }
-
oldValue += " ";
oldValue += value;
-
- // SetString automatically escapes internal quotes and then surrounds
- // the result with quotes if necessary...
attr->SetString(oldValue.c_str());
}
}
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 517348c3f7..757f59828c 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -340,7 +340,7 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
argP1 = arg;
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
- }
+ }
// does a command exist
if (*arg == "COMMAND" && argP1 != newArgs.end())
{
@@ -357,6 +357,22 @@ bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
IncrementArguments(newArgs,argP1,argP2);
reducible = 1;
}
+ // does a target exist
+ if (*arg == "TARGET" && argP1 != newArgs.end())
+ {
+ if(makefile->FindTargetToUse((argP1)->c_str()))
+ {
+ *arg = "1";
+ }
+ else
+ {
+ *arg = "0";
+ }
+ newArgs.erase(argP1);
+ argP1 = arg;
+ IncrementArguments(newArgs,argP1,argP2);
+ reducible = 1;
+ }
// does a policy exist
if (*arg == "POLICY" && argP1 != newArgs.end())
{
diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h
index bdccdf30a9..532190acf4 100644
--- a/Source/cmIfCommand.h
+++ b/Source/cmIfCommand.h
@@ -142,6 +142,8 @@ public:
" if(POLICY policy-id)\n"
"True if the given name is an existing policy "
"(of the form CMP<NNNN>).\n"
+ " if(TARGET target-name)\n"
+ "True if the given name is an existing target, built or imported.\n"
" if(EXISTS file-name)\n"
" if(EXISTS directory-name)\n"
"True if the named file or directory exists. "
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 35e14ff11b..c1922631b5 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -101,6 +101,43 @@ void cmLocalGenerator::Configure()
// relative paths.
this->UseRelativePaths = this->Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS");
+ // Choose a maximum object file name length.
+ {
+#if defined(_WIN32) || defined(__CYGWIN__)
+ this->ObjectPathMax = 250;
+#else
+ this->ObjectPathMax = 1000;
+#endif
+ const char* plen = this->Makefile->GetDefinition("CMAKE_OBJECT_PATH_MAX");
+ if(plen && *plen)
+ {
+ unsigned int pmax;
+ if(sscanf(plen, "%u", &pmax) == 1)
+ {
+ if(pmax >= 128)
+ {
+ this->ObjectPathMax = pmax;
+ }
+ else
+ {
+ cmOStringStream w;
+ w << "CMAKE_OBJECT_PATH_MAX is set to " << pmax
+ << ", which is less than the minimum of 128. "
+ << "The value will be ignored.";
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+ }
+ else
+ {
+ cmOStringStream w;
+ w << "CMAKE_OBJECT_PATH_MAX is set to \"" << plen
+ << "\", which fails to parse as a positive integer. "
+ << "The value will be ignored.";
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+ }
+ }
+
this->Configured = true;
this->GetGlobalGenerator()->SetCurrentLocalGenerator(previousLg);
@@ -723,11 +760,7 @@ void cmLocalGenerator
}
}
break;
- case cmTarget::UTILITY:
- case cmTarget::GLOBAL_TARGET:
- case cmTarget::INSTALL_FILES:
- case cmTarget::INSTALL_PROGRAMS:
- case cmTarget::INSTALL_DIRECTORY:
+ default:
break;
}
}
@@ -1441,11 +1474,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
}
}
break;
- case cmTarget::UTILITY:
- case cmTarget::GLOBAL_TARGET:
- case cmTarget::INSTALL_FILES:
- case cmTarget::INSTALL_PROGRAMS:
- case cmTarget::INSTALL_DIRECTORY:
+ default:
break;
}
}
@@ -1714,6 +1743,7 @@ std::string cmLocalGenerator::GetRealDependency(const char* inName,
case cmTarget::STATIC_LIBRARY:
case cmTarget::SHARED_LIBRARY:
case cmTarget::MODULE_LIBRARY:
+ case cmTarget::UNKNOWN_LIBRARY:
{
// Get the location of the target's output file and depend on it.
if(const char* location = target->GetLocation(config))
@@ -2321,16 +2351,11 @@ cmLocalGeneratorShortenObjectName(std::string& objName,
}
}
-static bool cmLocalGeneratorCheckObjectName(std::string& objName,
- std::string::size_type dir_len)
+static
+bool cmLocalGeneratorCheckObjectName(std::string& objName,
+ std::string::size_type dir_len,
+ std::string::size_type max_total_len)
{
- // Choose a maximum file name length.
-#if defined(_WIN32) || defined(__CYGWIN__)
- std::string::size_type const max_total_len = 250;
-#else
- std::string::size_type const max_total_len = 1000;
-#endif
-
// Enforce the maximum file name length if possible.
std::string::size_type max_obj_len = max_total_len;
if(dir_len < max_total_len)
@@ -2421,7 +2446,7 @@ cmLocalGenerator
}
#if defined(CM_LG_ENCODE_OBJECT_NAMES)
- cmLocalGeneratorCheckObjectName(ssin, dir_len);
+ cmLocalGeneratorCheckObjectName(ssin, dir_len, this->ObjectPathMax);
#else
(void)dir_len;
#endif
@@ -2838,3 +2863,43 @@ void cmLocalGenerator::GenerateAppleInfoPList(cmTarget* target,
mf->ConfigureFile(inFile.c_str(), fname, false, false, false);
mf->PopScope();
}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::GenerateFrameworkInfoPList(cmTarget* target,
+ const char* targetName,
+ const char* fname)
+{
+ // Find the Info.plist template.
+ const char* in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST");
+ std::string inFile = (in && *in)? in : "MacOSXFrameworkInfo.plist.in";
+ if(!cmSystemTools::FileIsFullPath(inFile.c_str()))
+ {
+ std::string inMod = this->Makefile->GetModulesFile(inFile.c_str());
+ if(!inMod.empty())
+ {
+ inFile = inMod;
+ }
+ }
+ if(!cmSystemTools::FileExists(inFile.c_str(), true))
+ {
+ cmOStringStream e;
+ e << "Target " << target->GetName() << " Info.plist template \""
+ << inFile << "\" could not be found.";
+ cmSystemTools::Error(e.str().c_str());
+ return;
+ }
+
+ // Convert target properties to variables in an isolated makefile
+ // scope to configure the file. If properties are set they will
+ // override user make variables. If not the configuration will fall
+ // back to the directory-level values set by the user.
+ cmMakefile* mf = this->Makefile;
+ mf->PushScope();
+ mf->AddDefinition("MACOSX_FRAMEWORK_NAME", targetName);
+ cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_ICON_FILE");
+ cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_IDENTIFIER");
+ cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_SHORT_VERSION_STRING");
+ cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_BUNDLE_VERSION");
+ mf->ConfigureFile(inFile.c_str(), fname, false, false, false);
+ mf->PopScope();
+}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 6b3b7ea638..d528d2fccf 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -275,6 +275,13 @@ public:
*/
void GenerateAppleInfoPList(cmTarget* target, const char* targetName,
const char* fname);
+
+ /**
+ * Generate a Mac OS X framework Info.plist file.
+ */
+ void GenerateFrameworkInfoPList(cmTarget* target,
+ const char* targetName,
+ const char* fname);
protected:
/** Construct a comment for a custom command. */
std::string ConstructComment(const cmCustomCommand& cc,
@@ -348,6 +355,7 @@ protected:
std::vector<cmLocalGenerator*> Children;
std::map<cmStdString, cmStdString> LanguageToIncludeFlags;
std::map<cmStdString, cmStdString> UniqueObjectNamesMap;
+ std::string::size_type ObjectPathMax;
bool WindowsShell;
bool WindowsVSIDE;
bool WatcomWMake;
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 7e035e1880..102ca44bc5 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1222,24 +1222,27 @@ void cmMakefile::AddLinkLibraryForTarget(const char *target,
if(tgt)
{
// CMake versions below 2.4 allowed linking to modules.
- bool allowModules = this->NeedBackwardsCompatibility(2,3);
+ bool allowModules = this->NeedBackwardsCompatibility(2,2);
// if it is not a static or shared library then you can not link to it
if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) ||
(tgt->GetType() == cmTarget::SHARED_LIBRARY) ||
tgt->IsExecutableWithExports()))
{
cmOStringStream e;
- e << "Attempt to add link target " << lib << " of type: "
+ e << "Target \"" << lib << "\" of type "
<< cmTarget::TargetTypeNames[static_cast<int>(tgt->GetType())]
- << "\nto target " << target
- << ". One can only link to STATIC or SHARED libraries, or "
+ << " may not be linked into another target. "
+ << "One may link only to STATIC or SHARED libraries, or "
<< "to executables with the ENABLE_EXPORTS property set.";
// in older versions of cmake linking to modules was allowed
if( tgt->GetType() == cmTarget::MODULE_LIBRARY )
{
- e <<
- "\nTo allow linking of modules set "
- "CMAKE_BACKWARDS_COMPATIBILITY to 2.2 or lower\n";
+ e << "\n"
+ << "If you are developing a new project, re-organize it to avoid "
+ << "linking to modules. "
+ << "If you are just trying to build an existing project, "
+ << "set CMAKE_BACKWARDS_COMPATIBILITY to 2.2 or lower to allow "
+ << "linking to modules.";
}
// if no modules are allowed then this is always an error
if(!allowModules ||
@@ -1247,7 +1250,7 @@ void cmMakefile::AddLinkLibraryForTarget(const char *target,
// still an error
(allowModules && tgt->GetType() != cmTarget::MODULE_LIBRARY))
{
- cmSystemTools::Error(e.str().c_str());
+ this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
}
}
}
@@ -3460,50 +3463,59 @@ bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
return true;
}
-cmPolicies::PolicyStatus cmMakefile
-::GetPolicyStatus(cmPolicies::PolicyID id)
+//----------------------------------------------------------------------------
+cmPolicies::PolicyStatus
+cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id)
{
- cmPolicies::PolicyStatus status = cmPolicies::REQUIRED_IF_USED;
- PolicyMap::iterator mappos;
- int vecpos;
- bool done = false;
+ // Get the current setting of the policy.
+ cmPolicies::PolicyStatus cur = this->GetPolicyStatusInternal(id);
- // check our policy stack first
- for (vecpos = static_cast<int>(this->PolicyStack.size()) - 1;
- vecpos >= 0 && !done; vecpos--)
- {
- mappos = this->PolicyStack[vecpos].find(id);
- if (mappos != this->PolicyStack[vecpos].end())
+ // If the policy is required to be set to NEW but is not, ignore the
+ // current setting and tell the caller.
+ if(cur != cmPolicies::NEW)
{
- status = mappos->second;
- done = true;
+ if(cur == cmPolicies::REQUIRED_ALWAYS ||
+ cur == cmPolicies::REQUIRED_IF_USED)
+ {
+ return cur;
+ }
+ cmPolicies::PolicyStatus def = this->GetPolicies()->GetPolicyStatus(id);
+ if(def == cmPolicies::REQUIRED_ALWAYS ||
+ def == cmPolicies::REQUIRED_IF_USED)
+ {
+ return def;
+ }
}
- }
-
- // if not found then
- if (!done)
- {
- // pass the buck to our parent if we have one
- if (this->LocalGenerator->GetParent())
+
+ // The current setting is okay.
+ return cur;
+}
+
+//----------------------------------------------------------------------------
+cmPolicies::PolicyStatus
+cmMakefile::GetPolicyStatusInternal(cmPolicies::PolicyID id)
+{
+ // Is the policy set in our stack?
+ for(std::vector<PolicyMap>::reverse_iterator
+ psi = this->PolicyStack.rbegin();
+ psi != this->PolicyStack.rend(); ++psi)
{
- cmMakefile *parent =
- this->LocalGenerator->GetParent()->GetMakefile();
- return parent->GetPolicyStatus(id);
+ PolicyMap::const_iterator pse = psi->find(id);
+ if(pse != psi->end())
+ {
+ return pse->second;
+ }
}
- // otherwise use the default
- else
+
+ // If we have a parent directory, recurse up to it.
+ if(this->LocalGenerator->GetParent())
{
- status = this->GetPolicies()->GetPolicyStatus(id);
+ cmMakefile* parent = this->LocalGenerator->GetParent()->GetMakefile();
+ return parent->GetPolicyStatusInternal(id);
}
- }
-
- // warn if we see a REQUIRED_IF_USED above a OLD or WARN
- if (!this->GetPolicies()->IsValidUsedPolicyStatus(id,status))
- {
- return cmPolicies::REQUIRED_IF_USED;
- }
-
- return status;
+
+ // The policy is not set. Use the default for this CMake version.
+ return this->GetPolicies()->GetPolicyStatus(id);
}
bool cmMakefile::SetPolicy(const char *id,
@@ -3520,37 +3532,44 @@ bool cmMakefile::SetPolicy(const char *id,
return this->SetPolicy(pid,status);
}
-bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
+//----------------------------------------------------------------------------
+bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
cmPolicies::PolicyStatus status)
{
- // setting a REQUIRED_ALWAYS policy to WARN or OLD is an insta error
- if (this->GetPolicies()->
- IsValidPolicyStatus(id,status))
- {
- this->PolicyStack.back()[id] = status;
+ // A REQUIRED_ALWAYS policy may be set only to NEW.
+ if(status != cmPolicies::NEW &&
+ this->GetPolicies()->GetPolicyStatus(id) ==
+ cmPolicies::REQUIRED_ALWAYS)
+ {
+ std::string msg =
+ this->GetPolicies()->GetRequiredAlwaysPolicyError(id);
+ this->IssueMessage(cmake::FATAL_ERROR, msg.c_str());
+ return false;
+ }
- // Special hook for presenting compatibility variable as soon as
- // the user requests it.
- if(id == cmPolicies::CMP0001 &&
- (status == cmPolicies::WARN || status == cmPolicies::OLD))
+ // Store the setting.
+ this->PolicyStack.back()[id] = status;
+
+ // Special hook for presenting compatibility variable as soon as
+ // the user requests it.
+ if(id == cmPolicies::CMP0001 &&
+ (status == cmPolicies::WARN || status == cmPolicies::OLD))
+ {
+ if(!(this->GetCacheManager()
+ ->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
{
- if(!(this->GetCacheManager()
- ->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")))
- {
- // Set it to 2.4 because that is the last version where the
- // variable had meaning.
- this->AddCacheDefinition
- ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
- "For backwards compatibility, what version of CMake "
- "commands and "
- "syntax should this version of CMake try to support.",
- cmCacheManager::STRING);
- }
+ // Set it to 2.4 because that is the last version where the
+ // variable had meaning.
+ this->AddCacheDefinition
+ ("CMAKE_BACKWARDS_COMPATIBILITY", "2.4",
+ "For backwards compatibility, what version of CMake "
+ "commands and "
+ "syntax should this version of CMake try to support.",
+ cmCacheManager::STRING);
}
+ }
- return true;
- }
- return false;
+ return true;
}
bool cmMakefile::PushPolicy()
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 780b2fe071..f9d10b6ca8 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -900,6 +900,7 @@ private:
typedef std::map<cmPolicies::PolicyID,
cmPolicies::PolicyStatus> PolicyMap;
std::vector<PolicyMap> PolicyStack;
+ cmPolicies::PolicyStatus GetPolicyStatusInternal(cmPolicies::PolicyID id);
bool CheckCMP0000;
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 29be46ce78..ed7e7bc8ea 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -504,6 +504,7 @@ cmMakefileExecutableTargetGenerator::CreateAppBundle(std::string& targetName,
outpath += "MacOS";
cmSystemTools::MakeDirectory(outpath.c_str());
outpath += "/";
+ this->Makefile->AddCMakeDependFile(outpath.c_str());
// Configure the Info.plist file. Note that it needs the executable name
// to be set.
@@ -511,4 +512,5 @@ cmMakefileExecutableTargetGenerator::CreateAppBundle(std::string& targetName,
this->LocalGenerator->GenerateAppleInfoPList(this->Target,
targetName.c_str(),
plist.c_str());
+ this->Makefile->AddCMakeDependFile(plist.c_str());
}
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 7bd12a04e7..9c0cc38483 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -235,8 +235,17 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
}
//----------------------------------------------------------------------------
-void cmMakefileLibraryTargetGenerator::CreateFramework()
+void
+cmMakefileLibraryTargetGenerator
+::CreateFramework(std::string const& targetName)
{
+ // Configure the Info.plist file into the Resources directory.
+ this->MacContentFolders.insert("Resources");
+ std::string plist = this->MacContentDirectory + "Resources/Info.plist";
+ this->LocalGenerator->GenerateFrameworkInfoPList(this->Target,
+ targetName.c_str(),
+ plist.c_str());
+
// TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to
// drive rules to create these files at build time.
std::string oldName;
@@ -388,7 +397,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
if(this->Target->IsFrameworkOnApple())
{
outpath = this->MacContentDirectory;
- this->CreateFramework();
+ this->CreateFramework(targetName);
}
else if(relink)
{
diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h
index e5f9482fab..8aa17cd2cd 100644
--- a/Source/cmMakefileLibraryTargetGenerator.h
+++ b/Source/cmMakefileLibraryTargetGenerator.h
@@ -37,7 +37,7 @@ protected:
bool relink);
// MacOSX Framework support methods
void WriteFrameworkRules(bool relink);
- void CreateFramework();
+ void CreateFramework(std::string const& targetName);
// Store the computd framework version for OS X Frameworks.
std::string FrameworkVersion;
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 1b9ab96d5e..640e0e7d68 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -347,6 +347,7 @@ void cmPolicies::DefinePolicy(cmPolicies::PolicyID iD,
this->PolicyStringMap[idString] = iD;
}
+//----------------------------------------------------------------------------
bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
const char *version)
{
@@ -408,13 +409,18 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
}
// now loop over all the policies and set them as appropriate
+ std::vector<cmPolicies::PolicyID> ancientPolicies;
std::map<cmPolicies::PolicyID,cmPolicy *>::iterator i
= this->Policies.begin();
for (;i != this->Policies.end(); ++i)
{
if (i->second->IsPolicyNewerThan(majorVer,minorVer,patchVer))
{
- if (!mf->SetPolicy(i->second->ID, cmPolicies::WARN))
+ if(i->second->Status == cmPolicies::REQUIRED_ALWAYS)
+ {
+ ancientPolicies.push_back(i->first);
+ }
+ else if (!mf->SetPolicy(i->second->ID, cmPolicies::WARN))
{
return false;
}
@@ -427,105 +433,16 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
}
}
}
- return true;
-}
-// is this a valid status the listfile can set this policy to?
-bool cmPolicies::IsValidPolicyStatus(cmPolicies::PolicyID id,
- cmPolicies::PolicyStatus status)
-{
- // if they are setting a feature to anything other than OLD or WARN and the
- // feature is not known about then that is an error
- if (this->Policies.find(id) == this->Policies.end())
- {
- if (status == cmPolicies::WARN ||
- status == cmPolicies::OLD)
+ // Make sure the project does not use any ancient policies.
+ if(!ancientPolicies.empty())
{
- return true;
- }
- cmOStringStream error;
- error <<
- "Error: an attempt was made to enable the new behavior for " <<
- "a new feature that is in a later version of CMake than "
- "what you are runing, please upgrade to a newer version "
- "of CMake.";
- cmSystemTools::Error(error.str().c_str());
- return false;
- }
-
- // now we know the feature is defined, so the only issue is if someone is
- // setting it to WARN or OLD when the feature is REQUIRED_ALWAYS
- if ((status == cmPolicies::WARN ||
- status == cmPolicies::OLD) &&
- this->Policies[id]->Status == cmPolicies::REQUIRED_ALWAYS)
- {
- cmOStringStream error;
- error <<
- "Error: an attempt was made to enable the old behavior for " <<
- "a feature that is no longer supported. The feature in " <<
- "question is feature " <<
- id <<
- " which had new behavior introduced in CMake version " <<
- this->Policies[id]->GetVersionString() <<
- " please either update your CMakeLists files to conform to " <<
- "the new behavior " <<
- "or use an older version of CMake that still supports " <<
- "the old behavior. Run cmake --help-policies " <<
- id << " for more information.";
- cmSystemTools::Error(error.str().c_str());
+ this->DiagnoseAncientPolicies(ancientPolicies,
+ majorVer, minorVer, patchVer, mf);
+ cmSystemTools::SetFatalErrorOccured();
return false;
- }
-
- return true;
-}
-
-// is this a valid status the listfile can set this policy to?
-bool cmPolicies::IsValidUsedPolicyStatus(cmPolicies::PolicyID id,
- cmPolicies::PolicyStatus status)
-{
- // if they are setting a feature to anything other than OLD or WARN and the
- // feature is not known about then that is an error
- if (this->Policies.find(id) == this->Policies.end())
- {
- if (status == cmPolicies::WARN ||
- status == cmPolicies::OLD)
- {
- return true;
}
- cmOStringStream error;
- error <<
- "Error: an attempt was made to enable the new behavior for " <<
- "a new feature that is in a later version of CMake than "
- "what you are runing, please upgrade to a newer version "
- "of CMake.";
- cmSystemTools::Error(error.str().c_str());
- return false;
- }
- // now we know the feature is defined, so the only issue is if someone is
- // setting it to WARN or OLD when the feature is REQUIRED_ALWAYS
- if ((status == cmPolicies::WARN ||
- status == cmPolicies::OLD) &&
- (this->Policies[id]->Status == cmPolicies::REQUIRED_ALWAYS ||
- this->Policies[id]->Status == cmPolicies::REQUIRED_IF_USED))
- {
- cmOStringStream error;
- error <<
- "Error: an attempt was made to enable the old behavior for " <<
- "a feature that is no longer supported. The feature in " <<
- "question is feature " <<
- id <<
- " which had new behavior introduced in CMake version " <<
- this->Policies[id]->GetVersionString() <<
- " please either update your CMakeLists files to conform to " <<
- "the new behavior " <<
- "or use an older version of CMake that still supports " <<
- "the old behavior. Run cmake --help-policies " <<
- id << " for more information.";
- cmSystemTools::Error(error.str().c_str());
- return false;
- }
-
return true;
}
@@ -671,3 +588,48 @@ void cmPolicies::GetDocumentation(std::vector<cmDocumentationEntry>& v)
v.push_back(e);
}
}
+
+//----------------------------------------------------------------------------
+std::string
+cmPolicies::GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id)
+{
+ std::string pid = this->GetPolicyIDString(id);
+ cmOStringStream e;
+ e << "Policy " << pid << " may not be set to OLD behavior because this "
+ << "version of CMake no longer supports it. "
+ << "The policy was introduced in "
+ << "CMake version " << this->Policies[id]->GetVersionString()
+ << ", and use of NEW behavior is now required."
+ << "\n"
+ << "Please either update your CMakeLists.txt files to conform to "
+ << "the new behavior or use an older version of CMake that still "
+ << "supports the old behavior. "
+ << "Run cmake --help-policy " << pid << " for more information.";
+ return e.str();
+}
+
+//----------------------------------------------------------------------------
+void
+cmPolicies::DiagnoseAncientPolicies(std::vector<PolicyID> const& ancient,
+ unsigned int majorVer,
+ unsigned int minorVer,
+ unsigned int patchVer,
+ cmMakefile* mf)
+{
+ cmOStringStream e;
+ e << "The project requests behavior compatible with CMake version \""
+ << majorVer << "." << minorVer << "." << patchVer
+ << "\", which requires OLD the behavior for some policies:\n";
+ for(std::vector<PolicyID>::const_iterator
+ i = ancient.begin(); i != ancient.end(); ++i)
+ {
+ cmPolicy const* policy = this->Policies[*i];
+ e << " " << policy->IDString << ": " << policy->ShortDescription << "\n";
+ }
+ e << "However, this version of CMake no longer supports the OLD "
+ << "behavior for these policies. "
+ << "Please either update your CMakeLists.txt files to conform to "
+ << "the new behavior or use an older version of CMake that still "
+ << "supports the old behavior.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+}
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 7c9be18e3a..5284034cbc 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -75,20 +75,15 @@ public:
///! Set a policy level for this listfile
bool ApplyPolicyVersion(cmMakefile *mf, const char *version);
- ///! test to see if setting a policy to a specific value is valid
- bool IsValidPolicyStatus(cmPolicies::PolicyID id,
- cmPolicies::PolicyStatus status);
-
- ///! test to see if setting a policy to a specific value is valid, when used
- bool IsValidUsedPolicyStatus(cmPolicies::PolicyID id,
- cmPolicies::PolicyStatus status);
-
///! return a warning string for a given policy
std::string GetPolicyWarning(cmPolicies::PolicyID id);
///! return an error string for when a required policy is unspecified
std::string GetRequiredPolicyError(cmPolicies::PolicyID id);
+ ///! return an error string for when a required policy is unspecified
+ std::string GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id);
+
///! Get docs for policies
void GetDocumentation(std::vector<cmDocumentationEntry>& v);
@@ -96,7 +91,10 @@ public:
// might have to make these internal for VS6 not sure yet
std::map<PolicyID,cmPolicy *> Policies;
std::map<std::string,PolicyID> PolicyStringMap;
-
+
+ void DiagnoseAncientPolicies(std::vector<PolicyID> const& ancient,
+ unsigned int majorVer, unsigned int minorVer,
+ unsigned int patchVer, cmMakefile* mf);
};
#endif
diff --git a/Source/cmReturnCommand.h b/Source/cmReturnCommand.h
index d75cda5295..5aee88b18c 100644
--- a/Source/cmReturnCommand.h
+++ b/Source/cmReturnCommand.h
@@ -57,7 +57,7 @@ public:
*/
virtual const char* GetTerseDocumentation()
{
- return "Return from a directory or function.";
+ return "Return from a file, directory or function.";
}
/**
@@ -67,10 +67,14 @@ public:
{
return
" return()\n"
- "Returns from a directory or function. When this command is "
- "encountered, it caused process of the current function or "
- "directory to stop and control is return to the caller of the "
- "function, or the parent directory if any. Note that a macro "
+ "Returns from a file, directory or function. When this command is "
+ "encountered in an included file (via include() or find_package()), "
+ "it causes processing of the current file to stop and control is "
+ "returned to the including file. If it is encountered in a file which "
+ "is not included by another file, e.g. a CMakeLists.txt, control is "
+ "returned to the parent directory if there is one. "
+ "If return is called in a function, control is returned to the caller "
+ "of the function. Note that a macro "
"is not a function and does not handle return like a function does.";
}
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index 21eeaf122a..9d00e327aa 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -271,6 +271,9 @@ bool cmSetPropertyCommand::HandleTarget(cmTarget* target)
target->SetProperty(name, value);
}
+ // Check the resulting value.
+ target->CheckProperty(name, this->Makefile);
+
return true;
}
diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx
index 26615dc3ac..895386ab48 100644
--- a/Source/cmSetTargetPropertiesCommand.cxx
+++ b/Source/cmSetTargetPropertiesCommand.cxx
@@ -103,6 +103,7 @@ bool cmSetTargetPropertiesCommand
{
target->SetProperty(propertyPairs[k].c_str(),
propertyPairs[k+1].c_str());
+ target->CheckProperty(propertyPairs[k].c_str(), mf);
}
}
// if file is not already in the makefile, then add it
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index df32afc077..084eb7c675 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -222,7 +222,7 @@ bool cmStringCommand::HandleRegexCommand(std::vector<std::string> const& args)
{
if(args.size() < 6)
{
- this->SetError("sub-command REGEX, mode MATCH needs "
+ this->SetError("sub-command REGEX, mode REPLACE needs "
"at least 6 arguments total to command.");
return false;
}
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 4e1f9453ed..1d2a0cf49d 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -26,6 +26,7 @@
#if defined(CMAKE_BUILD_WITH_CMAKE)
# include <cmsys/Terminal.h>
#endif
+#include <cmsys/stl/algorithm>
#if defined(_WIN32)
# include <windows.h>
@@ -1392,7 +1393,9 @@ cmSystemTools::FileFormat cmSystemTools::GetFileFormat(const char* cext)
}
//std::string ext = cmSystemTools::LowerCase(cext);
std::string ext = cext;
- if ( ext == "c" || ext == ".c" ) { return cmSystemTools::C_FILE_FORMAT; }
+ if ( ext == "c" || ext == ".c" ||
+ ext == "m" || ext == ".m"
+ ) { return cmSystemTools::C_FILE_FORMAT; }
if (
ext == "C" || ext == ".C" ||
ext == "M" || ext == ".M" ||
@@ -1400,7 +1403,6 @@ cmSystemTools::FileFormat cmSystemTools::GetFileFormat(const char* cext)
ext == "cc" || ext == ".cc" ||
ext == "cpp" || ext == ".cpp" ||
ext == "cxx" || ext == ".cxx" ||
- ext == "m" || ext == ".m" ||
ext == "mm" || ext == ".mm"
) { return cmSystemTools::CXX_FILE_FORMAT; }
if (
@@ -2328,6 +2330,16 @@ std::string::size_type cmSystemToolsFindRPath(std::string const& have,
}
#endif
+#if defined(CMAKE_USE_ELF_PARSER)
+struct cmSystemToolsRPathInfo
+{
+ unsigned long Position;
+ unsigned long Size;
+ std::string Name;
+ std::string Value;
+};
+#endif
+
//----------------------------------------------------------------------------
bool cmSystemTools::ChangeRPath(std::string const& file,
std::string const& oldRPath,
@@ -2340,37 +2352,71 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
{
*changed = false;
}
- unsigned long rpathPosition = 0;
- unsigned long rpathSize = 0;
- std::string rpathPrefix;
- std::string rpathSuffix;
+ int rp_count = 0;
+ cmSystemToolsRPathInfo rp[2];
{
// Parse the ELF binary.
cmELF elf(file.c_str());
- // Get the RPATH or RUNPATH entry from it.
- cmELF::StringEntry const* se = elf.GetRPath();
- if(!se)
+ // Get the RPATH and RUNPATH entries from it.
+ int se_count = 0;
+ cmELF::StringEntry const* se[2] = {0, 0};
+ const char* se_name[2] = {0, 0};
+ if(cmELF::StringEntry const* se_rpath = elf.GetRPath())
{
- se = elf.GetRunPath();
+ se[se_count] = se_rpath;
+ se_name[se_count] = "RPATH";
+ ++se_count;
+ }
+ if(cmELF::StringEntry const* se_runpath = elf.GetRunPath())
+ {
+ se[se_count] = se_runpath;
+ se_name[se_count] = "RUNPATH";
+ ++se_count;
+ }
+ if(se_count == 0)
+ {
+ if(newRPath.empty())
+ {
+ // The new rpath is empty and there is no rpath anyway so it is
+ // okay.
+ return true;
+ }
+ else
+ {
+ if(emsg)
+ {
+ *emsg = "No valid ELF RPATH or RUNPATH entry exists in the file; ";
+ *emsg += elf.GetErrorMessage();
+ }
+ return false;
+ }
}
- if(se)
+ for(int i=0; i < se_count; ++i)
{
+ // If both RPATH and RUNPATH refer to the same string literal it
+ // needs to be changed only once.
+ if(rp_count && rp[0].Position == se[i]->Position)
+ {
+ continue;
+ }
+
// Make sure the current rpath contains the old rpath.
- std::string::size_type pos = cmSystemToolsFindRPath(se->Value, oldRPath);
+ std::string::size_type pos =
+ cmSystemToolsFindRPath(se[i]->Value, oldRPath);
if(pos == std::string::npos)
{
// If it contains the new rpath instead then it is okay.
- if(cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos)
+ if(cmSystemToolsFindRPath(se[i]->Value, newRPath) != std::string::npos)
{
- return true;
+ continue;
}
if(emsg)
{
cmOStringStream e;
- e << "The current RPATH is:\n"
- << " " << se->Value << "\n"
+ e << "The current " << se_name[i] << " is:\n"
+ << " " << se[i]->Value << "\n"
<< "which does not contain:\n"
<< " " << oldRPath << "\n"
<< "as was expected.";
@@ -2379,47 +2425,44 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
return false;
}
- // Store information about the entry.
- rpathPosition = se->Position;
- rpathSize = se->Size;
+ // Store information about the entry in the file.
+ rp[rp_count].Position = se[i]->Position;
+ rp[rp_count].Size = se[i]->Size;
+ rp[rp_count].Name = se_name[i];
- // Store the part of the path we must preserve.
- rpathPrefix = se->Value.substr(0, pos);
- rpathSuffix = se->Value.substr(pos+oldRPath.length(), oldRPath.npos);
- }
- else if(newRPath.empty())
- {
- // The new rpath is empty and there is no rpath anyway so it is
- // okay.
- return true;
- }
- else
- {
- if(emsg)
+ // Construct the new value which preserves the part of the path
+ // not being changed.
+ rp[rp_count].Value = se[i]->Value.substr(0, pos);
+ rp[rp_count].Value += newRPath;
+ rp[rp_count].Value += se[i]->Value.substr(pos+oldRPath.length(),
+ oldRPath.npos);
+
+ // Make sure there is enough room to store the new rpath and at
+ // least one null terminator.
+ if(rp[rp_count].Size < rp[rp_count].Value.length()+1)
{
- *emsg = "No valid ELF RPATH entry exists in the file; ";
- *emsg += elf.GetErrorMessage();
+ if(emsg)
+ {
+ *emsg = "The replacement path is too long for the ";
+ *emsg += se_name[i];
+ *emsg += " entry.";
+ }
+ return false;
}
- return false;
+
+ // This entry is ready for update.
+ ++rp_count;
}
}
- // Compute the full new rpath.
- std::string rpath = rpathPrefix;
- rpath += newRPath;
- rpath += rpathSuffix;
- // Make sure there is enough room to store the new rpath and at
- // least one null terminator.
- if(rpathSize < rpath.length()+1)
+ // If no runtime path needs to be changed, we are done.
+ if(rp_count == 0)
{
- if(emsg)
- {
- *emsg = "The replacement RPATH is too long.";
- }
- return false;
+ return true;
}
- // Open the file for update and seek to the RPATH position.
+ {
+ // Open the file for update.
std::ofstream f(file.c_str(),
std::ios::in | std::ios::out | std::ios::binary);
if(!f)
@@ -2430,40 +2473,50 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
}
return false;
}
- if(!f.seekp(rpathPosition))
+
+ // Store the new RPATH and RUNPATH strings.
+ for(int i=0; i < rp_count; ++i)
{
- if(emsg)
+ // Seek to the RPATH position.
+ if(!f.seekp(rp[i].Position))
{
- *emsg = "Error seeking to RPATH position.";
+ if(emsg)
+ {
+ *emsg = "Error seeking to ";
+ *emsg += rp[i].Name;
+ *emsg += " position.";
+ }
+ return false;
}
- return false;
- }
- // Write the new rpath. Follow it with enough null terminators to
- // fill the string table entry.
- f << rpath;
- for(unsigned long i=rpath.length(); i < rpathSize; ++i)
- {
- f << '\0';
- }
+ // Write the new rpath. Follow it with enough null terminators to
+ // fill the string table entry.
+ f << rp[i].Value;
+ for(unsigned long j=rp[i].Value.length(); j < rp[i].Size; ++j)
+ {
+ f << '\0';
+ }
- // Make sure everything was okay.
- if(f)
- {
- if(changed)
+ // Make sure it wrote correctly.
+ if(!f)
{
- *changed = true;
+ if(emsg)
+ {
+ *emsg = "Error writing the new ";
+ *emsg += rp[i].Name;
+ *emsg += " string to the file.";
+ }
+ return false;
}
- return true;
}
- else
+ }
+
+ // Everything was updated successfully.
+ if(changed)
{
- if(emsg)
- {
- *emsg = "Error writing the new rpath to the file.";
- }
- return false;
+ *changed = true;
}
+ return true;
#else
(void)file;
(void)oldRPath;
@@ -2475,57 +2528,95 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
}
//----------------------------------------------------------------------------
-bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
+bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
+ bool* removed)
{
#if defined(CMAKE_USE_ELF_PARSER)
- unsigned long rpathPosition = 0;
- unsigned long rpathSize = 0;
- unsigned long rpathEntryPosition = 0;
+ if(removed)
+ {
+ *removed = false;
+ }
+ int zeroCount = 0;
+ unsigned long zeroPosition[2] = {0,0};
+ unsigned long zeroSize[2] = {0,0};
+ unsigned long bytesBegin = 0;
std::vector<char> bytes;
{
// Parse the ELF binary.
cmELF elf(file.c_str());
- // Get the RPATH or RUNPATH entry from it.
- cmELF::StringEntry const* se = elf.GetRPath();
- if(!se)
+ // Get the RPATH and RUNPATH entries from it and sort them by index
+ // in the dynamic section header.
+ int se_count = 0;
+ cmELF::StringEntry const* se[2] = {0, 0};
+ if(cmELF::StringEntry const* se_rpath = elf.GetRPath())
{
- se = elf.GetRunPath();
+ se[se_count++] = se_rpath;
}
-
- if(se)
+ if(cmELF::StringEntry const* se_runpath = elf.GetRunPath())
+ {
+ se[se_count++] = se_runpath;
+ }
+ if(se_count == 0)
+ {
+ // There is no RPATH or RUNPATH anyway.
+ return true;
+ }
+ if(se_count == 2 && se[1]->IndexInSection < se[0]->IndexInSection)
{
- // Store information about the entry.
- rpathPosition = se->Position;
- rpathSize = se->Size;
- rpathEntryPosition = elf.GetDynamicEntryPosition(se->IndexInSection);
+ cmsys_stl::swap(se[0], se[1]);
+ }
- // Get the file range containing the rest of the DYNAMIC table
- // after the RPATH entry.
- unsigned long nextEntryPosition =
- elf.GetDynamicEntryPosition(se->IndexInSection+1);
- unsigned int count = elf.GetDynamicEntryCount();
- if(count == 0)
+ // Get the size of the dynamic section header.
+ unsigned int count = elf.GetDynamicEntryCount();
+ if(count == 0)
+ {
+ // This should happen only for invalid ELF files where a DT_NULL
+ // appears before the end of the table.
+ if(emsg)
{
- // This should happen only for invalid ELF files where a DT_NULL
- // appears before the end of the table.
- if(emsg)
- {
- *emsg = "DYNAMIC section contains a DT_NULL before the end.";
- }
- return false;
+ *emsg = "DYNAMIC section contains a DT_NULL before the end.";
}
- unsigned long nullEntryPosition = elf.GetDynamicEntryPosition(count);
+ return false;
+ }
+
+ // Save information about the string entries to be zeroed.
+ zeroCount = se_count;
+ for(int i=0; i < se_count; ++i)
+ {
+ zeroPosition[i] = se[i]->Position;
+ zeroSize[i] = se[i]->Size;
+ }
- // Allocate and fill a buffer with zeros.
- bytes.resize(nullEntryPosition - rpathEntryPosition, 0);
+ // Get the range of file positions corresponding to each entry and
+ // the rest of the table after them.
+ unsigned long entryBegin[3] = {0,0,0};
+ unsigned long entryEnd[2] = {0,0};
+ for(int i=0; i < se_count; ++i)
+ {
+ entryBegin[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection);
+ entryEnd[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection+1);
+ }
+ entryBegin[se_count] = elf.GetDynamicEntryPosition(count);
- // Read the part of the DYNAMIC section header that will move.
- // The remainder of the buffer will be left with zeros which
- // represent a DT_NULL entry.
- if(!elf.ReadBytes(nextEntryPosition,
- nullEntryPosition - nextEntryPosition,
- &bytes[0]))
+ // The data are to be written over the old table entries starting at
+ // the first one being removed.
+ bytesBegin = entryBegin[0];
+ unsigned long bytesEnd = entryBegin[se_count];
+
+ // Allocate a buffer to hold the part of the file to be written.
+ // Initialize it with zeros.
+ bytes.resize(bytesEnd - bytesBegin, 0);
+
+ // Read the part of the DYNAMIC section header that will move.
+ // The remainder of the buffer will be left with zeros which
+ // represent a DT_NULL entry.
+ char* data = &bytes[0];
+ for(int i=0; i < se_count; ++i)
+ {
+ // Read data between the entries being removed.
+ unsigned long sz = entryBegin[i+1] - entryEnd[i];
+ if(sz > 0 && !elf.ReadBytes(entryEnd[i], sz, data))
{
if(emsg)
{
@@ -2533,11 +2624,7 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
}
return false;
}
- }
- else
- {
- // There is no RPATH or RUNPATH anyway.
- return true;
+ data += sz;
}
}
@@ -2554,7 +2641,7 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
}
// Write the new DYNAMIC table header.
- if(!f.seekp(rpathEntryPosition))
+ if(!f.seekp(bytesBegin))
{
if(emsg)
{
@@ -2571,36 +2658,41 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
return false;
}
- // Fill the RPATH string with zero bytes.
- if(!f.seekp(rpathPosition))
+ // Fill the RPATH and RUNPATH strings with zero bytes.
+ for(int i=0; i < zeroCount; ++i)
{
- if(emsg)
+ if(!f.seekp(zeroPosition[i]))
{
- *emsg = "Error seeking to RPATH position.";
+ if(emsg)
+ {
+ *emsg = "Error seeking to RPATH position.";
+ }
+ return false;
+ }
+ for(unsigned long j=0; j < zeroSize[i]; ++j)
+ {
+ f << '\0';
+ }
+ if(!f)
+ {
+ if(emsg)
+ {
+ *emsg = "Error writing the empty rpath string to the file.";
+ }
+ return false;
}
- return false;
- }
- for(unsigned long i=0; i < rpathSize; ++i)
- {
- f << '\0';
}
- // Make sure everything was okay.
- if(f)
- {
- return true;
- }
- else
+ // Everything was updated successfully.
+ if(removed)
{
- if(emsg)
- {
- *emsg = "Error writing the empty rpath to the file.";
- }
- return false;
+ *removed = true;
}
+ return true;
#else
(void)file;
(void)emsg;
+ (void)removed;
return false;
#endif
}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 493ff714d4..1ff12bf48a 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -396,7 +396,8 @@ public:
bool* changed = 0);
/** Try to remove the RPATH from an ELF binary. */
- static bool RemoveRPath(std::string const& file, std::string* emsg = 0);
+ static bool RemoveRPath(std::string const& file, std::string* emsg = 0,
+ bool* removed = 0);
/** Check whether the RPATH in an ELF binary contains the path
given. */
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 7d49a0a2e9..0fbae69b8f 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -22,6 +22,7 @@
#include "cmGlobalGenerator.h"
#include "cmComputeLinkInformation.h"
#include "cmListFileCache.h"
+#include <cmsys/RegularExpression.hxx>
#include <map>
#include <set>
#include <queue>
@@ -30,7 +31,8 @@
const char* cmTarget::TargetTypeNames[] = {
"EXECUTABLE", "STATIC_LIBRARY",
"SHARED_LIBRARY", "MODULE_LIBRARY", "UTILITY", "GLOBAL_TARGET",
- "INSTALL_FILES", "INSTALL_PROGRAMS", "INSTALL_DIRECTORY"
+ "INSTALL_FILES", "INSTALL_PROGRAMS", "INSTALL_DIRECTORY",
+ "UNKNOWN_LIBRARY"
};
//----------------------------------------------------------------------------
@@ -245,7 +247,9 @@ void cmTarget::DefineProperties(cmake *cm)
"This property is used when loading settings for the <CONFIG> "
"configuration of an imported target. "
"Configuration names correspond to those provided by the project "
- "from which the target is imported.");
+ "from which the target is imported. "
+ "If set, this property completely overrides the generic property "
+ "for the named configuration.");
cm->DefineProperty
("IMPORTED_LINK_INTERFACE_LIBRARIES", cmProperty::TARGET,
@@ -253,7 +257,9 @@ void cmTarget::DefineProperties(cmake *cm)
"Lists libraries whose interface is included when an IMPORTED library "
"target is linked to another target. "
"The libraries will be included on the link line for the target. "
- "Ignored for non-imported targets.");
+ "Unlike the LINK_INTERFACE_LIBRARIES property, this property applies "
+ "to all imported target types, including STATIC libraries. "
+ "This property is ignored for non-imported targets.");
cm->DefineProperty
("IMPORTED_LINK_INTERFACE_LIBRARIES_<CONFIG>", cmProperty::TARGET,
@@ -261,7 +267,9 @@ void cmTarget::DefineProperties(cmake *cm)
"This property is used when loading settings for the <CONFIG> "
"configuration of an imported target. "
"Configuration names correspond to those provided by the project "
- "from which the target is imported.");
+ "from which the target is imported. "
+ "If set, this property completely overrides the generic property "
+ "for the named configuration.");
cm->DefineProperty
("IMPORTED_LOCATION", cmProperty::TARGET,
@@ -277,6 +285,7 @@ void cmTarget::DefineProperties(cmake *cm)
"For frameworks on OS X this is the location of the library file "
"symlink just inside the framework folder. "
"For DLLs this is the location of the \".dll\" part of the library. "
+ "For UNKNOWN libraries this is the location of the file to be linked. "
"Ignored for non-imported targets.");
cm->DefineProperty
@@ -398,13 +407,16 @@ void cmTarget::DefineProperties(cmake *cm)
"provided to the other target also. "
"If the list is empty then no transitive link dependencies will be "
"incorporated when this target is linked into another target even if "
- "the default set is non-empty.");
+ "the default set is non-empty. "
+ "This property is ignored for STATIC libraries.");
cm->DefineProperty
("LINK_INTERFACE_LIBRARIES_<CONFIG>", cmProperty::TARGET,
"Per-configuration list of public interface libraries for a target.",
"This is the configuration-specific version of "
- "LINK_INTERFACE_LIBRARIES.");
+ "LINK_INTERFACE_LIBRARIES. "
+ "If set, this property completely overrides the generic property "
+ "for the named configuration.");
cm->DefineProperty
("MAP_IMPORTED_CONFIG_<CONFIG>", cmProperty::TARGET,
@@ -577,6 +589,26 @@ void cmTarget::DefineProperties(cmake *cm)
"hard-code all the settings instead of using the target properties.");
cm->DefineProperty
+ ("MACOSX_FRAMEWORK_INFO_PLIST", cmProperty::TARGET,
+ "Specify a custom Info.plist template for a Mac OS X Framework.",
+ "An library target with FRAMEWORK enabled will be built as a "
+ "framework on Mac OS X. "
+ "By default its Info.plist file is created by configuring a template "
+ "called MacOSXFrameworkInfo.plist.in located in the CMAKE_MODULE_PATH. "
+ "This property specifies an alternative template file name which "
+ "may be a full path.\n"
+ "The following target properties may be set to specify content to "
+ "be configured into the file:\n"
+ " MACOSX_FRAMEWORK_ICON_FILE\n"
+ " MACOSX_FRAMEWORK_IDENTIFIER\n"
+ " MACOSX_FRAMEWORK_SHORT_VERSION_STRING\n"
+ " MACOSX_FRAMEWORK_BUNDLE_VERSION\n"
+ "CMake variables of the same name may be set to affect all targets "
+ "in a directory that do not have each specific property set. "
+ "If a custom Info.plist is specified by this property it may of course "
+ "hard-code all the settings instead of using the target properties.");
+
+ cm->DefineProperty
("ENABLE_EXPORTS", cmProperty::TARGET,
"Specify whether an executable exports symbols for loadable modules.",
"Normally an executable does not export any symbols because it is "
@@ -787,6 +819,16 @@ bool cmTarget::IsExecutableWithExports()
}
//----------------------------------------------------------------------------
+bool cmTarget::IsLinkable()
+{
+ return (this->GetType() == cmTarget::STATIC_LIBRARY ||
+ this->GetType() == cmTarget::SHARED_LIBRARY ||
+ this->GetType() == cmTarget::MODULE_LIBRARY ||
+ this->GetType() == cmTarget::UNKNOWN_LIBRARY ||
+ this->IsExecutableWithExports());
+}
+
+//----------------------------------------------------------------------------
bool cmTarget::IsFrameworkOnApple()
{
return (this->GetType() == cmTarget::SHARED_LIBRARY &&
@@ -1670,6 +1712,69 @@ void cmTarget::AppendProperty(const char* prop, const char* value)
}
//----------------------------------------------------------------------------
+static void cmTargetCheckLINK_INTERFACE_LIBRARIES(
+ const char* prop, const char* value, cmMakefile* context, bool imported
+ )
+{
+ // Look for link-type keywords in the value.
+ static cmsys::RegularExpression
+ keys("(^|;)(debug|optimized|general)(;|$)");
+ if(!keys.find(value))
+ {
+ return;
+ }
+
+ // Support imported and non-imported versions of the property.
+ const char* base = (imported?
+ "IMPORTED_LINK_INTERFACE_LIBRARIES" :
+ "LINK_INTERFACE_LIBRARIES");
+
+ // Report an error.
+ cmOStringStream e;
+ e << "Property " << prop << " may not contain link-type keyword \""
+ << keys.match(2) << "\". "
+ << "The " << base << " property has a per-configuration "
+ << "version called " << base << "_<CONFIG> which may be "
+ << "used to specify per-configuration rules.";
+ if(!imported)
+ {
+ e << " "
+ << "Alternatively, an IMPORTED library may be created, configured "
+ << "with a per-configuration location, and then named in the "
+ << "property value. "
+ << "See the add_library command's IMPORTED mode for details."
+ << "\n"
+ << "If you have a list of libraries that already contains the "
+ << "keyword, use the target_link_libraries command with its "
+ << "LINK_INTERFACE_LIBRARIES mode to set the property. "
+ << "The command automatically recognizes link-type keywords and sets "
+ << "the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG "
+ << "properties accordingly.";
+ }
+ context->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::CheckProperty(const char* prop, cmMakefile* context)
+{
+ // Certain properties need checking.
+ if(strncmp(prop, "LINK_INTERFACE_LIBRARIES", 24) == 0)
+ {
+ if(const char* value = this->GetProperty(prop))
+ {
+ cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, false);
+ }
+ }
+ if(strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES", 33) == 0)
+ {
+ if(const char* value = this->GetProperty(prop))
+ {
+ cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, true);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
void cmTarget::MarkAsImported()
{
this->IsImportedTarget = true;
@@ -1860,7 +1965,8 @@ const char *cmTarget::GetProperty(const char* prop,
if(this->GetType() == cmTarget::EXECUTABLE ||
this->GetType() == cmTarget::STATIC_LIBRARY ||
this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY)
+ this->GetType() == cmTarget::MODULE_LIBRARY ||
+ this->GetType() == cmTarget::UNKNOWN_LIBRARY)
{
if(!this->IsImported() && strcmp(prop,"LOCATION") == 0)
{
@@ -1957,6 +2063,9 @@ const char *cmTarget::GetProperty(const char* prop,
case cmTarget::INSTALL_DIRECTORY:
return "INSTALL_DIRECTORY";
// break; /* unreachable */
+ case cmTarget::UNKNOWN_LIBRARY:
+ return "UNKNOWN_LIBRARY";
+ // break; /* unreachable */
}
return 0;
}
@@ -2043,11 +2152,7 @@ const char* cmTarget::GetCreateRuleVariable()
return "_CREATE_SHARED_MODULE";
case cmTarget::EXECUTABLE:
return "_LINK_EXECUTABLE";
- case cmTarget::UTILITY:
- case cmTarget::GLOBAL_TARGET:
- case cmTarget::INSTALL_FILES:
- case cmTarget::INSTALL_PROGRAMS:
- case cmTarget::INSTALL_DIRECTORY:
+ default:
break;
}
return "";
@@ -2073,11 +2178,7 @@ const char* cmTarget::GetSuffixVariableInternal(TargetType type,
return (implib
? "CMAKE_IMPORT_LIBRARY_SUFFIX"
: "CMAKE_EXECUTABLE_SUFFIX");
- case cmTarget::UTILITY:
- case cmTarget::GLOBAL_TARGET:
- case cmTarget::INSTALL_FILES:
- case cmTarget::INSTALL_PROGRAMS:
- case cmTarget::INSTALL_DIRECTORY:
+ default:
break;
}
return "";
@@ -2102,11 +2203,7 @@ const char* cmTarget::GetPrefixVariableInternal(TargetType type,
: "CMAKE_SHARED_MODULE_PREFIX");
case cmTarget::EXECUTABLE:
return (implib? "CMAKE_IMPORT_LIBRARY_PREFIX" : "");
- case cmTarget::UTILITY:
- case cmTarget::GLOBAL_TARGET:
- case cmTarget::INSTALL_FILES:
- case cmTarget::INSTALL_PROGRAMS:
- case cmTarget::INSTALL_DIRECTORY:
+ default:
break;
}
return "";
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 7141e41849..695d9e81eb 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -80,7 +80,8 @@ public:
cmTarget();
enum TargetType { EXECUTABLE, STATIC_LIBRARY,
SHARED_LIBRARY, MODULE_LIBRARY, UTILITY, GLOBAL_TARGET,
- INSTALL_FILES, INSTALL_PROGRAMS, INSTALL_DIRECTORY};
+ INSTALL_FILES, INSTALL_PROGRAMS, INSTALL_DIRECTORY,
+ UNKNOWN_LIBRARY};
static const char* TargetTypeNames[];
enum CustomCommandType { PRE_BUILD, PRE_LINK, POST_BUILD };
@@ -244,6 +245,7 @@ public:
const char *GetProperty(const char *prop);
const char *GetProperty(const char *prop, cmProperty::ScopeType scope);
bool GetPropertyAsBool(const char *prop);
+ void CheckProperty(const char* prop, cmMakefile* context);
bool IsImported() const {return this->IsImportedTarget;}
@@ -393,6 +395,9 @@ public:
enabled. */
bool IsExecutableWithExports();
+ /** Return whether this target may be used to link another target. */
+ bool IsLinkable();
+
/** Return whether this target is a shared library Framework on
Apple. */
bool IsFrameworkOnApple();
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 8c06e071e1..0bccd27d78 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -16,6 +16,13 @@
=========================================================================*/
#include "cmTargetLinkLibrariesCommand.h"
+const char* cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[3] =
+{
+ "general",
+ "debug",
+ "optimized"
+};
+
// cmTargetLinkLibrariesCommand
bool cmTargetLinkLibrariesCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
@@ -32,57 +39,88 @@ bool cmTargetLinkLibrariesCommand
{
return true;
}
+
+ // Lookup the target for which libraries are specified.
+ this->Target =
+ this->Makefile->GetCMakeInstance()
+ ->GetGlobalGenerator()->FindTarget(0, args[0].c_str());
+ if(!this->Target)
+ {
+ cmOStringStream e;
+ e << "Cannot specify link libraries for target \"" << args[0] << "\" "
+ << "which is not built by this project.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+
+ // Keep track of link configuration specifiers.
+ cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
+ bool haveLLT = false;
+
+ // Start with primary linking and switch to link interface
+ // specification when the keyword is encountered.
+ this->DoingInterface = false;
+
// add libraries, nothe that there is an optional prefix
// of debug and optimized than can be used
- std::vector<std::string>::const_iterator i = args.begin();
-
- for(++i; i != args.end(); ++i)
+ for(unsigned int i=1; i < args.size(); ++i)
{
- if (*i == "debug")
+ if(args[i] == "LINK_INTERFACE_LIBRARIES")
+ {
+ this->DoingInterface = true;
+ if(i != 1)
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "The LINK_INTERFACE_LIBRARIES option must appear as the second "
+ "argument, just after the target name."
+ );
+ return true;
+ }
+ }
+ else if(args[i] == "debug")
{
- ++i;
- if(i == args.end())
+ if(haveLLT)
{
- this->SetError
- ("The \"debug\" argument must be followed by a library");
- return false;
+ this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::DEBUG);
}
- this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),i->c_str(),
- cmTarget::DEBUG);
+ llt = cmTarget::DEBUG;
+ haveLLT = true;
}
- else if (*i == "optimized")
+ else if(args[i] == "optimized")
{
- ++i;
- if(i == args.end())
+ if(haveLLT)
{
- this->SetError(
- "The \"optimized\" argument must be followed by a library");
- return false;
+ this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::OPTIMIZED);
}
- this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),i->c_str(),
- cmTarget::OPTIMIZED);
+ llt = cmTarget::OPTIMIZED;
+ haveLLT = true;
}
- else if (*i == "general")
+ else if(args[i] == "general")
{
- ++i;
- if(i == args.end())
+ if(haveLLT)
{
- this->SetError(
- "The \"general\" argument must be followed by a library");
- return false;
+ this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::GENERAL);
}
- this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),i->c_str(),
- cmTarget::GENERAL);
+ llt = cmTarget::GENERAL;
+ haveLLT = true;
+ }
+ else if(haveLLT)
+ {
+ // The link type was specified by the previous argument.
+ haveLLT = false;
+ this->HandleLibrary(args[i].c_str(), llt);
}
else
{
- // make sure the type is correct if it is currently general. So if you
+ // Lookup old-style cache entry if type is unspecified. So if you
// do a target_link_libraries(foo optimized bar) it will stay optimized
// and not use the lookup. As there maybe the case where someone has
// specifed that a library is both debug and optimized. (this check is
// only there for backwards compatibility when mixing projects built
// with old versions of CMake and new)
- cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
+ llt = cmTarget::GENERAL;
std::string linkType = args[0];
linkType += "_LINK_TYPE";
const char* linkTypeString =
@@ -98,8 +136,80 @@ bool cmTargetLinkLibrariesCommand
llt = cmTarget::OPTIMIZED;
}
}
- this->Makefile->AddLinkLibraryForTarget(args[0].c_str(),i->c_str(),llt);
+ this->HandleLibrary(args[i].c_str(), llt);
}
}
+
+ // Make sure the last argument was not a library type specifier.
+ if(haveLLT)
+ {
+ cmOStringStream e;
+ e << "The \"" << this->LinkLibraryTypeNames[llt]
+ << "\" argument must be followed by a library.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ }
+
+ // If the INTERFACE option was given, make sure the
+ // LINK_INTERFACE_LIBRARIES property exists. This allows the
+ // command to be used to specify an empty link interface.
+ if(this->DoingInterface &&
+ !this->Target->GetProperty("LINK_INTERFACE_LIBRARIES"))
+ {
+ this->Target->SetProperty("LINK_INTERFACE_LIBRARIES", "");
+ }
+
return true;
}
+
+//----------------------------------------------------------------------------
+void
+cmTargetLinkLibrariesCommand
+::LinkLibraryTypeSpecifierWarning(int left, int right)
+{
+ cmOStringStream w;
+ w << "Link library type specifier \""
+ << this->LinkLibraryTypeNames[left] << "\" is followed by specifier \""
+ << this->LinkLibraryTypeNames[right] << "\" instead of a library name. "
+ << "The first specifier will be ignored.";
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+}
+
+//----------------------------------------------------------------------------
+void
+cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
+ cmTarget::LinkLibraryType llt)
+{
+ // Handle normal case first.
+ if(!this->DoingInterface)
+ {
+ this->Makefile
+ ->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt);
+ return;
+ }
+
+ // Include this library in the link interface for the target.
+ if(llt == cmTarget::DEBUG)
+ {
+ // Put in only the DEBUG configuration interface.
+ this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES_DEBUG", lib);
+ }
+ else if(llt == cmTarget::OPTIMIZED)
+ {
+ // Put in only the non-DEBUG configuration interface.
+ this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib);
+
+ // Make sure the DEBUG configuration interface exists so that this
+ // one will not be used as a fall-back.
+ if(!this->Target->GetProperty("LINK_INTERFACE_LIBRARIES_DEBUG"))
+ {
+ this->Target->SetProperty("LINK_INTERFACE_LIBRARIES_DEBUG", "");
+ }
+ }
+ else
+ {
+ // Put in both the DEBUG and non-DEBUG configuration interfaces.
+ this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib);
+ this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES_DEBUG", lib);
+ }
+}
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
index de20533cba..cc37608b7d 100644
--- a/Source/cmTargetLinkLibrariesCommand.h
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -64,21 +64,55 @@ public:
virtual const char* GetFullDocumentation()
{
return
- " target_link_libraries(target library1\n"
- " <debug | optimized | general> library2\n"
- " ...)\n"
+ " target_link_libraries(<target> [lib1 [lib2 [...]]]\n"
+ " [[debug|optimized|general] <lib>] ...)\n"
"Specify a list of libraries to be linked into the specified target. "
- "The debug and optimized strings may be used to indicate that "
- "the next library listed is to be used only for that specific "
- "type of build. general indicates it is used for all build types "
- "and is assumed if not specified.\n"
"If any library name matches that of a target in the current project "
"a dependency will automatically be added in the build system to make "
- "sure the library being linked is up-to-date before the target links.";
+ "sure the library being linked is up-to-date before the target links."
+ "\n"
+ "A \"debug\", \"optimized\", or \"general\" keyword indicates that "
+ "the library immediately following it is to be used only for the "
+ "corresponding build configuration. "
+ "The \"debug\" keyword corresponds to the Debug configuration. "
+ "The \"optimized\" keyword corresponds to all other configurations. "
+ "The \"general\" keyword corresponds to all configurations, and is "
+ "purely optional (assumed if omitted). "
+ "Higher granularity may be achieved for per-configuration rules "
+ "by creating and linking to IMPORTED library targets. "
+ "See the IMPORTED mode of the add_library command for more "
+ "information. "
+ "\n"
+ "Library dependencies are transitive by default. "
+ "When this target is linked into another target then the libraries "
+ "linked to this target will appear on the link line for the other "
+ "target too. "
+ "See the LINK_INTERFACE_LIBRARIES target property to override the "
+ "set of transitive link dependencies for a target."
+ "\n"
+ " target_link_libraries(<target> LINK_INTERFACE_LIBRARIES\n"
+ " [[debug|optimized|general] <lib>] ...)\n"
+ "The LINK_INTERFACE_LIBRARIES mode appends the libraries "
+ "to the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG "
+ "target properties instead of using them for linking. "
+ "Libraries specified as \"debug\" are appended to the "
+ "the LINK_INTERFACE_LIBRARIES_DEBUG property. "
+ "Libraries specified as \"optimized\" are appended to the "
+ "the LINK_INTERFACE_LIBRARIES property. "
+ "Libraries specified as \"general\" (or without any keyword) are "
+ "appended to both properties."
+ ;
}
cmTypeMacro(cmTargetLinkLibrariesCommand, cmCommand);
private:
+ void LinkLibraryTypeSpecifierWarning(int left, int right);
+ static const char* LinkLibraryTypeNames[3];
+
+ cmTarget* Target;
+ bool DoingInterface;
+
+ void HandleLibrary(const char* lib, cmTarget::LinkLibraryType llt);
};
diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx
index b6c5be274d..0a430f546e 100644
--- a/Source/cmXCodeObject.cxx
+++ b/Source/cmXCodeObject.cxx
@@ -151,7 +151,9 @@ void cmXCodeObject::Print(std::ostream& out)
if(j->second->TypeValue == STRING)
{
- out << j->first << " = " << j->second->String << ";";
+ out << j->first << " = ";
+ j->second->PrintString(out);
+ out << ";";
}
else if(j->second->TypeValue == OBJECT_LIST)
{
@@ -160,7 +162,8 @@ void cmXCodeObject::Print(std::ostream& out)
{
if(j->second->List[k]->TypeValue == STRING)
{
- out << j->second->List[k]->String << ", ";
+ j->second->List[k]->PrintString(out);
+ out << ", ";
}
else
{
@@ -192,7 +195,9 @@ void cmXCodeObject::Print(std::ostream& out)
}
else if(object->TypeValue == STRING)
{
- out << i->first << " = " << object->String << ";" << separator;
+ out << i->first << " = ";
+ object->PrintString(out);
+ out << ";" << separator;
}
else
{
@@ -230,29 +235,32 @@ void cmXCodeObject::CopyAttributes(cmXCodeObject* copy)
}
//----------------------------------------------------------------------------
-void cmXCodeObject::SetString(const char* s)
+void cmXCodeObject::PrintString(std::ostream& os) const
{
- std::string ss = s;
- if(ss.size() == 0)
- {
- this->String = "\"\"";
- return;
- }
- // escape quotes
- cmSystemTools::ReplaceString(ss, "\"", "\\\"");
- bool needQuote = false;
- this->String = "";
- if(ss.find_first_of(" <>.+-=@") != ss.npos)
- {
- needQuote = true;
- }
- if(needQuote)
- {
- this->String = "\"";
- }
- this->String += ss;
- if(needQuote)
+ // The string needs to be quoted if it contains any characters
+ // considered special by the Xcode project file parser.
+ bool needQuote =
+ (this->String.empty() ||
+ this->String.find_first_of(" <>.+-=@") != this->String.npos);
+ const char* quote = needQuote? "\"" : "";
+
+ // Print the string, quoted and escaped as necessary.
+ os << quote;
+ for(std::string::const_iterator i = this->String.begin();
+ i != this->String.end(); ++i)
{
- this->String += "\"";
+ if(*i == '"')
+ {
+ // Escape double-quotes.
+ os << '\\';
+ }
+ os << *i;
}
+ os << quote;
+}
+
+//----------------------------------------------------------------------------
+void cmXCodeObject::SetString(const char* s)
+{
+ this->String = s;
}
diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h
index eecb0e099c..303fbf5e04 100644
--- a/Source/cmXCodeObject.h
+++ b/Source/cmXCodeObject.h
@@ -147,6 +147,8 @@ public:
std::vector<cmXCodeObject*> const& GetObjectList() { return this->List;}
void SetComment(const char* c) { this->Comment = c;}
protected:
+ void PrintString(std::ostream& os) const;
+
cmTarget* Target;
Type TypeValue;
cmStdString Id;
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index b89ce7ea71..94c27bf83d 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -1871,7 +1871,10 @@ int cmake::HandleDeleteCacheVariables(const char* var)
cmSystemTools::ExpandListArgument(std::string(var), argsSplit);
// erase the property to avoid infinite recursion
this->SetProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", "");
-
+ if(this->GetIsInTryCompile())
+ {
+ return 0;
+ }
cmCacheManager::CacheIterator ci = this->CacheManager->NewIterator();
std::vector<SaveCacheEntry> saved;
cmOStringStream warning;
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 601c060a99..ff57eca2b8 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -303,9 +303,6 @@ int main(int ac, char** av)
int do_cmake(int ac, char** av)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
- cmDocumentation doc;
-#endif
int nocwd = 0;
if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 )
@@ -316,7 +313,8 @@ int do_cmake(int ac, char** av)
}
#ifdef CMAKE_BUILD_WITH_CMAKE
- if(doc.CheckOptions(ac, av) || nocwd)
+ cmDocumentation doc;
+ if(doc.CheckOptions(ac, av, "-E") || nocwd)
{
// Construct and print requested documentation.
cmake hcm;
@@ -418,29 +416,29 @@ int do_cmake(int ac, char** av)
{
command = true;
}
- else if (strcmp(av[i], "-N") == 0)
+ else if (!command && strcmp(av[i], "-N") == 0)
{
view_only = true;
}
- else if (strcmp(av[i], "-L") == 0)
+ else if (!command && strcmp(av[i], "-L") == 0)
{
list_cached = true;
}
- else if (strcmp(av[i], "-LA") == 0)
+ else if (!command && strcmp(av[i], "-LA") == 0)
{
list_all_cached = true;
}
- else if (strcmp(av[i], "-LH") == 0)
+ else if (!command && strcmp(av[i], "-LH") == 0)
{
list_cached = true;
list_help = true;
}
- else if (strcmp(av[i], "-LAH") == 0)
+ else if (!command && strcmp(av[i], "-LAH") == 0)
{
list_all_cached = true;
list_help = true;
}
- else if (strncmp(av[i], "-P", strlen("-P")) == 0)
+ else if (!command && strncmp(av[i], "-P", strlen("-P")) == 0)
{
if ( i == ac -1 )
{
@@ -459,7 +457,6 @@ int do_cmake(int ac, char** av)
args.push_back(av[i]);
}
}
-
if(command)
{
int ret = cmake::ExecuteCMakeCommand(args);
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx
index 68586899ff..80fdf29acd 100644
--- a/Source/kwsys/Glob.cxx
+++ b/Source/kwsys/Glob.cxx
@@ -63,6 +63,10 @@ Glob::Glob()
this->Internals = new GlobInternals;
this->Recurse = false;
this->Relative = "";
+
+ this->RecurseThroughSymlinks = true;
+ // RecurseThroughSymlinks is true by default for backwards compatibility,
+ // not because it's a good idea...
}
//----------------------------------------------------------------------------
@@ -262,7 +266,11 @@ void Glob::RecurseDirectory(kwsys_stl::string::size_type start,
}
if ( kwsys::SystemTools::FileIsDirectory(realname.c_str()) )
{
- this->RecurseDirectory(start+1, realname, dir_only);
+ if (!kwsys::SystemTools::FileIsSymlink(realname.c_str()) ||
+ this->RecurseThroughSymlinks)
+ {
+ this->RecurseDirectory(start+1, realname, dir_only);
+ }
}
}
}
diff --git a/Source/kwsys/Glob.hxx.in b/Source/kwsys/Glob.hxx.in
index 7e2fb96a91..a66dd6f551 100644
--- a/Source/kwsys/Glob.hxx.in
+++ b/Source/kwsys/Glob.hxx.in
@@ -57,6 +57,13 @@ public:
void SetRecurse(bool i) { this->Recurse = i; }
bool GetRecurse() { return this->Recurse; }
+ //! Set recurse through symlinks to true if recursion should traverse the
+ // linked-to directories
+ void RecurseThroughSymlinksOn() { this->SetRecurseThroughSymlinks(true); }
+ void RecurseThroughSymlinksOff() { this->SetRecurseThroughSymlinks(false); }
+ void SetRecurseThroughSymlinks(bool i) { this->RecurseThroughSymlinks = i; }
+ bool GetRecurseThroughSymlinks() { return this->RecurseThroughSymlinks; }
+
//! Set relative to true to only show relative path to files.
void SetRelative(const char* dir);
const char* GetRelative();
@@ -90,6 +97,7 @@ protected:
GlobInternals* Internals;
bool Recurse;
kwsys_stl::string Relative;
+ bool RecurseThroughSymlinks;
private:
Glob(const Glob&); // Not implemented.
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index becd00462a..515bceb8c9 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -770,14 +770,14 @@ void kwsysProcess_Execute(kwsysProcess* cp)
return;
}
-#if !KWSYSPE_USE_SELECT
+ /* Set to non-blocking in case select lies, or for the polling
+ implementation. */
if(!kwsysProcessSetNonBlocking(p[0]))
{
kwsysProcessCleanup(cp, 1);
kwsysProcessCleanupDescriptor(&si.StdErr);
return;
}
-#endif
}
/* Replace the stderr pipe with a file if requested. In this case
@@ -830,14 +830,12 @@ void kwsysProcess_Execute(kwsysProcess* cp)
failed = 1;
}
-#if !KWSYSPE_USE_SELECT
- /* Set the output pipe of the last process to be non-blocking so
- we can poll it. */
- if(i == cp->NumberOfCommands-1 && !kwsysProcessSetNonBlocking(readEnd))
+ /* Set the output pipe of the last process to be non-blocking in
+ case select lies, or for the polling implementation. */
+ if(i == (cp->NumberOfCommands-1) && !kwsysProcessSetNonBlocking(readEnd))
{
failed = 1;
}
-#endif
if(failed)
{
@@ -1057,6 +1055,11 @@ static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
return 1;
}
}
+ else if(n < 0 && errno == EAGAIN)
+ {
+ /* No data are really ready. The select call lied. See the
+ "man select" page on Linux for cases when this occurs. */
+ }
else
{
/* We are done reading from this pipe. */
diff --git a/Tests/BundleTest/BundleLib.cxx b/Tests/BundleTest/BundleLib.cxx
index 4f353fba86..bab745e46f 100644
--- a/Tests/BundleTest/BundleLib.cxx
+++ b/Tests/BundleTest/BundleLib.cxx
@@ -3,6 +3,8 @@
#include <stdlib.h>
#include <unistd.h>
+#include <Carbon/Carbon.h>
+
int fileExists(char* filename)
{
#ifndef R_OK
@@ -49,6 +51,11 @@ int findBundleFile(char* exec, const char* file)
int foo(char *exec)
{
+ // Call a "Carbon" function...
+ //
+ CFBundleRef br = CFBundleGetMainBundle();
+ (void) br;
+
int res1 = findBundleFile(exec, "Resources/randomResourceFile.plist");
int res2 = findBundleFile(exec, "MacOS/SomeRandomFile.txt");
int res3 = findBundleFile(exec, "MacOS/ChangeLog.txt");
diff --git a/Tests/BundleTest/BundleSubDir/CMakeLists.txt b/Tests/BundleTest/BundleSubDir/CMakeLists.txt
index 3f7a5f1697..322b2a7d2f 100644
--- a/Tests/BundleTest/BundleSubDir/CMakeLists.txt
+++ b/Tests/BundleTest/BundleSubDir/CMakeLists.txt
@@ -12,7 +12,7 @@ SET_SOURCE_FILES_PROPERTIES(
SET_SOURCE_FILES_PROPERTIES(
"${BundleTest_SOURCE_DIR}/SomeRandomFile.txt"
- "${CMake_SOURCE_DIR}/ChangeLog.txt"
+ "${BundleTest_SOURCE_DIR}/../../ChangeLog.txt"
PROPERTIES
MACOSX_PACKAGE_LOCATION MacOS
)
@@ -21,11 +21,11 @@ ADD_EXECUTABLE(SecondBundle
MACOSX_BUNDLE
"${BundleTest_SOURCE_DIR}/BundleTest.cxx"
"${BundleTest_SOURCE_DIR}/SomeRandomFile.txt"
- "${CMake_SOURCE_DIR}/ChangeLog.txt"
+ "${BundleTest_SOURCE_DIR}/../../ChangeLog.txt"
"${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist"
)
TARGET_LINK_LIBRARIES(SecondBundle BundleTestLib)
-
+
# Test bundle installation.
INSTALL(TARGETS SecondBundle DESTINATION Applications)
diff --git a/Tests/BundleTest/BundleTest.cxx b/Tests/BundleTest/BundleTest.cxx
index 1e508ac09e..29d17dbbed 100644
--- a/Tests/BundleTest/BundleTest.cxx
+++ b/Tests/BundleTest/BundleTest.cxx
@@ -1,9 +1,20 @@
#include <stdio.h>
+#include <Carbon/Carbon.h>
+
extern int foo(char* exec);
int main(int argc, char* argv[])
{
printf("Started with: %d arguments\n", argc);
+
+ // Call a "Carbon" function... but pull in the link dependency on "-framework
+ // Carbon" via CMake's dependency chaining mechanism. This code exists to
+ // verify that the chaining mechanism works with "-framework blah" style
+ // link dependencies.
+ //
+ CFBundleRef br = CFBundleGetMainBundle();
+ (void) br;
+
return foo(argv[0]);
}
diff --git a/Tests/BundleTest/CMakeLists.txt b/Tests/BundleTest/CMakeLists.txt
index 3f95afb51b..5ccf2bf85d 100644
--- a/Tests/BundleTest/CMakeLists.txt
+++ b/Tests/BundleTest/CMakeLists.txt
@@ -17,24 +17,35 @@ SET_SOURCE_FILES_PROPERTIES(
SET_SOURCE_FILES_PROPERTIES(
SomeRandomFile.txt
- "${CMake_SOURCE_DIR}/ChangeLog.txt"
+ "${BundleTest_SOURCE_DIR}/../../ChangeLog.txt"
PROPERTIES
MACOSX_PACKAGE_LOCATION MacOS
)
SET(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}/foobar")
-# Test building a bundle linking to a shared library.
+# Test building a bundle linking to a shared library where the
+# shared library links to Carbon, but the executable does not
+# explicitly link to Carbon, but the executable does *depend*
+# on Carbon. There should be a link failure for the executable
+# if CMake's dependency chaining for libraries with "-framework
+# blah" style dependencies gets broken...
+#
ADD_LIBRARY(BundleTestLib SHARED BundleLib.cxx)
+TARGET_LINK_LIBRARIES(BundleTestLib "-framework Carbon")
+
ADD_EXECUTABLE(BundleTest
MACOSX_BUNDLE
BundleTest.cxx
SomeRandomFile.txt
- "${CMake_SOURCE_DIR}/ChangeLog.txt"
+ "${BundleTest_SOURCE_DIR}/../../ChangeLog.txt"
"${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist"
)
-
TARGET_LINK_LIBRARIES(BundleTest BundleTestLib)
+#
+# DO NOT: TARGET_LINK_LIBRARIES(BundleTest "-framework Carbon")
+# (see above comments about Carbon)
+#
# Test bundle installation.
#INSTALL(TARGETS BundleTestLib DESTINATION Applications/BundleTestExe.app/Contents/Plugins)
diff --git a/Tests/Complex/CMakeLists.txt b/Tests/Complex/CMakeLists.txt
index 1814528cdd..d77e896029 100644
--- a/Tests/Complex/CMakeLists.txt
+++ b/Tests/Complex/CMakeLists.txt
@@ -7,6 +7,11 @@ PROJECT (Complex)
# Try setting a new policy. The IF test is for coverage.
IF(POLICY CMP0003)
CMAKE_POLICY(SET CMP0003 NEW)
+
+ CMAKE_POLICY(GET CMP0003 P3)
+ IF(NOT "${P3}" STREQUAL "NEW")
+ MESSAGE(FATAL_ERROR "CMAKE_POLICY(GET) did not report NEW!")
+ ENDIF(NOT "${P3}" STREQUAL "NEW")
ENDIF(POLICY CMP0003)
# Choose whether to test CMakeLib.
diff --git a/Tests/Complex/Executable/CMakeLists.txt b/Tests/Complex/Executable/CMakeLists.txt
index 1c406b90e1..9f64cbb152 100644
--- a/Tests/Complex/Executable/CMakeLists.txt
+++ b/Tests/Complex/Executable/CMakeLists.txt
@@ -16,6 +16,23 @@ IF(COMPLEX_TEST_CMAKELIB)
LINK_DIRECTORIES(${Complex_BINARY_DIR}/../../Utilities/cmtar)
ENDIF(COMPLEX_TEST_CMAKELIB)
+# Create an imported target for if(TARGET) test below.
+ADD_LIBRARY(ExeImportedTarget UNKNOWN IMPORTED)
+
+# Test if(TARGET) command.
+IF(NOT TARGET CMakeTestLibrary)
+ MESSAGE(FATAL_ERROR "IF(NOT TARGET CMakeTestLibrary) returned true!")
+ENDIF(NOT TARGET CMakeTestLibrary)
+IF(NOT TARGET ExeImportedTarget)
+ MESSAGE(FATAL_ERROR "IF(NOT TARGET ExeImportedTarget) returned true!")
+ENDIF(NOT TARGET ExeImportedTarget)
+IF(TARGET LibImportedTarget)
+ MESSAGE(FATAL_ERROR "IF(TARGET LibImportedTarget) returned true!")
+ENDIF(TARGET LibImportedTarget)
+IF(TARGET NotATarget)
+ MESSAGE(FATAL_ERROR "IF(TARGET NotATarget) returned true!")
+ENDIF(TARGET NotATarget)
+
# Use LINK_LIBRARIES instead of TARGET_LINK_LIBRARIES to
SET(COMPLEX_LIBS CMakeTestLibrary;CMakeTestLibraryShared;CMakeTestCLibraryShared)
LINK_LIBRARIES(${COMPLEX_LIBS})
diff --git a/Tests/Complex/Library/CMakeLists.txt b/Tests/Complex/Library/CMakeLists.txt
index 0fae1ec1e0..4f2e5a4aec 100644
--- a/Tests/Complex/Library/CMakeLists.txt
+++ b/Tests/Complex/Library/CMakeLists.txt
@@ -114,6 +114,10 @@ INSTALL_FILES(/tmp .cxx ${Complex_BINARY_DIR}/cmTestConfigure.h)
# Test creating a library that is not built by default.
ADD_LIBRARY(notInAllLib EXCLUDE_FROM_ALL notInAllLib.cxx)
+# Create an imported target for if(TARGET) test in Executable dir.
+# That test should not see this target.
+ADD_LIBRARY(LibImportedTarget UNKNOWN IMPORTED)
+
# Test generation of preprocessed sources.
IF("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM)
IF(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE)
diff --git a/Tests/ComplexOneConfig/CMakeLists.txt b/Tests/ComplexOneConfig/CMakeLists.txt
index 1814528cdd..d77e896029 100644
--- a/Tests/ComplexOneConfig/CMakeLists.txt
+++ b/Tests/ComplexOneConfig/CMakeLists.txt
@@ -7,6 +7,11 @@ PROJECT (Complex)
# Try setting a new policy. The IF test is for coverage.
IF(POLICY CMP0003)
CMAKE_POLICY(SET CMP0003 NEW)
+
+ CMAKE_POLICY(GET CMP0003 P3)
+ IF(NOT "${P3}" STREQUAL "NEW")
+ MESSAGE(FATAL_ERROR "CMAKE_POLICY(GET) did not report NEW!")
+ ENDIF(NOT "${P3}" STREQUAL "NEW")
ENDIF(POLICY CMP0003)
# Choose whether to test CMakeLib.
diff --git a/Tests/ComplexOneConfig/Executable/CMakeLists.txt b/Tests/ComplexOneConfig/Executable/CMakeLists.txt
index 1c406b90e1..9f64cbb152 100644
--- a/Tests/ComplexOneConfig/Executable/CMakeLists.txt
+++ b/Tests/ComplexOneConfig/Executable/CMakeLists.txt
@@ -16,6 +16,23 @@ IF(COMPLEX_TEST_CMAKELIB)
LINK_DIRECTORIES(${Complex_BINARY_DIR}/../../Utilities/cmtar)
ENDIF(COMPLEX_TEST_CMAKELIB)
+# Create an imported target for if(TARGET) test below.
+ADD_LIBRARY(ExeImportedTarget UNKNOWN IMPORTED)
+
+# Test if(TARGET) command.
+IF(NOT TARGET CMakeTestLibrary)
+ MESSAGE(FATAL_ERROR "IF(NOT TARGET CMakeTestLibrary) returned true!")
+ENDIF(NOT TARGET CMakeTestLibrary)
+IF(NOT TARGET ExeImportedTarget)
+ MESSAGE(FATAL_ERROR "IF(NOT TARGET ExeImportedTarget) returned true!")
+ENDIF(NOT TARGET ExeImportedTarget)
+IF(TARGET LibImportedTarget)
+ MESSAGE(FATAL_ERROR "IF(TARGET LibImportedTarget) returned true!")
+ENDIF(TARGET LibImportedTarget)
+IF(TARGET NotATarget)
+ MESSAGE(FATAL_ERROR "IF(TARGET NotATarget) returned true!")
+ENDIF(TARGET NotATarget)
+
# Use LINK_LIBRARIES instead of TARGET_LINK_LIBRARIES to
SET(COMPLEX_LIBS CMakeTestLibrary;CMakeTestLibraryShared;CMakeTestCLibraryShared)
LINK_LIBRARIES(${COMPLEX_LIBS})
diff --git a/Tests/ComplexOneConfig/Library/CMakeLists.txt b/Tests/ComplexOneConfig/Library/CMakeLists.txt
index 0fae1ec1e0..4f2e5a4aec 100644
--- a/Tests/ComplexOneConfig/Library/CMakeLists.txt
+++ b/Tests/ComplexOneConfig/Library/CMakeLists.txt
@@ -114,6 +114,10 @@ INSTALL_FILES(/tmp .cxx ${Complex_BINARY_DIR}/cmTestConfigure.h)
# Test creating a library that is not built by default.
ADD_LIBRARY(notInAllLib EXCLUDE_FROM_ALL notInAllLib.cxx)
+# Create an imported target for if(TARGET) test in Executable dir.
+# That test should not see this target.
+ADD_LIBRARY(LibImportedTarget UNKNOWN IMPORTED)
+
# Test generation of preprocessed sources.
IF("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM)
IF(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE)
diff --git a/Tests/ComplexRelativePaths/CMakeLists.txt b/Tests/ComplexRelativePaths/CMakeLists.txt
index 1814528cdd..d77e896029 100644
--- a/Tests/ComplexRelativePaths/CMakeLists.txt
+++ b/Tests/ComplexRelativePaths/CMakeLists.txt
@@ -7,6 +7,11 @@ PROJECT (Complex)
# Try setting a new policy. The IF test is for coverage.
IF(POLICY CMP0003)
CMAKE_POLICY(SET CMP0003 NEW)
+
+ CMAKE_POLICY(GET CMP0003 P3)
+ IF(NOT "${P3}" STREQUAL "NEW")
+ MESSAGE(FATAL_ERROR "CMAKE_POLICY(GET) did not report NEW!")
+ ENDIF(NOT "${P3}" STREQUAL "NEW")
ENDIF(POLICY CMP0003)
# Choose whether to test CMakeLib.
diff --git a/Tests/ComplexRelativePaths/Executable/CMakeLists.txt b/Tests/ComplexRelativePaths/Executable/CMakeLists.txt
index 1c406b90e1..9f64cbb152 100644
--- a/Tests/ComplexRelativePaths/Executable/CMakeLists.txt
+++ b/Tests/ComplexRelativePaths/Executable/CMakeLists.txt
@@ -16,6 +16,23 @@ IF(COMPLEX_TEST_CMAKELIB)
LINK_DIRECTORIES(${Complex_BINARY_DIR}/../../Utilities/cmtar)
ENDIF(COMPLEX_TEST_CMAKELIB)
+# Create an imported target for if(TARGET) test below.
+ADD_LIBRARY(ExeImportedTarget UNKNOWN IMPORTED)
+
+# Test if(TARGET) command.
+IF(NOT TARGET CMakeTestLibrary)
+ MESSAGE(FATAL_ERROR "IF(NOT TARGET CMakeTestLibrary) returned true!")
+ENDIF(NOT TARGET CMakeTestLibrary)
+IF(NOT TARGET ExeImportedTarget)
+ MESSAGE(FATAL_ERROR "IF(NOT TARGET ExeImportedTarget) returned true!")
+ENDIF(NOT TARGET ExeImportedTarget)
+IF(TARGET LibImportedTarget)
+ MESSAGE(FATAL_ERROR "IF(TARGET LibImportedTarget) returned true!")
+ENDIF(TARGET LibImportedTarget)
+IF(TARGET NotATarget)
+ MESSAGE(FATAL_ERROR "IF(TARGET NotATarget) returned true!")
+ENDIF(TARGET NotATarget)
+
# Use LINK_LIBRARIES instead of TARGET_LINK_LIBRARIES to
SET(COMPLEX_LIBS CMakeTestLibrary;CMakeTestLibraryShared;CMakeTestCLibraryShared)
LINK_LIBRARIES(${COMPLEX_LIBS})
diff --git a/Tests/ComplexRelativePaths/Library/CMakeLists.txt b/Tests/ComplexRelativePaths/Library/CMakeLists.txt
index 0fae1ec1e0..4f2e5a4aec 100644
--- a/Tests/ComplexRelativePaths/Library/CMakeLists.txt
+++ b/Tests/ComplexRelativePaths/Library/CMakeLists.txt
@@ -114,6 +114,10 @@ INSTALL_FILES(/tmp .cxx ${Complex_BINARY_DIR}/cmTestConfigure.h)
# Test creating a library that is not built by default.
ADD_LIBRARY(notInAllLib EXCLUDE_FROM_ALL notInAllLib.cxx)
+# Create an imported target for if(TARGET) test in Executable dir.
+# That test should not see this target.
+ADD_LIBRARY(LibImportedTarget UNKNOWN IMPORTED)
+
# Test generation of preprocessed sources.
IF("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM)
IF(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE)
diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt
index 293ac9b8e7..b8410e1835 100644
--- a/Tests/CustomCommand/CMakeLists.txt
+++ b/Tests/CustomCommand/CMakeLists.txt
@@ -98,7 +98,7 @@ ADD_CUSTOM_TARGET(TDocument ALL
COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1.h to doc2.h."
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1.h
${PROJECT_BINARY_DIR}/doc2.h
- DEPENDS ${PROJECT_BINARY_DIR}/doc1.h
+ DEPENDS ${PROJECT_BINARY_DIR}/doc1.h doc1.txt
COMMENT "Running top-level TDocument commands"
)
diff --git a/Tests/Dependency/CMakeLists.txt b/Tests/Dependency/CMakeLists.txt
index d2c1c1a259..d700374b04 100644
--- a/Tests/Dependency/CMakeLists.txt
+++ b/Tests/Dependency/CMakeLists.txt
@@ -52,3 +52,4 @@ ADD_SUBDIRECTORY(Exec4)
ADD_SUBDIRECTORY(Case1)
ADD_SUBDIRECTORY(Case2)
ADD_SUBDIRECTORY(Case3)
+ADD_SUBDIRECTORY(Case4)
diff --git a/Tests/Dependency/Case4/CMakeLists.txt b/Tests/Dependency/Case4/CMakeLists.txt
new file mode 100644
index 0000000000..87ab50722e
--- /dev/null
+++ b/Tests/Dependency/Case4/CMakeLists.txt
@@ -0,0 +1,23 @@
+project(CASE4 C)
+
+IF(CMAKE_ANSI_CFLAGS)
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
+ENDIF(CMAKE_ANSI_CFLAGS)
+
+# This is not really a circular dependency. "case4Bar" refers to a
+# third-party library that happens to match the executable name, which
+# is okay when the executable is not a linkable target (ENABLE_EXPORTS
+# is not set). This tests whether CMake avoids incorrectly reporting
+# a circular dependency. In practice case4Foo may be a shared
+# library, but we skip that here because we do not want it to actually
+# have to find the third-party library.
+add_library(case4Foo STATIC foo.c)
+target_link_libraries(case4Foo case4Bar)
+
+# The executable avoids linking to a library with its own name, which
+# has been a CMake-ism for a long time, so we will not get a link
+# failure. An imported target or executable with an OUTPUT_NAME set
+# may be used if the user really wants to link a third-party library
+# into an executable of the same name.
+add_executable(case4Bar bar.c)
+target_link_libraries(case4Bar case4Foo)
diff --git a/Tests/Dependency/Case4/bar.c b/Tests/Dependency/Case4/bar.c
new file mode 100644
index 0000000000..d0bb0c43c2
--- /dev/null
+++ b/Tests/Dependency/Case4/bar.c
@@ -0,0 +1,2 @@
+extern int foo();
+int main() { return foo(); }
diff --git a/Tests/Dependency/Case4/foo.c b/Tests/Dependency/Case4/foo.c
new file mode 100644
index 0000000000..9fe07f82f9
--- /dev/null
+++ b/Tests/Dependency/Case4/foo.c
@@ -0,0 +1 @@
+int foo() { return 0; }
diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
index 9f1bab3bfc..595530795c 100644
--- a/Tests/ExportImport/Export/CMakeLists.txt
+++ b/Tests/ExportImport/Export/CMakeLists.txt
@@ -35,6 +35,29 @@ set_property(TARGET testLib3 PROPERTY SOVERSION 3)
add_library(testLib4 SHARED testLib4.c)
set_property(TARGET testLib4 PROPERTY FRAMEWORK 1)
+# Work-around: Visual Studio 6 does not support per-target object files.
+set(VS6)
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
+ set(VS6 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
+
+# Test using the target_link_libraries command to set the
+# LINK_INTERFACE_LIBRARIES* properties. We construct two libraries
+# providing the same two symbols. In each library one of the symbols
+# will work and the other one will fail to link. The import part of
+# this test will try to use the symbol corresponding to the
+# configuration in which it is built. If the proper library is not
+# used via the link interface the import test will fail to link.
+add_library(testLib4lib STATIC testLib4lib.c)
+add_library(testLib4libdbg STATIC testLib4libopt.c testLib4libdbg${VS6}.c)
+add_library(testLib4libopt STATIC testLib4libdbg.c testLib4libopt${VS6}.c)
+set_property(TARGET testLib4libdbg PROPERTY COMPILE_DEFINITIONS LIB_DBG)
+set_property(TARGET testLib4libopt PROPERTY COMPILE_DEFINITIONS LIB_OPT)
+target_link_libraries(testLib4
+ LINK_INTERFACE_LIBRARIES
+ testLib4lib debug testLib4libdbg optimized testLib4libopt
+ )
+
add_executable(testExe3 testExe3.c)
set_property(TARGET testExe3 PROPERTY MACOSX_BUNDLE 1)
@@ -42,7 +65,7 @@ set_property(TARGET testExe3 PROPERTY MACOSX_BUNDLE 1)
install(
TARGETS
testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3
- testExe2lib
+ testExe2lib testLib4lib testLib4libdbg testLib4libopt
EXPORT exp
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib NAMELINK_SKIP
@@ -67,6 +90,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3
FILE ExportBuildTree.cmake
)
export(TARGETS testExe2 testLib4 testExe3 testExe2lib
+ testLib4lib testLib4libdbg testLib4libopt
NAMESPACE bld_
APPEND FILE ExportBuildTree.cmake
)
diff --git a/Tests/ExportImport/Export/testLib4lib.c b/Tests/ExportImport/Export/testLib4lib.c
new file mode 100644
index 0000000000..bf3c11ec65
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib4lib.c
@@ -0,0 +1,4 @@
+int testLib4lib(void)
+{
+ return 0;
+}
diff --git a/Tests/ExportImport/Export/testLib4libdbg.c b/Tests/ExportImport/Export/testLib4libdbg.c
new file mode 100644
index 0000000000..453f262828
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib4libdbg.c
@@ -0,0 +1,14 @@
+#ifdef LIB_DBG
+/* We are building in testLib4libdbg. Provide the correct symbol. */
+int testLib4libdbg(void)
+{
+ return 0;
+}
+#else
+/* We are not building in testLib4libdbg. Poison the symbol. */
+extern int testLib4libdbg_noexist(void);
+int testLib4libdbg(void)
+{
+ return testLib4libdbg_noexist();
+}
+#endif
diff --git a/Tests/ExportImport/Export/testLib4libdbg1.c b/Tests/ExportImport/Export/testLib4libdbg1.c
new file mode 100644
index 0000000000..cc56cf9337
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib4libdbg1.c
@@ -0,0 +1 @@
+#include "testLib4libdbg.c"
diff --git a/Tests/ExportImport/Export/testLib4libopt.c b/Tests/ExportImport/Export/testLib4libopt.c
new file mode 100644
index 0000000000..605edd05bf
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib4libopt.c
@@ -0,0 +1,14 @@
+#ifdef LIB_OPT
+/* We are building in testLib4libopt. Provide the correct symbol. */
+int testLib4libopt(void)
+{
+ return 0;
+}
+#else
+/* We are not building in testLib4libopt. Poison the symbol. */
+extern int testLib4libopt_noexist(void);
+int testLib4libopt(void)
+{
+ return testLib4libopt_noexist();
+}
+#endif
diff --git a/Tests/ExportImport/Export/testLib4libopt1.c b/Tests/ExportImport/Export/testLib4libopt1.c
new file mode 100644
index 0000000000..d9b55879d3
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib4libopt1.c
@@ -0,0 +1 @@
+#include "testLib4libopt.c"
diff --git a/Tests/ExportImport/Import/CMakeLists.txt b/Tests/ExportImport/Import/CMakeLists.txt
index 5a946edab9..1ac9d3a573 100644
--- a/Tests/ExportImport/Import/CMakeLists.txt
+++ b/Tests/ExportImport/Import/CMakeLists.txt
@@ -32,6 +32,7 @@ add_executable(imp_testExe1
# Try linking to a library imported from the install tree.
target_link_libraries(imp_testExe1 exp_testLib2 exp_testLib3 exp_testLib4)
+set_property(TARGET imp_testExe1 PROPERTY COMPILE_DEFINITIONS_DEBUG EXE_DBG)
# Try building a plugin to an executable imported from the install tree.
add_library(imp_mod1 MODULE imp_mod1.c)
@@ -57,6 +58,7 @@ add_executable(imp_testExe1b
# Try linking to a library imported from the build tree.
target_link_libraries(imp_testExe1b bld_testLib2 bld_testLib3 bld_testLib4)
+set_property(TARGET imp_testExe1b PROPERTY COMPILE_DEFINITIONS_DEBUG EXE_DBG)
# Try building a plugin to an executable imported from the build tree.
add_library(imp_mod1b MODULE imp_mod1.c)
diff --git a/Tests/ExportImport/Import/imp_testExe1.c b/Tests/ExportImport/Import/imp_testExe1.c
index 0fbb689ffb..6424d33994 100644
--- a/Tests/ExportImport/Import/imp_testExe1.c
+++ b/Tests/ExportImport/Import/imp_testExe1.c
@@ -3,9 +3,19 @@ extern int generated_by_testExe3();
extern int testLib2();
extern int testLib3();
extern int testLib4();
+extern int testLib4lib();
+
+/* Switch a symbol between debug and optimized builds to make sure the
+ proper library is found from the testLib4 link interface. */
+#ifdef EXE_DBG
+# define testLib4libcfg testLib4libdbg
+#else
+# define testLib4libcfg testLib4libopt
+#endif
+extern testLib4libcfg(void);
int main()
{
return (testLib2() + generated_by_testExe1() + testLib3() + testLib4()
- + generated_by_testExe3());
+ + generated_by_testExe3() + testLib4lib() + testLib4libcfg());
}
diff --git a/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt b/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt
index 57c429e53f..9f7b868735 100644
--- a/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt
+++ b/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt
@@ -10,8 +10,11 @@ IF ("${PROJECT_SOURCE_DIR}" STREQUAL "${ANOTHER_PROJ_SOURCE_DIR}")
GET_FILENAME_COMPONENT(DEEPDIR
${OutOfSource_BINARY_DIR}/../OutOfSourceDeep/deeper ABSOLUTE)
- # The maximum allowed path length on Windows is near this value.
- SET(MAXPATH "250")
+ # Test giving the generator a custom limit.
+ SET(CMAKE_OBJECT_PATH_MAX 220)
+
+ # Use a separate variable for computation.
+ SET(MAXPATH "${CMAKE_OBJECT_PATH_MAX}")
# VS8 adds "OutOfSource/SubDir/OutOfSourceSubdir/../../../" to the
# path of the source file for no good reason. Reduce the length
diff --git a/Tests/ReturnTest/CMakeLists.txt b/Tests/ReturnTest/CMakeLists.txt
index bd0966e013..7c9156bf83 100644
--- a/Tests/ReturnTest/CMakeLists.txt
+++ b/Tests/ReturnTest/CMakeLists.txt
@@ -84,6 +84,14 @@ else ("${subdirResult}" EQUAL 1)
failed ("subdir got: ${subdirResult}")
endif ("${subdirResult}" EQUAL 1)
+# check return from a file
+include(include_return.cmake)
+if ("${include_returnResult}" EQUAL 1)
+ pass ("include_return")
+else ("${include_returnResult}" EQUAL 1)
+ failed ("include_return got: ${include_returnResult}")
+endif ("${include_returnResult}" EQUAL 1)
+
# check return from within a macro
macro (mymacro)
set (foo 1)
diff --git a/Tests/ReturnTest/include_return.cmake b/Tests/ReturnTest/include_return.cmake
new file mode 100644
index 0000000000..7cea1fb2d4
--- /dev/null
+++ b/Tests/ReturnTest/include_return.cmake
@@ -0,0 +1,3 @@
+set(include_returnResult 1)
+return()
+set(include_returnResult 0)
diff --git a/Tests/SimpleInstall/CMakeLists.txt b/Tests/SimpleInstall/CMakeLists.txt
index 34914b6a3a..c204e64100 100644
--- a/Tests/SimpleInstall/CMakeLists.txt
+++ b/Tests/SimpleInstall/CMakeLists.txt
@@ -66,9 +66,13 @@ IF(STAGE2)
PATHS ${LIBPATHS}
DOC "Fourth library")
+ # Test importing a library found on disk.
+ ADD_LIBRARY(lib_test4 UNKNOWN IMPORTED)
+ SET_PROPERTY(TARGET lib_test4 PROPERTY IMPORTED_LOCATION ${TEST4_LIBRARY})
+
INCLUDE_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/MyTest/include)
ADD_EXECUTABLE (SimpleInstExeS2 inst2.cxx foo.c foo.h)
- TARGET_LINK_LIBRARIES(SimpleInstExeS2 ${TEST1_LIBRARY} ${TEST2_LIBRARY} ${TEST4_LIBRARY})
+ TARGET_LINK_LIBRARIES(SimpleInstExeS2 ${TEST1_LIBRARY} ${TEST2_LIBRARY} lib_test4)
SET(install_target SimpleInstExeS2)
IF("${TEST1_LIBRARY}" MATCHES "static")
diff --git a/Tests/SimpleInstallS2/CMakeLists.txt b/Tests/SimpleInstallS2/CMakeLists.txt
index 34914b6a3a..c204e64100 100644
--- a/Tests/SimpleInstallS2/CMakeLists.txt
+++ b/Tests/SimpleInstallS2/CMakeLists.txt
@@ -66,9 +66,13 @@ IF(STAGE2)
PATHS ${LIBPATHS}
DOC "Fourth library")
+ # Test importing a library found on disk.
+ ADD_LIBRARY(lib_test4 UNKNOWN IMPORTED)
+ SET_PROPERTY(TARGET lib_test4 PROPERTY IMPORTED_LOCATION ${TEST4_LIBRARY})
+
INCLUDE_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/MyTest/include)
ADD_EXECUTABLE (SimpleInstExeS2 inst2.cxx foo.c foo.h)
- TARGET_LINK_LIBRARIES(SimpleInstExeS2 ${TEST1_LIBRARY} ${TEST2_LIBRARY} ${TEST4_LIBRARY})
+ TARGET_LINK_LIBRARIES(SimpleInstExeS2 ${TEST1_LIBRARY} ${TEST2_LIBRARY} lib_test4)
SET(install_target SimpleInstExeS2)
IF("${TEST1_LIBRARY}" MATCHES "static")