diff options
author | Bill Hoffman <bill.hoffman@kitware.com> | 2006-06-30 13:49:00 -0400 |
---|---|---|
committer | Bill Hoffman <bill.hoffman@kitware.com> | 2006-06-30 13:49:00 -0400 |
commit | 4ba26894365dc33e6bb59ceea3bd8a0fbe4489e3 (patch) | |
tree | 20cf58cfd59ac3d6bc3e81075b10592765faba9d | |
parent | 9c76e082150eae48102b537c0f3f8556c18b8616 (diff) | |
download | cmake-4ba26894365dc33e6bb59ceea3bd8a0fbe4489e3.tar.gz |
ENH: merge main tree into branch
134 files changed, 3001 insertions, 928 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index b771dcbe54..12e21da80c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,11 +186,11 @@ IF(CMAKE_BUILD_ON_VISUAL_STUDIO) IF("CMake_HAVE_MFC" MATCHES "^CMake_HAVE_MFC$") SET(CHECK_INCLUDE_FILE_VAR "afxwin.h") CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckIncludeFile.cxx IMMEDIATE) + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx IMMEDIATE) MESSAGE(STATUS "Looking for MFC") TRY_COMPILE(CMake_HAVE_MFC ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckIncludeFile.cxx + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx CMAKE_FLAGS -DCMAKE_MFC_FLAG:STRING=2 -DCOMPILE_DEFINITIONS:STRING=-D_AFXDLL @@ -198,13 +198,13 @@ IF(CMAKE_BUILD_ON_VISUAL_STUDIO) IF(CMake_HAVE_MFC) MESSAGE(STATUS "Looking for MFC - found") SET(CMake_HAVE_MFC 1 CACHE INTERNAL "Have MFC?") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if MFC exists passed with the following output:\n" "${OUTPUT}\n\n") ELSE(CMake_HAVE_MFC) MESSAGE(STATUS "Looking for MFC - not found") SET(CMake_HAVE_MFC 0 CACHE INTERNAL "Have MFC?") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if MFC exists failed with the following output:\n" "${OUTPUT}\n\n") ENDIF(CMake_HAVE_MFC) diff --git a/ChangeLog.manual b/ChangeLog.manual index c7a8e173a4..5f727aaf93 100644 --- a/ChangeLog.manual +++ b/ChangeLog.manual @@ -1,3 +1,40 @@ +Changes in CMake 2.4.3 +* progress is now reported for each compile + +* location of CMakeTmp changed to a varible + +* CMAKE_COLOR_MAKEFILE cache variable available to turn off color output + +* fixes for FindQt4 on mac. + +* Better search paths for finding VTK + +* Fix relative path problems in ADD_SUBDIRECTORY + +* Fix long link commands on UNIX shells + +* Fix depend file names in makefiles for generated headers + +* CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS allows for if/endif without variable + +* Xcode multiple custom command problem fixed. + +* INSTALL_RPATH_USE_LINK_PATH when true will add the link path to the rpath + +* Add target/fast rules in the sub directories + +* Fix Visual stuido C and C++ targets to not add /TP and /TC + +* print a context when cmake errors occur + +* add rxvt-unicode, cygwin, and screen terminal support for color output + +* Fix crash in CMakeSetup when status line is long + +* make sure try compile files have a newline at the end + +* fix for hp itanium build + Changes in CMake 2.4.2 * Run symlink command from correct directory for executable versions diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake index 2cd31f9d97..4d7ced5b56 100644 --- a/Modules/CMakeDetermineCCompiler.cmake +++ b/Modules/CMakeDetermineCCompiler.cmake @@ -71,11 +71,11 @@ IF(NOT CMAKE_COMPILER_IS_GNUCC_RUN) IF(NOT CMAKE_COMPILER_RETURN) IF("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_GNU.*" ) SET(CMAKE_COMPILER_IS_GNUCC 1) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the C compiler is GNU succeeded with " "the following output:\n${CMAKE_COMPILER_OUTPUT}\n\n") ELSE("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_GNU.*" ) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the C compiler is GNU failed with " "the following output:\n${CMAKE_COMPILER_OUTPUT}\n\n") ENDIF("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_GNU.*" ) diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake index 72622b866a..35197eb5f4 100644 --- a/Modules/CMakeDetermineCXXCompiler.cmake +++ b/Modules/CMakeDetermineCXXCompiler.cmake @@ -54,11 +54,11 @@ IF(NOT CMAKE_COMPILER_IS_GNUCXX_RUN) IF(NOT CMAKE_COMPILER_RETURN) IF("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_GNU.*" ) SET(CMAKE_COMPILER_IS_GNUCXX 1) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the C++ compiler is GNU succeeded with " "the following output:\n${CMAKE_COMPILER_OUTPUT}\n\n") ELSE("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_GNU.*" ) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the C++ compiler is GNU failed with " "the following output:\n${CMAKE_COMPILER_OUTPUT}\n\n") ENDIF("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_GNU.*" ) @@ -73,6 +73,6 @@ ENDIF(NOT CMAKE_COMPILER_IS_GNUCXX_RUN) # configure all variables set in this file CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeCXXCompiler.cmake.in - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCXXCompiler.cmake IMMEDIATE) + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCXXCompiler.cmake IMMEDIATE) SET(CMAKE_CXX_COMPILER_ENV_VAR "CXX") diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake index 812a54454a..edec369763 100644 --- a/Modules/CMakeDetermineFortranCompiler.cmake +++ b/Modules/CMakeDetermineFortranCompiler.cmake @@ -91,11 +91,11 @@ IF(NOT CMAKE_COMPILER_IS_GNUG77_RUN) IF(NOT CMAKE_COMPILER_RETURN) IF("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_GNU.*" ) SET(CMAKE_COMPILER_IS_GNUG77 1) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the Fortran compiler is GNU succeeded with " "the following output:\n${CMAKE_COMPILER_OUTPUT}\n\n") ELSE("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_GNU.*" ) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the Fortran compiler is GNU failed with " "the following output:\n${CMAKE_COMPILER_OUTPUT}\n\n") ENDIF("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_GNU.*" ) @@ -111,6 +111,6 @@ ENDIF(NOT CMAKE_COMPILER_IS_GNUG77_RUN) # configure variables set in this file for fast reload later on CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeFortranCompiler.cmake.in - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeFortranCompiler.cmake IMMEDIATE) + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeFortranCompiler.cmake IMMEDIATE) MARK_AS_ADVANCED(CMAKE_AR) SET(CMAKE_Fortran_COMPILER_ENV_VAR "FC") diff --git a/Modules/CMakeDetermineJavaCompiler.cmake b/Modules/CMakeDetermineJavaCompiler.cmake index 2edb46d37a..3d31233199 100644 --- a/Modules/CMakeDetermineJavaCompiler.cmake +++ b/Modules/CMakeDetermineJavaCompiler.cmake @@ -84,6 +84,6 @@ MARK_AS_ADVANCED(CMAKE_Java_COMPILER) # configure variables set in this file for fast reload later on CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeJavaCompiler.cmake.in - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeJavaCompiler.cmake IMMEDIATE @ONLY) + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeJavaCompiler.cmake IMMEDIATE @ONLY) MARK_AS_ADVANCED(CMAKE_AR CMAKE_Java_COMPILER_FULLPATH) SET(CMAKE_Java_COMPILER_ENV_VAR "JAVA_COMPILER") diff --git a/Modules/CMakeDetermineRCCompiler.cmake b/Modules/CMakeDetermineRCCompiler.cmake index c5732b27aa..e48f21f17b 100644 --- a/Modules/CMakeDetermineRCCompiler.cmake +++ b/Modules/CMakeDetermineRCCompiler.cmake @@ -44,5 +44,5 @@ MARK_AS_ADVANCED(CMAKE_RC_COMPILER) # configure variables set in this file for fast reload later on CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeRCCompiler.cmake.in - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeRCCompiler.cmake IMMEDIATE) + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeRCCompiler.cmake IMMEDIATE) SET(CMAKE_RC_COMPILER_ENV_VAR "RC") diff --git a/Modules/CMakeDetermineSystem.cmake b/Modules/CMakeDetermineSystem.cmake index 5fa1d18b3e..a2c22b4387 100644 --- a/Modules/CMakeDetermineSystem.cmake +++ b/Modules/CMakeDetermineSystem.cmake @@ -74,10 +74,11 @@ IF(CMAKE_SYSTEM_VERSION) ENDIF(CMAKE_SYSTEM_VERSION) -FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log +FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "The system is: ${CMAKE_SYSTEM_NAME} - ${CMAKE_SYSTEM_VERSION} - ${CMAKE_SYSTEM_PROCESSOR}\n") # configure variables set in this file for fast reload CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeSystem.cmake.in - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeSystem.cmake IMMEDIATE) + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake + IMMEDIATE) diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake index 5ec250149b..efa6f2bf8b 100644 --- a/Modules/CMakeGenericSystem.cmake +++ b/Modules/CMakeGenericSystem.cmake @@ -34,6 +34,13 @@ IF(CMAKE_GENERATOR MATCHES "KDevelop3") ENDIF(CMAKE_GENERATOR MATCHES "KDevelop3") SET(CMAKE_VERBOSE_MAKEFILE ${CMAKE_INIT_VALUE} CACHE BOOL "If this value is on, makefiles will be generated without the .SILENT directive, and all commands will be echoed to the console during the make. This is useful for debugging only. With Visual Studio IDE projects all commands are done without /nologo.") +IF(CMAKE_GENERATOR MATCHES "Makefiles") + SET(CMAKE_COLOR_MAKEFILE ON CACHE BOOL + "Enable/Disable color output during build." + ) + MARK_AS_ADVANCED(CMAKE_COLOR_MAKEFILE) +ENDIF(CMAKE_GENERATOR MATCHES "Makefiles") + # Choose a default install prefix for this platform. IF(UNIX) SET(CMAKE_INSTALL_PREFIX "/usr/local" diff --git a/Modules/CMakeTestCCompiler.cmake b/Modules/CMakeTestCCompiler.cmake index baf32df9c1..0beadd8a1e 100644 --- a/Modules/CMakeTestCCompiler.cmake +++ b/Modules/CMakeTestCCompiler.cmake @@ -6,20 +6,20 @@ # any makefiles or projects. IF(NOT CMAKE_C_COMPILER_WORKS) MESSAGE(STATUS "Check for working C compiler: ${CMAKE_C_COMPILER}") - FILE(WRITE ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/testCCompiler.c + FILE(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler.c "#ifdef __cplusplus\n" "# error \"The CMAKE_C_COMPILER is set to a C++ compiler\"\n" "#endif\n" "int main(){return 0;}\n") TRY_COMPILE(CMAKE_C_COMPILER_WORKS ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/testCCompiler.c + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler.c OUTPUT_VARIABLE OUTPUT) SET(C_TEST_WAS_RUN 1) ENDIF(NOT CMAKE_C_COMPILER_WORKS) IF(NOT CMAKE_C_COMPILER_WORKS) MESSAGE(STATUS "Check for working C compiler: ${CMAKE_C_COMPILER} -- broken") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the C compiler works failed with " "the following output:\n${OUTPUT}\n\n") MESSAGE(FATAL_ERROR "The C compiler \"${CMAKE_C_COMPILER}\" " @@ -29,7 +29,7 @@ IF(NOT CMAKE_C_COMPILER_WORKS) ELSE(NOT CMAKE_C_COMPILER_WORKS) IF(C_TEST_WAS_RUN) MESSAGE(STATUS "Check for working C compiler: ${CMAKE_C_COMPILER} -- works") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the C compiler works passed with " "the following output:\n${OUTPUT}\n\n") ENDIF(C_TEST_WAS_RUN) @@ -41,6 +41,6 @@ ELSE(NOT CMAKE_C_COMPILER_WORKS) # the value for CMAKE_SIZEOF_VOID_P # configure variables set in this file for fast reload later on CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeCCompiler.cmake.in - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCCompiler.cmake IMMEDIATE) + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCCompiler.cmake IMMEDIATE) ENDIF(NOT CMAKE_C_COMPILER_WORKS) diff --git a/Modules/CMakeTestCXXCompiler.cmake b/Modules/CMakeTestCXXCompiler.cmake index ece768786d..0b0fefcd87 100644 --- a/Modules/CMakeTestCXXCompiler.cmake +++ b/Modules/CMakeTestCXXCompiler.cmake @@ -6,20 +6,20 @@ # any makefiles or projects. IF(NOT CMAKE_CXX_COMPILER_WORKS) MESSAGE(STATUS "Check for working CXX compiler: ${CMAKE_CXX_COMPILER}") - FILE(WRITE ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/testCXXCompiler.cxx + FILE(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCXXCompiler.cxx "#ifndef __cplusplus\n" "# error \"The CMAKE_CXX_COMPILER is set to a C compiler\"\n" "#endif\n" "int main(){return 0;}\n") TRY_COMPILE(CMAKE_CXX_COMPILER_WORKS ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/testCXXCompiler.cxx + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCXXCompiler.cxx OUTPUT_VARIABLE OUTPUT) SET(CXX_TEST_WAS_RUN 1) ENDIF(NOT CMAKE_CXX_COMPILER_WORKS) IF(NOT CMAKE_CXX_COMPILER_WORKS) MESSAGE(STATUS "Check for working CXX compiler: ${CMAKE_CXX_COMPILER} -- broken") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the CXX compiler works failed with " "the following output:\n${OUTPUT}\n\n") MESSAGE(FATAL_ERROR "The C++ compiler \"${CMAKE_CXX_COMPILER}\" " @@ -29,7 +29,7 @@ IF(NOT CMAKE_CXX_COMPILER_WORKS) ELSE(NOT CMAKE_CXX_COMPILER_WORKS) IF(CXX_TEST_WAS_RUN) MESSAGE(STATUS "Check for working CXX compiler: ${CMAKE_CXX_COMPILER} -- works") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the CXX compiler works passed with " "the following output:\n${OUTPUT}\n\n") ENDIF(CXX_TEST_WAS_RUN) diff --git a/Modules/CMakeTestFortranCompiler.cmake b/Modules/CMakeTestFortranCompiler.cmake index 3e003eeccd..cc8c565e63 100644 --- a/Modules/CMakeTestFortranCompiler.cmake +++ b/Modules/CMakeTestFortranCompiler.cmake @@ -6,20 +6,20 @@ # any makefiles or projects. IF(NOT CMAKE_Fortran_COMPILER_WORKS) MESSAGE(STATUS "Check for working Fortran compiler: ${CMAKE_Fortran_COMPILER}") - FILE(WRITE ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/testFortranCompiler.f " + FILE(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f " PROGRAM TESTFortran PRINT *, 'Hello' END ") TRY_COMPILE(CMAKE_Fortran_COMPILER_WORKS ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/testFortranCompiler.f + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f OUTPUT_VARIABLE OUTPUT) SET(FORTRAN_TEST_WAS_RUN 1) ENDIF(NOT CMAKE_Fortran_COMPILER_WORKS) IF(NOT CMAKE_Fortran_COMPILER_WORKS) MESSAGE(STATUS "Check for working Fortran compiler: ${CMAKE_Fortran_COMPILER} -- broken") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the Fortran compiler works failed with " "the following output:\n${OUTPUT}\n\n") MESSAGE(FATAL_ERROR "The Fortran compiler \"${CMAKE_Fortran_COMPILER}\" " @@ -29,7 +29,7 @@ IF(NOT CMAKE_Fortran_COMPILER_WORKS) ELSE(NOT CMAKE_Fortran_COMPILER_WORKS) IF(FORTRAN_TEST_WAS_RUN) MESSAGE(STATUS "Check for working Fortran compiler: ${CMAKE_Fortran_COMPILER} -- works") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the Fortran compiler works passed with " "the following output:\n${OUTPUT}\n\n") ENDIF(FORTRAN_TEST_WAS_RUN) @@ -41,23 +41,23 @@ IF(CMAKE_Fortran_COMPILER_WORKS) IF(DEFINED CMAKE_Fortran_COMPILER_SUPPORTS_F90) ELSE(DEFINED CMAKE_Fortran_COMPILER_SUPPORTS_F90) MESSAGE(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90") - FILE(WRITE ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/testFortranCompilerF90.f90 " + FILE(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompilerF90.f90 " PROGRAM TESTFortran90 stop = 1 ; do while ( stop .eq. 0 ) ; end do END PROGRAM TESTFortran90 ") TRY_COMPILE(CMAKE_Fortran_COMPILER_SUPPORTS_F90 ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/testFortranCompilerF90.f90 + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompilerF90.f90 OUTPUT_VARIABLE OUTPUT) IF(CMAKE_Fortran_COMPILER_SUPPORTS_F90) MESSAGE(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90 -- yes") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the Fortran compiler supports Fortran 90 passed with " "the following output:\n${OUTPUT}\n\n") SET(CMAKE_Fortran_COMPILER_SUPPORTS_F90 1 CACHE INTERNAL "") ELSE(CMAKE_Fortran_COMPILER_SUPPORTS_F90) MESSAGE(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90 -- no") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the Fortran compiler supports Fortran 90 failed with " "the following output:\n${OUTPUT}\n\n") SET(CMAKE_Fortran_COMPILER_SUPPORTS_F90 0 CACHE INTERNAL "") diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 316f269c11..18fe53a24f 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -1,3 +1,7 @@ +# Default output files will be CPackConfig.cmake and CPackSourceConfig.cmake. +# This can be overwritten with CPACK_OUTPUT_CONFIG_FILE and +# CPACK_SOURCE_OUTPUT_CONFIG_FILE. + # Pick a configuration file SET(cpack_input_file "${CMAKE_ROOT}/Templates/CPackConfig.cmake.in") IF(EXISTS "${CMAKE_SOURCE_DIR}/CPackConfig.cmake.in") @@ -16,6 +20,10 @@ MACRO(cpack_set_if_not_set name value) ENDMACRO(cpack_set_if_not_set) # Macro to encode variables for the configuration file +# find any varable that stars with CPACK and create a variable +# _CPACK_OTHER_VARIABLES_ that contains SET commands for +# each cpack variable. _CPACK_OTHER_VARIABLES_ is then +# used as an @ replacment in configure_file for the CPackConfig. MACRO(cpack_encode_variables) SET(_CPACK_OTHER_VARIABLES_) GET_CMAKE_PROPERTY(res VARIABLES) @@ -103,9 +111,14 @@ cpack_set_if_not_set(CPACK_TOPLEVEL_TAG "${CPACK_SYSTEM_NAME}") cpack_set_if_not_set(CPACK_NSIS_DISPLAY_NAME "@CPACK_PACKAGE_INSTALL_DIRECTORY@") +cpack_set_if_not_set(CPACK_OUTPUT_CONFIG_FILE + "${CMAKE_BINARY_DIR}/CPackConfig.cmake") + +cpack_set_if_not_set(CPACK_SOURCE_OUTPUT_CONFIG_FILE + "${CMAKE_BINARY_DIR}/CPackSourceConfig.cmake") + cpack_encode_variables() -CONFIGURE_FILE("${cpack_input_file}" - "${CMAKE_BINARY_DIR}/CPackConfig.cmake" @ONLY IMMEDIATE) +CONFIGURE_FILE("${cpack_input_file}" "${CPACK_OUTPUT_CONFIG_FILE}" @ONLY IMMEDIATE) # Generate source file cpack_set_if_not_set(CPACK_SOURCE_INSTALLED_DIRECTORIES @@ -125,4 +138,4 @@ SET(CPACK_STRIP_FILES "${CPACK_SOURCE_STRIP_FILES}") cpack_encode_variables() CONFIGURE_FILE("${cpack_source_input_file}" - "${CMAKE_BINARY_DIR}/CPackSourceConfig.cmake" @ONLY IMMEDIATE) + "${CPACK_SOURCE_OUTPUT_CONFIG_FILE}" @ONLY IMMEDIATE) diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake index 7b737fa8dd..e3728610ef 100644 --- a/Modules/CTest.cmake +++ b/Modules/CTest.cmake @@ -1,6 +1,6 @@ # - setup CTest -# This file configures a project to use the CTest/Dart testing/dashboard process. -# +# This file configures a project to use the CTest/Dart +# testing/dashboard process. OPTION(BUILD_TESTING "Build the testing tree." ON) IF(BUILD_TESTING) @@ -48,6 +48,7 @@ IF(BUILD_TESTING) # Dashboard is opened for submissions for a 24 hour period starting at # the specified NIGHTLY_START_TIME. Time is specified in 24 hour format. SET_IF_NOT_SET (NIGHTLY_START_TIME "00:00:00 EDT") + SET_IF_NOT_SET(DROP_METHOD "http") # Dart server to submit results (used by client) # There should be an option to specify submit method, but I will leave it @@ -81,9 +82,9 @@ IF(BUILD_TESTING) SET(MAKEPROGRAM ${CMAKE_MAKE_PROGRAM}) FIND_PROGRAM(CVSCOMMAND cvs ) - SET(CVS_UPDATE_OPTIONS "-d -A -P" CACHE STRING "Options passed to the cvs update command.") + SET(CVS_UPDATE_OPTIONS "-d -A -P" CACHE STRING + "Options passed to the cvs update command.") FIND_PROGRAM(SVNCOMMAND svn) - #SET(SVN_UPDATE_OPTIONS "-d -A -P" CACHE STRING "Options passed to the svn update command.") IF(NOT UPDATE_TYPE) IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CVS") @@ -100,18 +101,17 @@ IF(BUILD_TESTING) ENDIF(NOT UPDATE_TYPE) IF(UPDATE_TYPE MATCHES "[Cc][Vv][Ss]") - MESSAGE(STATUS "This is a CVS repository") SET(UPDATE_COMMAND "${CVSCOMMAND}") SET(UPDATE_OPTIONS "${CVS_UPDATE_OPTIONS}") ELSE(UPDATE_TYPE MATCHES "[Cc][Vv][Ss]") IF(UPDATE_TYPE MATCHES "[Ss][Vv][Nn]") - MESSAGE(STATUS "This is a SVN repository") SET(UPDATE_COMMAND "${SVNCOMMAND}") SET(UPDATE_OPTIONS "${SVN_UPDATE_OPTIONS}") ENDIF(UPDATE_TYPE MATCHES "[Ss][Vv][Nn]") ENDIF(UPDATE_TYPE MATCHES "[Cc][Vv][Ss]") - SET(DART_TESTING_TIMEOUT 1500 CACHE STRING "MAximum time allowed before CTest will kill the test.") + SET(DART_TESTING_TIMEOUT 1500 CACHE STRING + "Maximum time allowed before CTest will kill the test.") FIND_PROGRAM(MEMORYCHECK_COMMAND NAMES purify valgrind boundscheck @@ -119,9 +119,14 @@ IF(BUILD_TESTING) "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Rational Software\\Purify\\Setup;InstallFolder]" DOC "Path to the memory checking command, used for memory error detection." ) - SET(MEMORYCHECK_SUPPRESSIONS_FILE "" CACHE FILEPATH "File that contains suppressions for the memory checker") - FIND_PROGRAM(SCPCOMMAND scp DOC "Path to scp command, used by CTest for submitting results to a Dart server") - FIND_PROGRAM(COVERAGE_COMMAND gcov DOC "Path to the coverage program that CTest uses for performing coverage inspection") + SET(MEMORYCHECK_SUPPRESSIONS_FILE "" CACHE FILEPATH + "File that contains suppressions for the memory checker") + FIND_PROGRAM(SCPCOMMAND scp DOC + "Path to scp command, used by CTest for submitting results to a Dart server" + ) + FIND_PROGRAM(COVERAGE_COMMAND gcov DOC + "Path to the coverage program that CTest uses for performing coverage inspection" + ) # set the site name SITE_NAME(SITE) @@ -146,9 +151,11 @@ IF(BUILD_TESTING) SET(BUILD_NAME_SYSTEM_NAME "Win32") ENDIF(WIN32) IF(UNIX OR BORLAND) - GET_FILENAME_COMPONENT(DART_CXX_NAME "${CMAKE_CXX_COMPILER}" ${DART_NAME_COMPONENT}) + GET_FILENAME_COMPONENT(DART_CXX_NAME + "${CMAKE_CXX_COMPILER}" ${DART_NAME_COMPONENT}) ELSE(UNIX OR BORLAND) - GET_FILENAME_COMPONENT(DART_CXX_NAME "${CMAKE_BUILD_TOOL}" ${DART_NAME_COMPONENT}) + GET_FILENAME_COMPONENT(DART_CXX_NAME + "${CMAKE_BUILD_TOOL}" ${DART_NAME_COMPONENT}) ENDIF(UNIX OR BORLAND) IF(DART_CXX_NAME MATCHES "msdev") SET(DART_CXX_NAME "vs60") @@ -165,7 +172,6 @@ IF(BUILD_TESTING) ENDIF(CMAKE_GENERATOR MATCHES "^Visual Studio 7$") ENDIF(DART_CXX_NAME MATCHES "devenv") SET(BUILDNAME "${BUILD_NAME_SYSTEM_NAME}-${DART_CXX_NAME}") - MESSAGE(STATUS "Using Buildname: ${BUILDNAME}") ENDIF(NOT BUILDNAME) # set the build command BUILD_COMMAND(MAKECOMMAND ${MAKEPROGRAM} ) diff --git a/Modules/CheckCSourceCompiles.cmake b/Modules/CheckCSourceCompiles.cmake index ec74325091..767b2af276 100644 --- a/Modules/CheckCSourceCompiles.cmake +++ b/Modules/CheckCSourceCompiles.cmake @@ -28,13 +28,13 @@ MACRO(CHECK_C_SOURCE_COMPILES SOURCE VAR) ELSE(CMAKE_REQUIRED_INCLUDES) SET(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES) ENDIF(CMAKE_REQUIRED_INCLUDES) - FILE(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/src.c" - "${SOURCE}") + FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c" + "${SOURCE}\n") MESSAGE(STATUS "Performing Test ${VAR}") TRY_COMPILE(${VAR} ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/src.c + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} "${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}" diff --git a/Modules/CheckCXXSourceCompiles.cmake b/Modules/CheckCXXSourceCompiles.cmake index 52a2217cc3..d8b8960940 100644 --- a/Modules/CheckCXXSourceCompiles.cmake +++ b/Modules/CheckCXXSourceCompiles.cmake @@ -28,13 +28,13 @@ MACRO(CHECK_CXX_SOURCE_COMPILES SOURCE VAR) ELSE(CMAKE_REQUIRED_INCLUDES) SET(CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES) ENDIF(CMAKE_REQUIRED_INCLUDES) - FILE(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/src.cxx" - "${SOURCE}") + FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx" + "${SOURCE}\n") MESSAGE(STATUS "Performing Test ${VAR}") TRY_COMPILE(${VAR} ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/src.cxx + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} "${CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES}" @@ -43,14 +43,14 @@ MACRO(CHECK_CXX_SOURCE_COMPILES SOURCE VAR) IF(${VAR}) SET(${VAR} 1 CACHE INTERNAL "Test ${FUNCTION}") MESSAGE(STATUS "Performing Test ${VAR} - Success") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Performing C++ SOURCE FILE Test ${VAR} succeded with the following output:\n" "${OUTPUT}\n" "Source file was:\n${SOURCE}\n") ELSE(${VAR}) MESSAGE(STATUS "Performing Test ${VAR} - Failed") SET(${VAR} "" CACHE INTERNAL "Test ${FUNCTION}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Performing C++ SOURCE FILE Test ${VAR} failed with the following output:\n" "${OUTPUT}\n" "Source file was:\n${SOURCE}\n") diff --git a/Modules/CheckFunctionExists.cmake b/Modules/CheckFunctionExists.cmake index 80ff36594c..e319a8137d 100644 --- a/Modules/CheckFunctionExists.cmake +++ b/Modules/CheckFunctionExists.cmake @@ -40,13 +40,13 @@ MACRO(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE) IF(${VARIABLE}) SET(${VARIABLE} 1 CACHE INTERNAL "Have function ${FUNCTION}") MESSAGE(STATUS "Looking for ${FUNCTION} - found") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the function ${FUNCTION} exists passed with the following output:\n" "${OUTPUT}\n\n") ELSE(${VARIABLE}) MESSAGE(STATUS "Looking for ${FUNCTION} - not found") SET(${VARIABLE} "" CACHE INTERNAL "Have function ${FUNCTION}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the function ${FUNCTION} exists failed with the following output:\n" "${OUTPUT}\n\n") ENDIF(${VARIABLE}) diff --git a/Modules/CheckIncludeFile.c.in b/Modules/CheckIncludeFile.c.in index 40441f15ab..ddfbee8be7 100644 --- a/Modules/CheckIncludeFile.c.in +++ b/Modules/CheckIncludeFile.c.in @@ -1,6 +1,13 @@ #include <${CHECK_INCLUDE_FILE_VAR}> +#ifdef __CLASSIC_C__ int main() { return 0; } +#else +int main(void) +{ + return 0; +} +#endif diff --git a/Modules/CheckIncludeFile.cmake b/Modules/CheckIncludeFile.cmake index aafe7a8181..cfb6921498 100644 --- a/Modules/CheckIncludeFile.cmake +++ b/Modules/CheckIncludeFile.cmake @@ -24,7 +24,7 @@ MACRO(CHECK_INCLUDE_FILE INCLUDE VARIABLE) SET(MACRO_CHECK_INCLUDE_FILE_FLAGS ${CMAKE_REQUIRED_FLAGS}) SET(CHECK_INCLUDE_FILE_VAR ${INCLUDE}) CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CheckIncludeFile.c.in - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckIncludeFile.c IMMEDIATE) + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c IMMEDIATE) MESSAGE(STATUS "Looking for ${INCLUDE}") IF(${ARGC} EQUAL 3) SET(CMAKE_C_FLAGS_SAVE ${CMAKE_C_FLAGS}) @@ -33,7 +33,7 @@ MACRO(CHECK_INCLUDE_FILE INCLUDE VARIABLE) TRY_COMPILE(${VARIABLE} ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckIncludeFile.c + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS} @@ -47,14 +47,14 @@ MACRO(CHECK_INCLUDE_FILE INCLUDE VARIABLE) IF(${VARIABLE}) MESSAGE(STATUS "Looking for ${INCLUDE} - found") SET(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the include file ${INCLUDE} " "exists passed with the following output:\n" "${OUTPUT}\n\n") ELSE(${VARIABLE}) MESSAGE(STATUS "Looking for ${INCLUDE} - not found") SET(${VARIABLE} "" CACHE INTERNAL "Have include ${INCLUDE}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the include file ${INCLUDE} " "exists failed with the following output:\n" "${OUTPUT}\n\n") diff --git a/Modules/CheckIncludeFileCXX.cmake b/Modules/CheckIncludeFileCXX.cmake index 9d8eaac1e1..548515b9fb 100644 --- a/Modules/CheckIncludeFileCXX.cmake +++ b/Modules/CheckIncludeFileCXX.cmake @@ -24,7 +24,7 @@ MACRO(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE) SET(MACRO_CHECK_INCLUDE_FILE_FLAGS ${CMAKE_REQUIRED_FLAGS}) SET(CHECK_INCLUDE_FILE_VAR ${INCLUDE}) CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckIncludeFile.cxx IMMEDIATE) + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx IMMEDIATE) MESSAGE(STATUS "Looking for C++ include ${INCLUDE}") IF(${ARGC} EQUAL 3) SET(CMAKE_CXX_FLAGS_SAVE ${CMAKE_CXX_FLAGS}) @@ -33,7 +33,7 @@ MACRO(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE) TRY_COMPILE(${VARIABLE} ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckIncludeFile.cxx + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS} @@ -47,14 +47,14 @@ MACRO(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE) IF(${VARIABLE}) MESSAGE(STATUS "Looking for C++ include ${INCLUDE} - found") SET(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the include file ${INCLUDE} " "exists passed with the following output:\n" "${OUTPUT}\n\n") ELSE(${VARIABLE}) MESSAGE(STATUS "Looking for C++ include ${INCLUDE} - not found") SET(${VARIABLE} "" CACHE INTERNAL "Have include ${INCLUDE}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the include file ${INCLUDE} " "exists failed with the following output:\n" "${OUTPUT}\n\n") diff --git a/Modules/CheckIncludeFiles.cmake b/Modules/CheckIncludeFiles.cmake index 7ff0ebbddd..5739afe795 100644 --- a/Modules/CheckIncludeFiles.cmake +++ b/Modules/CheckIncludeFiles.cmake @@ -29,12 +29,12 @@ MACRO(CHECK_INCLUDE_FILES INCLUDE VARIABLE) SET(CMAKE_CONFIGURABLE_FILE_CONTENT "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n\nint main(){return 0;}\n") CONFIGURE_FILE("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" - "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckIncludeFiles.c" @ONLY IMMEDIATE) + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFiles.c" @ONLY IMMEDIATE) MESSAGE(STATUS "Looking for include files ${VARIABLE}") TRY_COMPILE(${VARIABLE} ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckIncludeFiles.c + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFiles.c COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILES_FLAGS} @@ -43,14 +43,14 @@ MACRO(CHECK_INCLUDE_FILES INCLUDE VARIABLE) IF(${VARIABLE}) MESSAGE(STATUS "Looking for include files ${VARIABLE} - found") SET(${VARIABLE} 1 CACHE INTERNAL "Have include ${VARIABLE}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if files ${INCLUDE} " "exist passed with the following output:\n" "${OUTPUT}\n\n") ELSE(${VARIABLE}) MESSAGE(STATUS "Looking for include files ${VARIABLE} - not found.") SET(${VARIABLE} "" CACHE INTERNAL "Have includes ${VARIABLE}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if files ${INCLUDE} " "exist failed with the following output:\n" "${OUTPUT}\nSource:\n${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") diff --git a/Modules/CheckLibraryExists.cmake b/Modules/CheckLibraryExists.cmake index 1003ca7ae2..1e8a6bfeda 100644 --- a/Modules/CheckLibraryExists.cmake +++ b/Modules/CheckLibraryExists.cmake @@ -36,14 +36,14 @@ MACRO(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE) IF(${VARIABLE}) MESSAGE(STATUS "Looking for ${FUNCTION} in ${LIBRARY} - found") SET(${VARIABLE} 1 CACHE INTERNAL "Have library ${LIBRARY}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the function ${FUNCTION} exists in the ${LIBRARY} " "passed with the following output:\n" "${OUTPUT}\n\n") ELSE(${VARIABLE}) MESSAGE(STATUS "Looking for ${FUNCTION} in ${LIBRARY} - not found") SET(${VARIABLE} "" CACHE INTERNAL "Have library ${LIBRARY}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the function ${FUNCTION} exists in the ${LIBRARY} " "failed with the following output:\n" "${OUTPUT}\n\n") diff --git a/Modules/CheckSymbolExists.cmake b/Modules/CheckSymbolExists.cmake index 9391ac9a7c..99b8918917 100644 --- a/Modules/CheckSymbolExists.cmake +++ b/Modules/CheckSymbolExists.cmake @@ -37,12 +37,12 @@ MACRO(CHECK_SYMBOL_EXISTS SYMBOL FILES VARIABLE) "${CMAKE_CONFIGURABLE_FILE_CONTENT}\nvoid cmakeRequireSymbol(int dummy,...){(void)dummy;}\nint main()\n{\n#ifndef ${SYMBOL}\n cmakeRequireSymbol(0,&${SYMBOL});\n#endif\n return 0;\n}\n") CONFIGURE_FILE("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" - "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckSymbolExists.c" @ONLY) + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" @ONLY) MESSAGE(STATUS "Looking for ${SYMBOL}") TRY_COMPILE(${VARIABLE} ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckSymbolExists.c + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_SYMBOL_EXISTS_FLAGS} @@ -52,18 +52,18 @@ MACRO(CHECK_SYMBOL_EXISTS SYMBOL FILES VARIABLE) IF(${VARIABLE}) MESSAGE(STATUS "Looking for ${SYMBOL} - found") SET(${VARIABLE} 1 CACHE INTERNAL "Have symbol ${SYMBOL}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the ${SYMBOL} " "exist passed with the following output:\n" - "${OUTPUT}\nFile ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckSymbolExists.c:\n" + "${OUTPUT}\nFile ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c:\n" "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") ELSE(${VARIABLE}) MESSAGE(STATUS "Looking for ${SYMBOL} - not found.") SET(${VARIABLE} "" CACHE INTERNAL "Have symbol ${SYMBOL}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the ${SYMBOL} " "exist failed with the following output:\n" - "${OUTPUT}\nFile ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckSymbolExists.c:\n" + "${OUTPUT}\nFile ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c:\n" "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n") ENDIF(${VARIABLE}) ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$") diff --git a/Modules/CheckTypeSize.cmake b/Modules/CheckTypeSize.cmake index edaa00632c..2eb1224a1c 100644 --- a/Modules/CheckTypeSize.cmake +++ b/Modules/CheckTypeSize.cmake @@ -30,8 +30,8 @@ MACRO(CHECK_TYPE_SIZE TYPE VARIABLE) SET(CHECK_TYPE_SIZE_PREMAIN "${CHECK_TYPE_SIZE_PREMAIN}#include \"${def}\"\n") ENDFOREACH(def) CONFIGURE_FILE("${CMAKE_ROOT}/Modules/CheckTypeSize.c.in" - "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckTypeSize.c" IMMEDIATE @ONLY) - FILE(READ "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckTypeSize.c" + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c" IMMEDIATE @ONLY) + FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c" CHECK_TYPE_SIZE_FILE_CONTENT) MESSAGE(STATUS "Check size of ${TYPE}") IF(CMAKE_REQUIRED_LIBRARIES) @@ -48,7 +48,7 @@ MACRO(CHECK_TYPE_SIZE TYPE VARIABLE) ENDIF(CMAKE_REQUIRED_INCLUDES) TRY_RUN(${VARIABLE} HAVE_${VARIABLE} ${CMAKE_BINARY_DIR} - "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckTypeSize.c" + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c" COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_TYPE_SIZE_FLAGS} "${CHECK_TYPE_SIZE_ADD_LIBRARIES}" @@ -56,11 +56,11 @@ MACRO(CHECK_TYPE_SIZE TYPE VARIABLE) OUTPUT_VARIABLE OUTPUT) IF(HAVE_${VARIABLE}) MESSAGE(STATUS "Check size of ${TYPE} - done") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining size of ${TYPE} passed with the following output:\n${OUTPUT}\n\n") ELSE(HAVE_${VARIABLE}) MESSAGE(STATUS "Check size of ${TYPE} - failed") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining size of ${TYPE} failed with the following output:\n${OUTPUT}\nCheckTypeSize.c:\n${CHECK_TYPE_SIZE_FILE_CONTENT}\n\n") ENDIF(HAVE_${VARIABLE}) ENDIF("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$") diff --git a/Modules/CheckVariableExists.cmake b/Modules/CheckVariableExists.cmake index 2b0bdabb8d..a6cdc01fc3 100644 --- a/Modules/CheckVariableExists.cmake +++ b/Modules/CheckVariableExists.cmake @@ -34,13 +34,13 @@ MACRO(CHECK_VARIABLE_EXISTS VAR VARIABLE) IF(${VARIABLE}) SET(${VARIABLE} 1 CACHE INTERNAL "Have variable ${VAR}") MESSAGE(STATUS "Looking for ${VAR} - found") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the variable ${VAR} exists passed with the following output:\n" "${OUTPUT}\n\n") ELSE(${VARIABLE}) SET(${VARIABLE} "" CACHE INTERNAL "Have variable ${VAR}") MESSAGE(STATUS "Looking for ${VAR} - not found") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the variable ${VAR} exists failed with the following output:\n" "${OUTPUT}\n\n") ENDIF(${VARIABLE}) diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake index 4c18911251..9ba1938a9a 100644 --- a/Modules/FindOpenGL.cmake +++ b/Modules/FindOpenGL.cmake @@ -95,7 +95,9 @@ ELSE (WIN32) # It's not true on OSX. IF (OPENGL_gl_LIBRARY) + IF(NOT X11_FOUND) INCLUDE(FindX11) + ENDIF(NOT X11_FOUND) IF (X11_FOUND) IF (NOT APPLE) SET (OPENGL_LIBRARIES ${X11_LIBRARIES}) diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index 8f20d48abd..3b11596526 100644 --- a/Modules/FindQt4.cmake +++ b/Modules/FindQt4.cmake @@ -161,7 +161,7 @@ # QT_QT_LIBRARY Qt-Library is now split INCLUDE(CheckSymbolExists) -INCLUDE(AddFileDependencies) +INCLUDE(MacroAddFileDependencies) SET(QT_USE_FILE ${CMAKE_ROOT}/Modules/UseQt4.cmake) @@ -176,7 +176,7 @@ FIND_PROGRAM(QT_QMAKE_EXECUTABLE NAMES qmake qmake-qt4 PATHS "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\4.0.0;InstallDir]/bin" "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\4.0.0;InstallDir]/bin" $ENV{QTDIR}/bin - ) +) SET(QT4_INSTALLED_VERSION_TOO_OLD FALSE) @@ -203,18 +203,18 @@ IF (QT_QMAKE_EXECUTABLE) ENDIF (NOT req_qt_major_vers) # now parse the parts of the user given version string into variables - STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" req_qt_major_vers "${QT_MIN_VERSION}") - STRING(REGEX REPLACE "[0-9]+\\.([0-9])+\\.[0-9]+" "\\1" req_qt_minor_vers "${QT_MIN_VERSION}") - STRING(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" req_qt_patch_vers "${QT_MIN_VERSION}") + STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" req_qt_major_vers "${QT_MIN_VERSION}") + STRING(REGEX REPLACE "^[0-9]+\\.([0-9])+\\.[0-9]+" "\\1" req_qt_minor_vers "${QT_MIN_VERSION}") + STRING(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" req_qt_patch_vers "${QT_MIN_VERSION}") IF (NOT req_qt_major_vers EQUAL 4) MESSAGE( FATAL_ERROR "Invalid Qt version string given: \"${QT_MIN_VERSION}\", major version 4 is required, e.g. \"4.0.1\"") ENDIF (NOT req_qt_major_vers EQUAL 4) # and now the version string given by qmake - STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" found_qt_major_vers "${qt_version_tmp}") - STRING(REGEX REPLACE "[0-9]+\\.([0-9])+\\.[0-9]+" "\\1" found_qt_minor_vers "${qt_version_tmp}") - STRING(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" found_qt_patch_vers "${qt_version_tmp}") + STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" found_qt_major_vers "${QTVERSION}") + STRING(REGEX REPLACE "^[0-9]+\\.([0-9])+\\.[0-9]+.*" "\\1" found_qt_minor_vers "${QTVERSION}") + STRING(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" found_qt_patch_vers "${QTVERSION}") # compute an overall version number which can be compared at once MATH(EXPR req_vers "${req_qt_major_vers}*10000 + ${req_qt_minor_vers}*100 + ${req_qt_patch_vers}") @@ -299,11 +299,9 @@ IF (QT4_QMAKE_FOUND) ######################################## FIND_PATH(QT_QTCORE_INCLUDE_DIR QtGlobal - "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\4.0.0;InstallDir]/include/QtCore" ${QT_HEADERS_DIR}/QtCore ${QT_LIBRARY_DIR}/QtCore.framework/Headers - $ENV{QTDIR}/include/QtCore - "$ENV{ProgramFiles}/qt/include/Qt" + NO_DEFAULT_PATH ) # Set QT_INCLUDE_DIR by removine "/QtCore" in the string ${QT_QTCORE_INCLUDE_DIR} @@ -470,41 +468,6 @@ IF (QT4_QMAKE_FOUND) SET( QT_INCLUDES ${QT_INCLUDE_DIR} ${QT_QT_INCLUDE_DIR} ${QT_MKSPECS_DIR}/default ) - ######################################## - # - # Setting the LIBRARY-Variables - # - ######################################## - - IF (QT_USE_FRAMEWORKS) - # If FIND_LIBRARY found libraries in Apple frameworks, we would NOT have - # to jump through these hoops. - SET(QT_QTCORE_LIBRARY_RELEASE "-F${QT_LIBRARY_DIR} -framework QtCore" CACHE STRING "The QtCore library.") - SET(QT_QTCORE_LIBRARY_DEBUG "-F${QT_LIBRARY_DIR} -framework QtCore" CACHE STRING "The QtCore library.") - SET(QT_QT3SUPPORT_LIBRARY_RELEASE "-framework Qt3Support" CACHE STRING "The Qt3Support library.") - SET(QT_QT3SUPPORT_LIBRARY_DEBUG "-framework Qt3Support" CACHE STRING "The Qt3Support library.") - SET(QT_QTGUI_LIBRARY_RELEASE "-framework QtGui" CACHE STRING "The QtGui library.") - SET(QT_QTGUI_LIBRARY_DEBUG "-framework QtGui" CACHE STRING "The QtGui library.") - SET(QT_QTNETWORK_LIBRARY_RELEASE "-framework QtNetwork" CACHE STRING "The QtNetwork library.") - SET(QT_QTNETWORK_LIBRARY_DEBUG "-framework QtNetwork" CACHE STRING "The QtNetwork library.") - SET(QT_QTOPENGL_LIBRARY_RELEASE "-framework QtOpenGL" CACHE STRING "The QtOpenGL library.") - SET(QT_QTOPENGL_LIBRARY_DEBUG "-framework QtOpenGL" CACHE STRING "The QtOpenGL library.") - SET(QT_QTSQL_LIBRARY_RELEASE "-framework QtSql" CACHE STRING "The QtSql library.") - SET(QT_QTSQL_LIBRARY_DEBUG "-framework QtSql" CACHE STRING "The QtSql library.") - SET(QT_QTXML_LIBRARY_RELEASE "-framework QtXml" CACHE STRING "The QtXml library.") - SET(QT_QTXML_LIBRARY_DEBUG "-framework QtXml" CACHE STRING "The QtXml library.") - SET(QT_QTSVG_LIBRARY_RELEASE "-framework QtSvg" CACHE STRING "The QtSvg library.") - SET(QT_QTSVG_LIBRARY_DEBUG "-framework QtSvg" CACHE STRING "The QtSvg library.") - SET(QT_QTUITOOLS_LIBRARY_RELEASE "-framework QtUiTools" CACHE STRING "The QtUiTools library.") - SET(QT_QTUITOOLS_LIBRARY_DEBUG "-framework QtUiTools" CACHE STRING "The QtUiTools library.") - - - # WTF? why don't we have frameworks? :P - SET(QT_QTTEST_LIBRARY_RELEASE "-L${QT_LIBRARY_DIR} -lQtTest" CACHE STRING "The QtTest library.") - SET(QT_QTTEST_LIBRARY_DEBUG "-L${QT_LIBRARY_DIR} -lQtTest_debug" CACHE STRING "The QtTest library.") - MARK_AS_ADVANCED(QT_QT3SUPPORT_LIBRARY QT_QTGUI_LIBRARY ) - - ELSE (QT_USE_FRAMEWORKS) # Set QT_QTCORE_LIBRARY by searching for a lib with "QtCore." as part of the filename FIND_LIBRARY(QT_QTCORE_LIBRARY_RELEASE NAMES QtCore QtCore4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH ) @@ -558,7 +521,11 @@ IF (QT4_QMAKE_FOUND) MARK_AS_ADVANCED(QT_QT3SUPPORT_LIBRARY QT_QTGUI_LIBRARY ) - ENDIF (QT_USE_FRAMEWORKS) + IF( NOT QT_QTCORE_LIBRARY_DEBUG AND NOT QT_QTCORE_LIBRARY_RELEASE ) + IF( NOT Qt4_FIND_QUIETLY AND Qt4_FIND_REQUIRED) + MESSAGE( FATAL_ERROR "Could NOT find QtCore. Check CMakeFiles/CMakeError.log for more details.") + ENDIF( NOT Qt4_FIND_QUIETLY AND Qt4_FIND_REQUIRED) + ENDIF( NOT QT_QTCORE_LIBRARY_DEBUG AND NOT QT_QTCORE_LIBRARY_RELEASE ) # Set QT_QTASSISTANT_LIBRARY FIND_LIBRARY(QT_QTASSISTANT_LIBRARY_RELEASE NAMES QtAssistantClient QtAssistant QtAssistant4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) @@ -592,7 +559,11 @@ IF (QT4_QMAKE_FOUND) ENDIF (QT_${basename}_LIBRARY_DEBUG AND NOT QT_${basename}_LIBRARY_RELEASE) IF (QT_${basename}_LIBRARY_DEBUG AND QT_${basename}_LIBRARY_RELEASE) + IF(NOT MSVC) SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY_RELEASE}) + ELSE(NOT MSVC) + SET(QT_${basename}_LIBRARY optimized ${QT_${basename}_LIBRARY_RELEASE} debug ${QT_${basename}_LIBRARY_DEBUG}) + ENDIF(NOT MSVC) SET(QT_${basename}_LIBRARIES optimized ${QT_${basename}_LIBRARY_RELEASE} debug ${QT_${basename}_LIBRARY_DEBUG}) ENDIF (QT_${basename}_LIBRARY_DEBUG AND QT_${basename}_LIBRARY_RELEASE) @@ -641,25 +612,33 @@ IF (QT4_QMAKE_FOUND) # find moc and uic using qmake - FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmpQmake/tmp.pro + FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmpQmake/tmp.pro "message(MOC<$$QMAKE_MOC>) message(UIC<$$QMAKE_UIC>) ") EXECUTE_PROCESS(COMMAND ${QT_QMAKE_EXECUTABLE} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmpQmake + WORKING_DIRECTORY + ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmpQmake OUTPUT_VARIABLE _moc_OUTPUT ERROR_VARIABLE _moc_OUTPUT ) - FILE(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmpQmake") + FILE(REMOVE_RECURSE + "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmpQmake") - STRING(REGEX REPLACE ".*MOC<([^>]+).*" "\\1" QT_MOC_EXECUTABLE_INTERNAL "${_moc_OUTPUT}" ) - STRING(REGEX REPLACE ".*UIC<([^>]+).*" "\\1" QT_UIC_EXECUTABLE_INTERNAL "${_moc_OUTPUT}" ) + STRING(REGEX REPLACE + ".*MOC<([^>]+).*" "\\1" QT_MOC_EXECUTABLE_INTERNAL "${_moc_OUTPUT}" ) + STRING(REGEX REPLACE + ".*UIC<([^>]+).*" "\\1" QT_UIC_EXECUTABLE_INTERNAL "${_moc_OUTPUT}" ) - FILE(TO_CMAKE_PATH ${QT_MOC_EXECUTABLE_INTERNAL} QT_MOC_EXECUTABLE_INTERNAL) - FILE(TO_CMAKE_PATH ${QT_UIC_EXECUTABLE_INTERNAL} QT_UIC_EXECUTABLE_INTERNAL) + FILE(TO_CMAKE_PATH + "${QT_MOC_EXECUTABLE_INTERNAL}" QT_MOC_EXECUTABLE_INTERNAL) + FILE(TO_CMAKE_PATH + "${QT_UIC_EXECUTABLE_INTERNAL}" QT_UIC_EXECUTABLE_INTERNAL) - SET(QT_MOC_EXECUTABLE ${QT_MOC_EXECUTABLE_INTERNAL} CACHE FILEPATH "The moc executable") - SET(QT_UIC_EXECUTABLE ${QT_UIC_EXECUTABLE_INTERNAL} CACHE FILEPATH "The uic executable") + SET(QT_MOC_EXECUTABLE + ${QT_MOC_EXECUTABLE_INTERNAL} CACHE FILEPATH "The moc executable") + SET(QT_UIC_EXECUTABLE + ${QT_UIC_EXECUTABLE_INTERNAL} CACHE FILEPATH "The uic executable") FIND_PROGRAM(QT_UIC3_EXECUTABLE NAMES uic3 @@ -711,6 +690,8 @@ IF (QT4_QMAKE_FOUND) COMMAND ${QT_MOC_EXECUTABLE} ARGS ${moc_includes} -o ${outfile} ${infile} DEPENDS ${infile}) + + MACRO_ADD_FILE_DEPENDENCIES(${infile} ${outfile}) ENDMACRO (QT4_GENERATE_MOC) @@ -810,7 +791,7 @@ IF (QT4_QMAKE_FOUND) DEPENDS ${_header} ) - ADD_FILE_DEPENDENCIES(${_abs_FILE} ${_moc}) + MACRO_ADD_FILE_DEPENDENCIES(${_abs_FILE} ${_moc}) ENDFOREACH (_current_MOC_INC) ENDIF(_match) ENDIF ( NOT _skip AND EXISTS ${_abs_FILE} ) diff --git a/Modules/FindSDL_sound.cmake b/Modules/FindSDL_sound.cmake index bee01b18e4..62be3ee6db 100644 --- a/Modules/FindSDL_sound.cmake +++ b/Modules/FindSDL_sound.cmake @@ -147,7 +147,7 @@ IF(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY) # To minimize external dependencies, create a sdlsound test program # which will be used to figure out if additional link dependencies are # required for the link phase. - FILE(WRITE ${PROJECT_BINARY_DIR}/CMakeFiles/CMakeTmp/DetermineSoundLibs.c + FILE(WRITE ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/DetermineSoundLibs.c "#include \"SDL_sound.h\" #include \"SDL.h\" int main(int argc, char* argv[]) @@ -176,7 +176,7 @@ IF(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY) # in the TARGET_LINK_LIBRARIES, I seem to loose everything # in the SDL_LIBRARY string after the "-framework". # But if I quote the stuff in INCLUDE_DIRECTORIES, it doesn't work. - FILE(WRITE ${PROJECT_BINARY_DIR}/CMakeFiles/CMakeTmp/CMakeLists.txt + FILE(WRITE ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CMakeLists.txt "PROJECT(DetermineSoundLibs) INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR} ${SDL_SOUND_INCLUDE_DIR}) ADD_EXECUTABLE(DetermineSoundLibs DetermineSoundLibs.c) @@ -185,8 +185,8 @@ IF(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY) TRY_COMPILE( MY_RESULT - ${PROJECT_BINARY_DIR}/CMakeFiles/CMakeTmp - ${PROJECT_BINARY_DIR}/CMakeFiles/CMakeTmp + ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp + ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp DetermineSoundLibs OUTPUT_VARIABLE MY_OUTPUT ) diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake index 9a254e92d4..74405d6c52 100644 --- a/Modules/FindThreads.cmake +++ b/Modules/FindThreads.cmake @@ -62,12 +62,14 @@ ELSE(CMAKE_HAVE_SPROC_H) MESSAGE(STATUS "Check if compiler accepts -pthread - yes") ELSE(THREADS_PTHREAD_ARG MATCHES "^2$") MESSAGE(STATUS "Check if compiler accepts -pthread - no") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if compiler accepts -pthread returned ${THREADS_PTHREAD_ARG} instead of 2. The compiler had the following output:\n${OUTPUT}\n\n") ENDIF(THREADS_PTHREAD_ARG MATCHES "^2$") ELSE(THREADS_HAVE_PTHREAD_ARG) MESSAGE(STATUS "Check if compiler accepts -pthread - no") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if compiler accepts -pthread failed with the following output:\n${OUTPUT}\n\n") ENDIF(THREADS_HAVE_PTHREAD_ARG) ENDIF("THREADS_HAVE_PTHREAD_ARG" MATCHES "^THREADS_HAVE_PTHREAD_ARG") diff --git a/Modules/FindVTK.cmake b/Modules/FindVTK.cmake index eca57d64ca..f79a7026a6 100644 --- a/Modules/FindVTK.cmake +++ b/Modules/FindVTK.cmake @@ -44,7 +44,12 @@ IF(NOT VTK_DIR) # Construct a set of paths relative to the system search path. SET(VTK_DIR_SEARCH "") FOREACH(dir ${VTK_DIR_SEARCH2}) - SET(VTK_DIR_SEARCH ${VTK_DIR_SEARCH} "${dir}/../lib/vtk") + SET(VTK_DIR_SEARCH ${VTK_DIR_SEARCH} + ${dir}/../lib/vtk-5.2 + ${dir}/../lib/vtk-5.1 + ${dir}/../lib/vtk-5.0 + ${dir}/../lib/vtk + ) ENDFOREACH(dir) # Old scripts may set these directories in the CMakeCache.txt file. diff --git a/Modules/FindZLIB.cmake b/Modules/FindZLIB.cmake index e648817ad0..2dd8f2f58c 100644 --- a/Modules/FindZLIB.cmake +++ b/Modules/FindZLIB.cmake @@ -5,23 +5,41 @@ # ZLIB_LIBRARIES - List of libraries when using zlib. # ZLIB_FOUND - True if zlib found. + +IF (ZLIB_INCLUDE_DIR) + # Already in cache, be silent + SET(ZLIB_FIND_QUIETLY TRUE) +ENDIF (ZLIB_INCLUDE_DIR) + FIND_PATH(ZLIB_INCLUDE_DIR zlib.h /usr/local/include /usr/include ) -SET(ZLIB_NAMES ${ZLIB_NAMES} z zlib) +SET(ZLIB_NAMES z zlib zdll) FIND_LIBRARY(ZLIB_LIBRARY NAMES ${ZLIB_NAMES} PATHS /usr/lib /usr/local/lib ) -IF(ZLIB_INCLUDE_DIR) - IF(ZLIB_LIBRARY) +IF (ZLIB_INCLUDE_DIR AND ZLIB_LIBRARY) + SET(ZLIB_FOUND TRUE) SET( ZLIB_LIBRARIES ${ZLIB_LIBRARY} ) - SET( ZLIB_FOUND "YES" ) - ENDIF(ZLIB_LIBRARY) -ENDIF(ZLIB_INCLUDE_DIR) +ELSE (ZLIB_INCLUDE_DIR AND ZLIB_LIBRARY) + SET(ZLIB_FOUND FALSE) + SET( ZLIB_LIBRARIES ) +ENDIF (ZLIB_INCLUDE_DIR AND ZLIB_LIBRARY) + +IF (ZLIB_FOUND) + IF (NOT ZLIB_FIND_QUIETLY) + MESSAGE(STATUS "Found ZLIB: ${ZLIB_LIBRARY}") + ENDIF (NOT ZLIB_FIND_QUIETLY) +ELSE (ZLIB_FOUND) + IF (ZLIB_FIND_REQUIRED) + MESSAGE(STATUS "Looked for Z libraries named ${ZLIBS_NAMES}.") + MESSAGE(FATAL_ERROR "Could NOT find z library") + ENDIF (ZLIB_FIND_REQUIRED) +ENDIF (ZLIB_FOUND) MARK_AS_ADVANCED( ZLIB_LIBRARY diff --git a/Modules/KDE3Macros.cmake b/Modules/KDE3Macros.cmake index 17e4384067..0c2ae191ab 100644 --- a/Modules/KDE3Macros.cmake +++ b/Modules/KDE3Macros.cmake @@ -170,9 +170,10 @@ MACRO(KDE3_ADD_UI_FILES _sources ) ADD_CUSTOM_COMMAND(OUTPUT ${_src} COMMAND ${CMAKE_COMMAND} ARGS - -DKDE_UIC_FILE:STRING=${_tmp_FILE} - -DKDE_UIC_CPP_FILE:STRING=${_src} - -DKDE_UIC_H_FILE:STRING=${_header} + -DKDE_UIC_EXECUTABLE:FILEPATH=${QT_UIC_EXECUTABLE} + -DKDE_UIC_FILE:FILEPATH=${_tmp_FILE} + -DKDE_UIC_CPP_FILE:FILEPATH=${_src} + -DKDE_UIC_H_FILE:FILEPATH=${_header} -P ${KDE3_MODULE_DIR}/kde3uic.cmake DEPENDS ${_header} ) diff --git a/Modules/MacroAddFileDependencies.cmake b/Modules/MacroAddFileDependencies.cmake new file mode 100644 index 0000000000..13596912eb --- /dev/null +++ b/Modules/MacroAddFileDependencies.cmake @@ -0,0 +1,15 @@ +# - MACRO_ADD_FILE_DEPENDENCIES(<_file> depend_files...) +# MACRO_OPTIONAL_FIND_PACKAGE( <name> [QUIT] ) + +MACRO (MACRO_ADD_FILE_DEPENDENCIES _file) + + GET_SOURCE_FILE_PROPERTY(_deps ${_file} OBJECT_DEPENDS) + if (_deps) + set(_deps ${_deps} ${ARGN}) + else (_deps) + set(_deps ${ARGN}) + endif (_deps) + + SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES OBJECT_DEPENDS "${_deps}") + +ENDMACRO (MACRO_ADD_FILE_DEPENDENCIES) diff --git a/Modules/Platform/Windows-cl.cmake b/Modules/Platform/Windows-cl.cmake index 3c21bd0ee9..3c71c602e1 100644 --- a/Modules/Platform/Windows-cl.cmake +++ b/Modules/Platform/Windows-cl.cmake @@ -92,7 +92,7 @@ IF(CMAKE_GENERATOR MATCHES "Makefiles") RETURN_VALUE CMAKE_COMPILER_RETURN ) IF(NOT CMAKE_COMPILER_RETURN) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining the version of compiler passed with the following output:\n" "${CMAKE_COMPILER_OUTPUT}\n\n") STRING(REGEX REPLACE "\n" " " compilerVersion "${CMAKE_COMPILER_OUTPUT}") @@ -127,40 +127,40 @@ IF(CMAKE_GENERATOR MATCHES "Makefiles") SET(MSVC_VERSION "${compilerVersion}") ELSE(NOT CMAKE_COMPILER_RETURN) MESSAGE(STATUS "Check for CL compiler version - failed") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining the version of compiler failed with the following output:\n" "${CMAKE_COMPILER_OUTPUT}\n\n") ENDIF(NOT CMAKE_COMPILER_RETURN) # try to figure out if we are running the free command line # tools from Microsoft. These tools do not provide debug libraries, # so the link flags used have to be different. - MAKE_DIRECTORY("${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp2") + MAKE_DIRECTORY("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp2") SET(testForFreeVCFile "${CMAKE_ROOT}/Modules/CMakeTestForFreeVC.cxx") STRING(REGEX REPLACE "/" "\\\\" testForFreeVCFile "${testForFreeVCFile}") MESSAGE(STATUS "Check if this is a free VC compiler") - EXEC_PROGRAM(${CMAKE_C_COMPILER} ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp2 + EXEC_PROGRAM(${CMAKE_C_COMPILER} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp2 ARGS /nologo /MD /EHsc \"${testForFreeVCFile}\" OUTPUT_VARIABLE CMAKE_COMPILER_OUTPUT RETURN_VALUE CMAKE_COMPILER_RETURN ) IF(CMAKE_COMPILER_RETURN) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if this is a free VC compiler failed with the following output:\n" "${CMAKE_COMPILER_OUTPUT}\n\n") MESSAGE(STATUS "Check if this is a free VC compiler - yes") SET(CMAKE_USING_VC_FREE_TOOLS 1) ELSE(CMAKE_COMPILER_RETURN) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if this is a free VC compiler passed with the following output:\n" "${CMAKE_COMPILER_OUTPUT}\n\n") MESSAGE(STATUS "Check if this is a free VC compiler - no") SET(CMAKE_USING_VC_FREE_TOOLS 0) ENDIF(CMAKE_COMPILER_RETURN) - MAKE_DIRECTORY("${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp3") + MAKE_DIRECTORY("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp3") MESSAGE(STATUS "Check CL platform") - EXEC_PROGRAM(${CMAKE_C_COMPILER} ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp3 + EXEC_PROGRAM(${CMAKE_C_COMPILER} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp3 ARGS /nologo \"${testForFreeVCFile}\" /link /machine:i386 @@ -170,13 +170,13 @@ IF(CMAKE_GENERATOR MATCHES "Makefiles") # if there was an error assume it is a 64bit system IF(CMAKE_COMPILER_RETURN) FILE(APPEND - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if this is a 64 bit system passed:\n" "${CMAKE_COMPILER_OUTPUT}\n\n") MESSAGE(STATUS "Check CL platform - 64 bit") SET(CMAKE_CL_64 1) ELSE(CMAKE_COMPILER_RETURN) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if this is a 32 bit system passed:\n" "${CMAKE_COMPILER_OUTPUT}\n\n") MESSAGE(STATUS "Check CL platform - 32 bit") @@ -194,16 +194,16 @@ ENDIF(CMAKE_FORCE_WIN64) IF(MSVC80) # for 2005 make sure the manifest is put in the dll with mt SET(CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY}" - "mt /manifest <TARGET>.manifest /outputresource:<TARGET>\;#2") + "mt ${CMAKE_CL_NOLOGO} /manifest <TARGET>.manifest /outputresource:<TARGET>\;#2") SET(CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_LIBRARY}") # create a C shared library SET(CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY}") # create a C shared module just copy the shared library rule SET(CMAKE_C_CREATE_SHARED_MODULE "${CMAKE_C_CREATE_SHARED_LIBRARY}") SET(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE}" - "mt /manifest <TARGET>.manifest /outputresource:<TARGET>\;#2") + "mt ${CMAKE_CL_NOLOGO} /manifest <TARGET>.manifest /outputresource:<TARGET>\;#2") SET(CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}" - "mt /manifest <TARGET>.manifest /outputresource:<TARGET>\;#2") + "mt ${CMAKE_CL_NOLOGO} /manifest <TARGET>.manifest /outputresource:<TARGET>\;#2") SET(CMAKE_BUILD_TYPE_INIT Debug) SET (CMAKE_CXX_FLAGS_INIT "/DWIN32 /D_WINDOWS /W3 /Zm1000 /EHsc /GR") SET (CMAKE_CXX_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Ob0 /Od /RTC1") @@ -275,12 +275,12 @@ SET (CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_RELW # save computed information for this platform IF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake") CONFIGURE_FILE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake.in - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCPlatform.cmake IMMEDIATE) + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCPlatform.cmake IMMEDIATE) ENDIF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake") IF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake") CONFIGURE_FILE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake.in - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeCXXPlatform.cmake IMMEDIATE) + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCXXPlatform.cmake IMMEDIATE) ENDIF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake") INCLUDE(Platform/WindowsPaths) diff --git a/Modules/TestBigEndian.cmake b/Modules/TestBigEndian.cmake index 3a38dfc39c..021b9a67cd 100644 --- a/Modules/TestBigEndian.cmake +++ b/Modules/TestBigEndian.cmake @@ -15,21 +15,21 @@ MACRO(TEST_BIG_ENDIAN VARIABLE) ENDIF("${VARIABLE}" STREQUAL "FAILED_TO_RUN") MESSAGE(STATUS "Check if the system is big endian") IF(HAVE_${VARIABLE}) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining the endianes of the system passed. The system is ") IF(${VARIABLE}) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "big endian") MESSAGE(STATUS "Check if the system is big endian - big endian") ELSE(${VARIABLE}) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "little endian") MESSAGE(STATUS "Check if the system is big endian - little endian") ENDIF(${VARIABLE}) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Test produced following output:\n${OUTPUT}\n\n") ELSE(HAVE_${VARIABLE}) - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining the endianes of the system failed with the following output:\n${OUTPUT}\n\n") MESSAGE("Check if the system is big endian - failed") ENDIF(HAVE_${VARIABLE}) diff --git a/Modules/TestCXXAcceptsFlag.cmake b/Modules/TestCXXAcceptsFlag.cmake index 8ead32ac72..2242dcf20c 100644 --- a/Modules/TestCXXAcceptsFlag.cmake +++ b/Modules/TestCXXAcceptsFlag.cmake @@ -17,12 +17,12 @@ MACRO(CHECK_CXX_ACCEPTS_FLAG FLAGS VARIABLE) OUTPUT_VARIABLE OUTPUT) IF(${VARIABLE}) MESSAGE(STATUS "Checking to see if CXX compiler accepts flag ${FLAGS} - yes") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the CXX compiler accepts the flag ${FLAGS} passed with " "the following output:\n${OUTPUT}\n\n") ELSE(${VARIABLE}) MESSAGE(STATUS "Checking to see if CXX compiler accepts flag ${FLAGS} - no") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the CXX compiler accepts the flag ${FLAGS} failed with " "the following output:\n${OUTPUT}\n\n") ENDIF(${VARIABLE}) diff --git a/Modules/TestForANSIForScope.cmake b/Modules/TestForANSIForScope.cmake index ca41cca5ec..b8afc102b8 100644 --- a/Modules/TestForANSIForScope.cmake +++ b/Modules/TestForANSIForScope.cmake @@ -12,14 +12,14 @@ IF("CMAKE_ANSI_FOR_SCOPE" MATCHES "^CMAKE_ANSI_FOR_SCOPE$") MESSAGE(STATUS "Check for ANSI scope - found") SET (CMAKE_NO_ANSI_FOR_SCOPE 0 CACHE INTERNAL "Does the compiler support ansi for scope.") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the CXX compiler understands ansi for scopes passed with " "the following output:\n${OUTPUT}\n\n") ELSE (CMAKE_ANSI_FOR_SCOPE) MESSAGE(STATUS "Check for ANSI scope - not found") SET (CMAKE_NO_ANSI_FOR_SCOPE 1 CACHE INTERNAL "Does the compiler support ansi for scope.") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the CXX compiler understands ansi for scopes failed with " "the following output:\n${OUTPUT}\n\n") ENDIF (CMAKE_ANSI_FOR_SCOPE) diff --git a/Modules/TestForSSTREAM.cmake b/Modules/TestForSSTREAM.cmake index f0d12d9f5b..55afbc3a48 100644 --- a/Modules/TestForSSTREAM.cmake +++ b/Modules/TestForSSTREAM.cmake @@ -11,14 +11,14 @@ IF("CMAKE_HAS_ANSI_STRING_STREAM" MATCHES "^CMAKE_HAS_ANSI_STRING_STREAM$") MESSAGE(STATUS "Check for sstream - found") SET (CMAKE_NO_ANSI_STRING_STREAM 0 CACHE INTERNAL "Does the compiler support sstream") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the CXX compiler has sstream passed with " "the following output:\n${OUTPUT}\n\n") ELSE (CMAKE_HAS_ANSI_STRING_STREAM) MESSAGE(STATUS "Check for sstream - not found") SET (CMAKE_NO_ANSI_STRING_STREAM 1 CACHE INTERNAL "Does the compiler support sstream") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the CXX compiler has sstream failed with " "the following output:\n${OUTPUT}\n\n") ENDIF (CMAKE_HAS_ANSI_STRING_STREAM) diff --git a/Modules/TestForSTDNamespace.cmake b/Modules/TestForSTDNamespace.cmake index e0991efe3d..58d2ff36cd 100644 --- a/Modules/TestForSTDNamespace.cmake +++ b/Modules/TestForSTDNamespace.cmake @@ -11,14 +11,14 @@ IF("CMAKE_STD_NAMESPACE" MATCHES "^CMAKE_STD_NAMESPACE$") MESSAGE(STATUS "Check for STD namespace - found") SET (CMAKE_NO_STD_NAMESPACE 0 CACHE INTERNAL "Does the compiler support std::.") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the CXX compiler has std namespace passed with " "the following output:\n${OUTPUT}\n\n") ELSE (CMAKE_STD_NAMESPACE) MESSAGE(STATUS "Check for STD namespace - not found") SET (CMAKE_NO_STD_NAMESPACE 1 CACHE INTERNAL "Does the compiler support std::.") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the CXX compiler has std namespace failed with " "the following output:\n${OUTPUT}\n\n") ENDIF (CMAKE_STD_NAMESPACE) diff --git a/Modules/kde3uic.cmake b/Modules/kde3uic.cmake index 948372927e..f41b2a3b62 100644 --- a/Modules/kde3uic.cmake +++ b/Modules/kde3uic.cmake @@ -4,7 +4,7 @@ # neundorf@kde.org -EXECUTE_PROCESS(COMMAND uic +EXECUTE_PROCESS(COMMAND ${KDE_UIC_EXECUTABLE} -nounload -tr tr2i18n -impl ${KDE_UIC_H_FILE} ${KDE_UIC_FILE} diff --git a/Source/CPack/cmCPackGenericGenerator.cxx b/Source/CPack/cmCPackGenericGenerator.cxx index 846226cb89..f4e51b3af5 100644 --- a/Source/CPack/cmCPackGenericGenerator.cxx +++ b/Source/CPack/cmCPackGenericGenerator.cxx @@ -43,6 +43,21 @@ cmCPackGenericGenerator::~cmCPackGenericGenerator() } //---------------------------------------------------------------------- +void cmCPackGenericGeneratorProgress(const char *msg, float prog, void* ptr) +{ + cmCPackGenericGenerator* self = static_cast<cmCPackGenericGenerator*>(ptr); + self->DisplayVerboseOutput(msg, prog); +} + +//---------------------------------------------------------------------- +void cmCPackGenericGenerator::DisplayVerboseOutput(const char* msg, + float progress) +{ + (void)progress; + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "" << msg << std::endl); +} + +//---------------------------------------------------------------------- int cmCPackGenericGenerator::PrepareNames() { this->SetOption("CPACK_GENERATOR", this->Name.c_str()); @@ -152,6 +167,7 @@ int cmCPackGenericGenerator::InstallProject() ignoreFilesRegex.push_back(it->c_str()); } } + this->CleanTemporaryDirectory(); const char* tempInstallDirectory = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY"); int res = 1; @@ -174,6 +190,9 @@ int cmCPackGenericGenerator::InstallProject() destDir += tempInstallDirectory; cmSystemTools::PutEnv(destDir.c_str()); } + + // If the CPackConfig file sets CPACK_INSTALL_COMMANDS then run them + // as listed const char* installCommands = this->GetOption("CPACK_INSTALL_COMMANDS"); if ( installCommands && *installCommands ) { @@ -207,6 +226,10 @@ int cmCPackGenericGenerator::InstallProject() } } } + + // If the CPackConfig file sets CPACK_INSTALLED_DIRECTORIES + // then glob it and copy it to CPACK_TEMPORARY_DIRECTORY + // This is used in Source packageing const char* installDirectories = this->GetOption("CPACK_INSTALLED_DIRECTORIES"); if ( installDirectories && *installDirectories ) @@ -281,6 +304,9 @@ int cmCPackGenericGenerator::InstallProject() } } } + + // If the project is a CMAKE project then run pre-install + // and then read the cmake_install script to run it const char* cmakeProjects = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS"); const char* cmakeGenerator @@ -346,7 +372,7 @@ int cmCPackGenericGenerator::InstallProject() = globalGenerator->GenerateBuildCommand(cmakeMakeProgram, installProjectName.c_str(), 0, globalGenerator->GetPreinstallTargetName(), - buildConfig, false); + buildConfig, false, false); cmCPackLogger(cmCPackLog::LOG_DEBUG, "- Install command: " << buildCommand << std::endl); cmCPackLogger(cmCPackLog::LOG_OUTPUT, @@ -381,6 +407,7 @@ int cmCPackGenericGenerator::InstallProject() cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Install project: " << installProjectName << std::endl); cmake cm; + cm.SetProgressCallback(cmCPackGenericGeneratorProgress, this); cmGlobalGenerator gg; gg.SetCMakeInstance(&cm); std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator()); @@ -414,6 +441,8 @@ int cmCPackGenericGenerator::InstallProject() } } } + + // ????? const char* binaryDirectories = this->GetOption("CPACK_BINARY_DIR"); if ( binaryDirectories && !cmakeProjects ) { @@ -846,3 +875,25 @@ bool cmCPackGenericGenerator::ConfigureFile(const char* inName, return this->MakefileMap->ConfigureFile(inName, outName, false, true, false) == 1; } + +//---------------------------------------------------------------------- +int cmCPackGenericGenerator::CleanTemporaryDirectory() +{ + const char* tempInstallDirectory + = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY"); + if(cmsys::SystemTools::FileExists(tempInstallDirectory)) + { + cmCPackLogger(cmCPackLog::LOG_OUTPUT, + "- Clean temporary : " + << tempInstallDirectory << std::endl); + if(!cmsys::SystemTools::RemoveADirectory(tempInstallDirectory)) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Problem removing temporary directory: " << + tempInstallDirectory + << std::endl); + return 0; + } + } + return 1; +} diff --git a/Source/CPack/cmCPackGenericGenerator.h b/Source/CPack/cmCPackGenericGenerator.h index 6867613232..87c486d425 100644 --- a/Source/CPack/cmCPackGenericGenerator.h +++ b/Source/CPack/cmCPackGenericGenerator.h @@ -87,10 +87,13 @@ public: //! Set the logger void SetLogger(cmCPackLog* log) { this->Logger = log; } + //! Display verbose information via logger + void DisplayVerboseOutput(const char* msg, float progress); + protected: int PrepareNames(); int InstallProject(); - + int CleanTemporaryDirectory(); virtual const char* GetOutputExtension() { return "cpack"; } virtual const char* GetOutputPostfix() { return 0; } virtual int CompressFiles(const char* outFileName, const char* toplevel, diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index b7a27d9ce9..6948bc6dec 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -196,7 +196,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) this->SourceDir.c_str(), this->BinaryDir.c_str(), this->BuildProject.c_str(), tarIt->c_str(), &output, this->BuildMakeProgram.c_str(), - this->CTest->GetConfigType().c_str(),!this->BuildNoClean); + this->CTest->GetConfigType().c_str(),!this->BuildNoClean, false); out << output; // if the build failed then return diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index 78381185be..f6a196dd21 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -93,7 +93,7 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() std::string buildCommand = this->GlobalGenerator->GenerateBuildCommand(cmakeMakeProgram, cmakeProjectName, - cmakeBuildAdditionalFlags, 0, cmakeBuildConfiguration, true); + cmakeBuildAdditionalFlags, 0, cmakeBuildConfiguration, true, false); this->CTest->SetCTestConfiguration("MakeCommand", buildCommand.c_str()); } else diff --git a/Source/CursesDialog/form/form.priv.h b/Source/CursesDialog/form/form.priv.h index 886121c94c..3691f2fd0c 100644 --- a/Source/CursesDialog/form/form.priv.h +++ b/Source/CursesDialog/form/form.priv.h @@ -33,6 +33,12 @@ #include "mf_common.h" #include "form.h" +/* get around odd bug on aCC and itanium */ +#if defined(__hpux) && defined(__ia64) +#define getmaxx __getmaxx +#define getmaxy __getmaxy +#endif + /* form status values */ #define _OVLMODE (0x04) /* Form is in overlay mode */ #define _WINDOW_MODIFIED (0x10) /* Current field window has been modified */ @@ -41,7 +47,7 @@ /* field status values */ #define _CHANGED (0x01) /* Field has been changed */ #define _NEWTOP (0x02) /* Vertical scrolling occured */ -#define _NEWPAGE (0x04) /* field begins new page of form */ +#define _NEWPAGE (0x04) /* field begins new page of form */ #define _MAY_GROW (0x08) /* dynamic field may still grow */ /* fieldtype status values */ @@ -91,20 +97,20 @@ typedef struct typearg { #define FIRST_ACTIVE_MAGIC (-291056) #define ALL_FORM_OPTS ( \ - O_NL_OVERLOAD |\ - O_BS_OVERLOAD ) + O_NL_OVERLOAD |\ + O_BS_OVERLOAD ) #define ALL_FIELD_OPTS ( \ - O_VISIBLE |\ - O_ACTIVE |\ - O_PUBLIC |\ - O_EDIT |\ - O_WRAP |\ - O_BLANK |\ - O_AUTOSKIP|\ - O_NULLOK |\ - O_PASSOK |\ - O_STATIC ) + O_VISIBLE |\ + O_ACTIVE |\ + O_PUBLIC |\ + O_EDIT |\ + O_WRAP |\ + O_BLANK |\ + O_AUTOSKIP|\ + O_NULLOK |\ + O_PASSOK |\ + O_STATIC ) #define C_BLANK ' ' diff --git a/Source/MFCDialog/CMakeSetupDialog.cpp b/Source/MFCDialog/CMakeSetupDialog.cpp index 534f71347a..0a605f2e70 100644 --- a/Source/MFCDialog/CMakeSetupDialog.cpp +++ b/Source/MFCDialog/CMakeSetupDialog.cpp @@ -83,7 +83,7 @@ void MFCMessageCallback(const char* m, const char* title, bool& nomore, void*) // CMakeSetupDialog dialog void updateProgress(const char *msg, float prog, void *cd) { - char tmp[1024]; + char* tmp = new char[strlen(msg) + 40]; if (prog >= 0) { sprintf(tmp,"%s %i%%",msg,(int)(100*prog)); @@ -120,6 +120,7 @@ void updateProgress(const char *msg, float prog, void *cd) break; } } + delete [] tmp; } // Convert to Win32 path (slashes). This calls the system tools one and then diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h index 7a40c477e1..bacce8fa02 100644 --- a/Source/cmAddCustomCommandCommand.h +++ b/Source/cmAddCustomCommandCommand.h @@ -74,7 +74,9 @@ public: " [WORKING_DIRECTORY dir]\n" " [COMMENT comment])\n" "This defines a new command that can be executed during the build " - "process. Note that MAIN_DEPENDENCY is completely optional and is " + "process. The outputs named should be listed as source files in the " + "target for which they are to be generated. " + "Note that MAIN_DEPENDENCY is completely optional and is " "used as a suggestion to visual studio about where to hang the " "custom command. In makefile terms this creates a new target in the " "following form:\n" @@ -100,9 +102,9 @@ public: " POST_BUILD - run after the target has been built\n" "Note that the PRE_BUILD option is only supported on Visual " "Studio 7 or later. For all other generators PRE_BUILD " - "will be treated as PRE_LINK." - "If WORKING_DIRECTORY is specified the command a cd \"dir\" is " - "done prior to running the command."; + "will be treated as PRE_LINK. " + "If WORKING_DIRECTORY is specified the command will be executed " + "in the directory given."; } cmTypeMacro(cmAddCustomCommandCommand, cmCommand); diff --git a/Source/cmAddCustomTargetCommand.h b/Source/cmAddCustomTargetCommand.h index 7bc8c5d302..4a448b3ea1 100644 --- a/Source/cmAddCustomTargetCommand.h +++ b/Source/cmAddCustomTargetCommand.h @@ -70,13 +70,16 @@ public: "Adds a target with the given name that executes the given commands " "every time the target is built. If the ALL option is specified " "it indicates that this target should be added to the default build " - "target so that it will be run every time. " - "The command and arguments are optional. If not specified, " - "it will create an empty target. The ADD_DEPENDENCIES command can be " - "used in conjunction with this command to drive custom target " - "generation. The command cannot be called ALL. " + "target so that it will be run every time " + "(the command cannot be called ALL). " + "The command and arguments are optional and if not specified an " + "empty target will be created. " "If WORKING_DIRECTORY is set, then the command will be run in that " - "directory."; + "directory. " + "Dependencies listed with the DEPENDS argument may reference files " + "and outputs of custom commands created with ADD_CUSTOM_COMMAND. " + "Dependencies on other targets may be added using the " + "ADD_DEPENDENCIES command."; } cmTypeMacro(cmAddCustomTargetCommand, cmCommand); diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx index 5e13150802..6591b4432d 100644 --- a/Source/cmAddSubDirectoryCommand.cxx +++ b/Source/cmAddSubDirectoryCommand.cxx @@ -54,14 +54,12 @@ bool cmAddSubDirectoryCommand::InitialPass } // check for relative arguments - bool relativeSource = true; std::string binPath = binArg; std::string srcPath = std::string(this->Makefile->GetCurrentDirectory()) + "/" + srcArg; // if the path does not exist then the arg was relative if (!cmSystemTools::FileIsDirectory(srcPath.c_str())) { - relativeSource = false; srcPath = srcArg; if (!cmSystemTools::FileIsDirectory(srcPath.c_str())) { @@ -74,6 +72,7 @@ bool cmAddSubDirectoryCommand::InitialPass // at this point srcPath has the full path to the source directory // now we need to compute the binPath if it was not provided + srcPath = cmSystemTools::CollapseFullPath(srcPath.c_str()); // if the argument was provided then use it if (binArg.size()) @@ -87,21 +86,13 @@ bool cmAddSubDirectoryCommand::InitialPass // otherwise compute the binPath from the srcPath else { - // if the srcArg was relative then we just do the same for the binPath - if (relativeSource) - { - binPath = std::string(this->Makefile->GetCurrentOutputDirectory()) + - "/" + srcArg; - } - // otherwise we try to remove the CurrentDirectory from the srcPath and + // we try to remove the CurrentDirectory from the srcPath and // replace it with the CurrentOutputDirectory. This may not really work // because the source dir they provided may not be "in" the source // tree. This is an error if this happens. - else - { // try replacing the home dir with the home output dir binPath = srcPath; - if (!cmSystemTools::FindLastString(binPath.c_str(), + if(!cmSystemTools::FindLastString(binPath.c_str(), this->Makefile->GetHomeDirectory())) { this->SetError("A full source directory was specified that is not " @@ -114,7 +105,6 @@ bool cmAddSubDirectoryCommand::InitialPass cmSystemTools::ReplaceString(binPath, this->Makefile->GetHomeDirectory(), this->Makefile->GetHomeOutputDirectory()); - } } // now we have all the arguments diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx index 13443b0eb7..405b463d53 100644 --- a/Source/cmBuildCommand.cxx +++ b/Source/cmBuildCommand.cxx @@ -34,7 +34,7 @@ bool cmBuildCommand::InitialPass(std::vector<std::string> const& args) std::string makecommand = this->Makefile->GetLocalGenerator() ->GetGlobalGenerator()->GenerateBuildCommand (makeprogram.c_str(), this->Makefile->GetProjectName(), 0, - 0, "Release", true); + 0, "Release", true, false); if(cacheValue) { diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index a0a231f1b5..5eecb1dccf 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -19,6 +19,7 @@ #include "cmSystemTools.h" #include "cmCacheManager.h" #include "cmMakefile.h" +#include "cmake.h" #include <cmsys/Directory.hxx> #include <cmsys/Glob.hxx> @@ -163,7 +164,8 @@ bool cmCacheManager::ParseEntry(const char* entry, void cmCacheManager::CleanCMakeFiles(const char* path) { std::string glob = path; - glob += "/CMakeFiles/*.cmake"; + glob += cmake::GetCMakeFilesDirectory(); + glob += "/*.cmake"; cmsys::Glob globIt; globIt.FindFiles(glob); std::vector<std::string> files = globIt.GetFiles(); @@ -601,7 +603,7 @@ bool cmCacheManager::SaveCache(const char* path) cacheFile.c_str()); cmSystemTools::RemoveFile(tempFile.c_str()); std::string checkCacheFile = path; - checkCacheFile += "/CMakeFiles"; + checkCacheFile += cmake::GetCMakeFilesDirectory(); cmSystemTools::MakeDirectory(checkCacheFile.c_str()); checkCacheFile += "/cmake.check_cache"; std::ofstream checkCache(checkCacheFile.c_str()); @@ -626,7 +628,7 @@ bool cmCacheManager::DeleteCache(const char* path) // now remove the files in the CMakeFiles directory // this cleans up language cache files cmsys::Directory dir; - cmakeFiles += "/CMakeFiles"; + cmakeFiles += cmake::GetCMakeFilesDirectory(); dir.Load(cmakeFiles.c_str()); for (unsigned long fileNum = 0; fileNum < dir.GetNumberOfFiles(); diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx index f6d577c77a..37c177b3be 100644 --- a/Source/cmDepends.cxx +++ b/Source/cmDepends.cxx @@ -22,7 +22,11 @@ #include <string.h> //---------------------------------------------------------------------------- -cmDepends::cmDepends(): Verbose(false), FileComparison(0), +cmDepends::cmDepends(): + CompileDirectory(), + LocalGenerator(0), + Verbose(false), + FileComparison(0), MaxPath(cmSystemTools::GetMaximumFilePathLength()), Dependee(new char[MaxPath]), Depender(new char[MaxPath]) diff --git a/Source/cmDepends.h b/Source/cmDepends.h index d6269af2e0..b7a11def1e 100644 --- a/Source/cmDepends.h +++ b/Source/cmDepends.h @@ -20,6 +20,7 @@ #include "cmStandardIncludes.h" class cmFileTimeComparison; +class cmLocalGenerator; /** \class cmDepends * \brief Dependency scanner superclass. @@ -38,11 +39,11 @@ public: /** at what level will the compile be done from */ void SetCompileDirectory(const char *dir) {this->CompileDirectory = dir;}; - /** Set the full path to the top of the build tree. This is - the base path from which dependencies are referenced as - relative paths. */ - void SetHomeOutputDirectory(const char *dir) { - this->HomeOutputDirectory = dir;}; + /** Set the local generator for the directory in which we are + scanning dependencies. This is not a full local generator; it + has been setup to do relative path conversions for the current + directory. */ + void SetLocalGenerator(cmLocalGenerator* lg) { this->LocalGenerator = lg; } /** should this be verbose in its output */ void SetVerbose(bool verb) { this->Verbose = verb; } @@ -79,8 +80,8 @@ protected: // The directory in which the build rule for the target file is executed. std::string CompileDirectory; - // The full path to the top of the build tree. - std::string HomeOutputDirectory; + // The local generator. + cmLocalGenerator* LocalGenerator; // Flag for verbose output. bool Verbose; diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index ad1d021529..7806ab3389 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -16,8 +16,9 @@ =========================================================================*/ #include "cmDependsC.h" -#include "cmSystemTools.h" #include "cmFileTimeComparison.h" +#include "cmLocalGenerator.h" +#include "cmSystemTools.h" #include <ctype.h> // isspace @@ -194,13 +195,18 @@ bool cmDependsC::WriteDependencies(const char *src, const char *obj, first = false; } - // Write the dependencies to the output stream. + // Write the dependencies to the output stream. Makefile rules + // written by the original local generator for this directory + // convert the dependencies to paths relative to the home output + // directory. We must do the same here. internalDepends << obj << std::endl; for(std::set<cmStdString>::iterator i=dependencies.begin(); i != dependencies.end(); ++i) { - makeDepends << obj << ": " - << cmSystemTools::ConvertToOutputPath(i->c_str()).c_str() + makeDepends << obj << ": " << + this->LocalGenerator->Convert(i->c_str(), + cmLocalGenerator::HOME_OUTPUT, + cmLocalGenerator::MAKEFILE) << std::endl; internalDepends << " " << i->c_str() << std::endl; } @@ -370,8 +376,9 @@ bool cmDependsC::FileExistsOrIsGenerated(const std::string& fname, // Note that CMAKE_GENERATED_FILES is written with a conversion // relative to the home output directory. std::string rname = - cmSystemTools::RelativePath(this->HomeOutputDirectory.c_str(), - fname.c_str()); + this->LocalGenerator->Convert(fname.c_str(), + cmLocalGenerator::HOME_OUTPUT, + cmLocalGenerator::UNCHANGED); if(this->FileIsGenerated(rname, scanned, dependencies)) { return true; diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 27c5e58e12..bbf42658f0 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -233,6 +233,11 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, } g.SetRelative(i->c_str()); ++i; + if(i == args.end()) + { + this->SetError("GLOB requires a glob expression after the directory"); + return false; + } } if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) ) { @@ -775,15 +780,10 @@ bool cmFileCommand::HandleInstallCommand( std::string libname = toFile; std::string soname = toFile; std::string soname_nopath = fromName; - soname += "."; - soname += lib_soversion; - soname_nopath += "."; - soname_nopath += lib_soversion; - - fromName += "."; - fromName += lib_version; - toFile += "."; - toFile += lib_version; + this->ComputeVersionedName(soname, lib_soversion); + this->ComputeVersionedName(soname_nopath, lib_soversion); + this->ComputeVersionedName(fromName, lib_version); + this->ComputeVersionedName(toFile, lib_version); cmSystemTools::RemoveFile(soname.c_str()); cmSystemTools::RemoveFile(libname.c_str()); @@ -946,6 +946,26 @@ bool cmFileCommand::HandleInstallCommand( } //---------------------------------------------------------------------------- +void cmFileCommand::ComputeVersionedName(std::string& name, + const char* version) +{ +#if defined(__APPLE__) + std::string ext; + kwsys_stl::string::size_type dot_pos = name.rfind("."); + if(dot_pos != name.npos) + { + ext = name.substr(dot_pos, name.npos); + name = name.substr(0, dot_pos); + } +#endif + name += "."; + name += version; +#if defined(__APPLE__) + name += ext; +#endif +} + +//---------------------------------------------------------------------------- bool cmFileCommand::HandleRelativePathCommand( std::vector<std::string> const& args) { diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index 249cbb6093..610fb7d65e 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -125,6 +125,7 @@ protected: bool HandleRelativePathCommand(std::vector<std::string> const& args); bool HandleCMakePathCommand(std::vector<std::string> const& args, bool nativePath); + void ComputeVersionedName(std::string& name, const char* version); }; diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index fe53b1289e..b7f388bc26 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -26,13 +26,17 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) return false; } - // at end of for each execute recorded commands - if (cmSystemTools::LowerCase(lff.Name) == "endforeach") + if (!cmSystemTools::Strucmp(lff.Name.c_str(),"foreach")) { - std::vector<std::string> expandedArguments; - mf.ExpandArguments(lff.Arguments, expandedArguments); - if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0])) + // record the number of nested foreach commands + this->Depth++; + } + else if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endforeach")) + { + // if this is the endofreach for this statement + if (!this->Depth) { + // at end of for each execute recorded commands // store the old value std::string oldDef; if (mf.GetDefinition(this->Args[0].c_str())) @@ -60,6 +64,11 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) mf.RemoveFunctionBlocker(lff); return true; } + else + { + // close out a nested foreach + this->Depth--; + } } // record the command @@ -72,11 +81,13 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) bool cmForEachFunctionBlocker:: ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) { - if(cmSystemTools::LowerCase(lff.Name) == "endforeach") + if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endforeach")) { std::vector<std::string> expandedArguments; mf.ExpandArguments(lff.Arguments, expandedArguments); - if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0])) + if ((!expandedArguments.empty() && + (expandedArguments[0] == this->Args[0])) + || mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS")) { return true; } diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h index 5a303596a1..04843c4789 100644 --- a/Source/cmForEachCommand.h +++ b/Source/cmForEachCommand.h @@ -29,7 +29,7 @@ class cmForEachFunctionBlocker : public cmFunctionBlocker { public: - cmForEachFunctionBlocker() {this->Executing = false;} + cmForEachFunctionBlocker() {this->Executing = false; Depth = 0;} virtual ~cmForEachFunctionBlocker() {} virtual bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf); @@ -39,6 +39,8 @@ public: std::vector<std::string> Args; std::vector<cmListFileFunction> Functions; bool Executing; +private: + int Depth; }; /** \class cmForEachCommand diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx index 5018a8c26c..1ce506dbd9 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.cxx +++ b/Source/cmGlobalBorlandMakefileGenerator.cxx @@ -25,6 +25,7 @@ cmGlobalBorlandMakefileGenerator::cmGlobalBorlandMakefileGenerator() this->FindMakeProgramFile = "CMakeBorlandFindMake.cmake"; this->ForceUnixPaths = false; this->ToolSupportsColor = true; + this->UseLinkScript = false; } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index ca1c126976..42e404f14b 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -36,6 +36,12 @@ cmGlobalGenerator::cmGlobalGenerator() // By default do not try to support color. this->ToolSupportsColor = false; + + // By default do not use link scripts. + this->UseLinkScript = false; + + // Relative paths are not configured in the constructor. + this->RelativePathsConfigured = false; } cmGlobalGenerator::~cmGlobalGenerator() @@ -175,7 +181,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, } mf->AddDefinition("RUN_CONFIGURE", true); std::string rootBin = mf->GetHomeOutputDirectory(); - rootBin += "/CMakeFiles"; + rootBin += cmake::GetCMakeFilesDirectory(); // If the configuration files path has been set, // then we are in a try compile and need to copy the enable language @@ -589,8 +595,6 @@ void cmGlobalGenerator::Configure() } this->LocalGenerators.clear(); - // Setup relative path generation. - this->ConfigureRelativePaths(); this->TotalTargets.clear(); // start with this directory @@ -772,13 +776,13 @@ int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir, const char* config = mf->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"); return this->Build(srcdir,bindir,projectName, newTarget.c_str(), - output,makeCommand.c_str(),config,false); + output,makeCommand.c_str(),config,false,true); } std::string cmGlobalGenerator ::GenerateBuildCommand(const char* makeProgram, const char *projectName, const char* additionalOptions, const char *targetName, - const char* config, bool ignoreErrors) + const char* config, bool ignoreErrors, bool) { // Project name and config are not used yet. (void)projectName; @@ -816,7 +820,7 @@ int cmGlobalGenerator::Build( std::string *output, const char *makeCommandCSTR, const char *config, - bool clean) + bool clean, bool fast) { *output += "\nTesting TryCompileWithoutMakefile\n"; @@ -836,7 +840,7 @@ int cmGlobalGenerator::Build( { std::string cleanCommand = this->GenerateBuildCommand(makeCommandCSTR, projectName, - 0, "clean", config, false); + 0, "clean", config, false, fast); if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), output, &retVal, 0, false, timeout)) { @@ -856,7 +860,7 @@ int cmGlobalGenerator::Build( // now build std::string makeCommand = this->GenerateBuildCommand(makeCommandCSTR, projectName, - 0, target, config, false); + 0, target, config, false, fast); if (!cmSystemTools::RunSingleCommand(makeCommand.c_str(), output, &retVal, 0, false, timeout)) @@ -932,7 +936,7 @@ cmLocalGenerator *cmGlobalGenerator::CreateLocalGenerator() void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator *gen ) { std::string cfp = gen->GetCMakeInstance()->GetHomeOutputDirectory(); - cfp += "/CMakeFiles"; + cfp += cmake::GetCMakeFilesDirectory(); this->SetConfiguredFilesPath(cfp.c_str()); const char* make = gen->GetCMakeInstance()->GetCacheDefinition("CMAKE_MAKE_PROGRAM"); @@ -1097,6 +1101,13 @@ std::string cmGlobalGenerator return in_remote; } + // Make sure relative path conversion is configured. + if(!this->RelativePathsConfigured) + { + this->ConfigureRelativePaths(); + this->RelativePathsConfigured = true; + } + std::string original = in_remote; // Skip conversion if the path and local are not both in the source or both @@ -1219,6 +1230,12 @@ inline std::string removeQuotes(const std::string& s) return s; } +void cmGlobalGenerator::SetCMakeInstance(cmake* cm) +{ + // Store a pointer to the cmake object instance. + this->CMakeInstance = cm; +} + void cmGlobalGenerator::SetupTests() { std::string ctest = this->LocalGenerators[0]->GetMakefile()-> diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 1134c2a99f..07ee8d82da 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -100,16 +100,16 @@ public: const char *projectName, const char *targetName, std::string *output, const char *makeProgram, const char *config, - bool clean); + bool clean, bool fast); virtual std::string GenerateBuildCommand (const char* makeProgram, const char *projectName, const char* additionalOptions, const char *targetName, - const char* config, bool ignoreErrors); + const char* config, bool ignoreErrors, bool fast); ///! Set the CMake instance - void SetCMakeInstance(cmake *cm) { this->CMakeInstance = cm; }; + void SetCMakeInstance(cmake *cm); ///! Get the CMake instance cmake *GetCMakeInstance() { return this->CMakeInstance; }; @@ -152,6 +152,9 @@ public: std::string ConvertToRelativePath(const std::vector<std::string>& local, const char* remote); + /** Get whether the generator should use a script for link commands. */ + bool GetUseLinkScript() { return this->UseLinkScript; } + /* * Determine what program to use for building the project. */ @@ -197,6 +200,7 @@ protected: bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen); void ConfigureRelativePaths(); + bool RelativePathsConfigured; void SetupTests(); void CreateDefaultGlobalTargets(cmTargets* targets); @@ -204,6 +208,7 @@ protected: const cmCustomCommandLines* commandLines, std::vector<std::string> depends, bool depends_on_all = false); + bool UseLinkScript; bool ForceUnixPaths; bool ToolSupportsColor; cmStdString FindMakeProgramFile; diff --git a/Source/cmGlobalKdevelopGenerator.cxx b/Source/cmGlobalKdevelopGenerator.cxx index 244e0319f9..ca902169ae 100644 --- a/Source/cmGlobalKdevelopGenerator.cxx +++ b/Source/cmGlobalKdevelopGenerator.cxx @@ -134,7 +134,9 @@ bool cmGlobalKdevelopGenerator tmp=*lt; cmSystemTools::ReplaceString(tmp, projectDir.c_str(), ""); // make sure the file is part of this source tree - if ((tmp[0]!='/') && (strstr(tmp.c_str(), "CMakeFiles/")==0)) + if ((tmp[0]!='/') && + (strstr(tmp.c_str(), + cmake::GetCMakeFilesDirectoryPostSlash())==0)) { files.insert(tmp); tmp=cmSystemTools::GetFilenameName(tmp); @@ -159,7 +161,9 @@ bool cmGlobalKdevelopGenerator { tmp=(*si)->GetFullPath(); cmSystemTools::ReplaceString(tmp, projectDir.c_str(), ""); - if ((tmp[0]!='/') && (strstr(tmp.c_str(), "CMakeFiles/")==0)) + if ((tmp[0]!='/') && + (strstr(tmp.c_str(), + cmake::GetCMakeFilesDirectoryPostSlash())==0)) { files.insert(tmp); } @@ -169,7 +173,9 @@ bool cmGlobalKdevelopGenerator { tmp=*lt; cmSystemTools::ReplaceString(tmp, projectDir.c_str(), ""); - if ((tmp[0]!='/') && (strstr(tmp.c_str(), "CMakeFiles/")==0)) + if ((tmp[0]!='/') && + (strstr(tmp.c_str(), + cmake::GetCMakeFilesDirectoryPostSlash())==0)) { files.insert(tmp.c_str()); } diff --git a/Source/cmGlobalMSYSMakefileGenerator.cxx b/Source/cmGlobalMSYSMakefileGenerator.cxx index ca1a292b83..53ea6492c2 100644 --- a/Source/cmGlobalMSYSMakefileGenerator.cxx +++ b/Source/cmGlobalMSYSMakefileGenerator.cxx @@ -24,6 +24,7 @@ cmGlobalMSYSMakefileGenerator::cmGlobalMSYSMakefileGenerator() this->FindMakeProgramFile = "CMakeMSYSFindMake.cmake"; this->ForceUnixPaths = true; this->ToolSupportsColor = true; + this->UseLinkScript = false; } std::string diff --git a/Source/cmGlobalMinGWMakefileGenerator.cxx b/Source/cmGlobalMinGWMakefileGenerator.cxx index 7e9ad82a93..f66134c595 100644 --- a/Source/cmGlobalMinGWMakefileGenerator.cxx +++ b/Source/cmGlobalMinGWMakefileGenerator.cxx @@ -23,6 +23,7 @@ cmGlobalMinGWMakefileGenerator::cmGlobalMinGWMakefileGenerator() this->FindMakeProgramFile = "CMakeMinGWFindMake.cmake"; this->ForceUnixPaths = true; this->ToolSupportsColor = true; + this->UseLinkScript = true; } void cmGlobalMinGWMakefileGenerator diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx index bfb09db26e..35a2a86bf1 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.cxx +++ b/Source/cmGlobalNMakeMakefileGenerator.cxx @@ -23,6 +23,7 @@ cmGlobalNMakeMakefileGenerator::cmGlobalNMakeMakefileGenerator() this->FindMakeProgramFile = "CMakeNMakeFindMake.cmake"; this->ForceUnixPaths = false; this->ToolSupportsColor = true; + this->UseLinkScript = false; } void cmGlobalNMakeMakefileGenerator diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 7c506ea9f5..df34fa3f73 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -20,6 +20,8 @@ #include "cmMakefile.h" #include "cmake.h" #include "cmGeneratedFileStream.h" +#include "cmSourceFile.h" +#include "cmTarget.h" cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3() { @@ -27,6 +29,13 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3() this->ForceUnixPaths = true; this->FindMakeProgramFile = "CMakeUnixFindMake.cmake"; this->ToolSupportsColor = true; + this->NumberOfSourceFiles = 0; + this->NumberOfSourceFilesWritten = 0; +#ifdef _WIN32 + this->UseLinkScript = false; +#else + this->UseLinkScript = true; +#endif } void cmGlobalUnixMakefileGenerator3 @@ -110,8 +119,83 @@ cmGlobalUnixMakefileGenerator3 } //---------------------------------------------------------------------------- +int cmGlobalUnixMakefileGenerator3::ShouldAddProgressRule() +{ + // add progress to 100 source files + if (this->NumberOfSourceFiles && + (((this->NumberOfSourceFilesWritten + 1)*100)/this->NumberOfSourceFiles) + -(this->NumberOfSourceFilesWritten*100)/this->NumberOfSourceFiles) + { + this->NumberOfSourceFilesWritten++; + return (this->NumberOfSourceFilesWritten*100)/this->NumberOfSourceFiles; + } + this->NumberOfSourceFilesWritten++; + return 0; +} + +int cmGlobalUnixMakefileGenerator3:: +GetNumberOfCompilableSourceFilesForTarget(cmTarget &tgt) +{ + std::map<cmStdString, int >::iterator tgtI = + this->TargetSourceFileCount.find(tgt.GetName()); + if (tgtI != this->TargetSourceFileCount.end()) + { + return tgtI->second; + } + + int result = 0; + + if((tgt.GetType() == cmTarget::EXECUTABLE) || + (tgt.GetType() == cmTarget::STATIC_LIBRARY) || + (tgt.GetType() == cmTarget::SHARED_LIBRARY) || + (tgt.GetType() == cmTarget::MODULE_LIBRARY) ) + { + std::vector<cmSourceFile*>& sources = tgt.GetSourceFiles(); + for(std::vector<cmSourceFile*>::iterator source = sources.begin(); + source != sources.end(); ++source) + { + if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY") && + !(*source)->GetCustomCommand()) + { + if(!this->IgnoreFile((*source)->GetSourceExtension().c_str())) + { + const char* lang = + static_cast<cmLocalUnixMakefileGenerator3 *> + (tgt.GetMakefile()->GetLocalGenerator()) + ->GetSourceFileLanguage(**source); + if(lang) + { + result++; + } + } + } + } + } + this->TargetSourceFileCount[tgt.GetName()] = result; + return result; +} + + +//---------------------------------------------------------------------------- void cmGlobalUnixMakefileGenerator3::Generate() { + // initialize progress + this->NumberOfSourceFiles = 0; + unsigned int i; + for (i = 0; i < this->LocalGenerators.size(); ++i) + { + // for all of out targets + for (cmTargets::iterator l = + this->LocalGenerators[i]->GetMakefile()->GetTargets().begin(); + l != this->LocalGenerators[i]->GetMakefile()->GetTargets().end(); + l++) + { + this->NumberOfSourceFiles += + this->GetNumberOfCompilableSourceFilesForTarget(l->second); + } + } + this->NumberOfSourceFilesWritten = 0; + // first do superclass method this->cmGlobalGenerator::Generate(); @@ -127,7 +211,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2() // see if the build system must be regenerated. std::string makefileName = this->GetCMakeInstance()->GetHomeOutputDirectory(); - makefileName += "/CMakeFiles/Makefile2"; + makefileName += cmake::GetCMakeFilesDirectory(); + makefileName += "/Makefile2"; cmGeneratedFileStream makefileStream(makefileName.c_str()); if(!makefileStream) { @@ -214,7 +299,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() // see if the build system must be regenerated. std::string cmakefileName = this->GetCMakeInstance()->GetHomeOutputDirectory(); - cmakefileName += "/CMakeFiles/Makefile.cmake"; + cmakefileName += cmake::GetCMakeFilesDirectory(); + cmakefileName += "/Makefile.cmake"; cmGeneratedFileStream cmakefileStream(cmakefileName.c_str()); if(!cmakefileStream) { @@ -281,7 +367,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() // Build the path to the cache check file. std::string check = this->GetCMakeInstance()->GetHomeOutputDirectory(); - check += "/CMakeFiles/cmake.check_cache"; + check += cmake::GetCMakeFilesDirectory(); + check += "/cmake.check_cache"; // Set the corresponding makefile in the cmake file. cmakefileStream @@ -301,7 +388,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() lg = static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]); tmpStr = lg->GetMakefile()->GetStartOutputDirectory(); - tmpStr += "/CMakeFiles/CMakeDirectoryInformation.cmake"; + tmpStr += cmake::GetCMakeFilesDirectory(); + tmpStr += "/CMakeDirectoryInformation.cmake"; cmakefileStream << " \"" << lg->Convert(tmpStr.c_str(),cmLocalGenerator::HOME_OUTPUT).c_str() << "\"\n"; @@ -518,7 +606,7 @@ cmGlobalUnixMakefileGenerator3 std::string cmGlobalUnixMakefileGenerator3 ::GenerateBuildCommand(const char* makeProgram, const char *projectName, const char* additionalOptions, const char *targetName, - const char* config, bool ignoreErrors) + const char* config, bool ignoreErrors, bool fast) { // Project name and config are not used yet. (void)projectName; @@ -565,7 +653,10 @@ std::string cmGlobalUnixMakefileGenerator3 lg->SetupPathConversions(); makeCommand += " \""; std::string tname = targetName; + if(fast) + { tname += "/fast"; + } tname = lg->Convert(tname.c_str(),cmLocalGenerator::HOME_OUTPUT, cmLocalGenerator::MAKEFILE); tname = lg->ConvertToMakeTarget(tname.c_str()); @@ -601,18 +692,20 @@ cmGlobalUnixMakefileGenerator3 cmTargets& targets = lg->GetMakefile()->GetTargets(); for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t) { - if((t->second.GetType() == cmTarget::EXECUTABLE) || - (t->second.GetType() == cmTarget::STATIC_LIBRARY) || - (t->second.GetType() == cmTarget::SHARED_LIBRARY) || - (t->second.GetType() == cmTarget::MODULE_LIBRARY) || - (t->second.GetType() == cmTarget::UTILITY)) - { // Don't emit the same rule twice (e.g. two targets with the same // simple name) if(t->second.GetName() && strlen(t->second.GetName()) && emitted.insert(t->second.GetName()).second) { + // Handle user targets here. Global targets are handled in + // the local generator on a per-directory basis. + if((t->second.GetType() == cmTarget::EXECUTABLE) || + (t->second.GetType() == cmTarget::STATIC_LIBRARY) || + (t->second.GetType() == cmTarget::SHARED_LIBRARY) || + (t->second.GetType() == cmTarget::MODULE_LIBRARY) || + (t->second.GetType() == cmTarget::UTILITY)) + { // Add a rule to build the target by name. lg->WriteDivider(ruleFileStream); ruleFileStream @@ -621,8 +714,10 @@ cmGlobalUnixMakefileGenerator3 // Write the rule. commands.clear(); + std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash(); + tmp += "Makefile2"; commands.push_back(lg->GetRecursiveMakeCall - ("CMakeFiles/Makefile2",t->second.GetName())); + (tmp.c_str(),t->second.GetName())); depends.clear(); depends.push_back("cmake_check_build_system"); lg->WriteMakeRule(ruleFileStream, @@ -647,17 +742,6 @@ cmGlobalUnixMakefileGenerator3 localName.c_str(), depends, commands, true); } } - else - { - // Add a fast rule to build the target - depends.clear(); - commands.clear(); - std::string localName = t->second.GetName(); - depends.push_back(localName); - localName += "/fast"; - lg->WriteMakeRule(ruleFileStream, "fast build rule for target.", - localName.c_str(), depends, commands, true); - } } } } @@ -675,6 +759,7 @@ cmGlobalUnixMakefileGenerator3 std::string localName; std::string makeTargetName; + // write the directory level rules for this local gen this->WriteDirectoryRules2(ruleFileStream,lg); @@ -731,6 +816,30 @@ cmGlobalUnixMakefileGenerator3 // Write the rule. localName += "/all"; depends.clear(); + + std::string progressDir = + lg->GetMakefile()->GetHomeOutputDirectory(); + progressDir += cmake::GetCMakeFilesDirectory(); + { + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; + // all target counts + progCmd << lg->Convert(progressDir.c_str(), + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + progCmd << " "; + std::vector<int> &progFiles = lg->ProgressFiles[t->first]; + for (std::vector<int>::iterator i = progFiles.begin(); + i != progFiles.end(); ++i) + { + progCmd << " " << *i; + } + commands.push_back(progCmd.str()); + } + progressDir = "Building target "; + progressDir += t->first; + lg->AppendEcho(commands,progressDir.c_str()); + this->AppendGlobalTargetDepends(depends,t->second); lg->WriteMakeRule(ruleFileStream, "All Build rule for target.", localName.c_str(), depends, commands, true); @@ -747,8 +856,35 @@ cmGlobalUnixMakefileGenerator3 // Write the rule. commands.clear(); + progressDir = lg->GetMakefile()->GetHomeOutputDirectory(); + progressDir += cmake::GetCMakeFilesDirectory(); + + { + // TODO: Convert the total progress count to a make variable. + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; + // # in target + progCmd << lg->Convert(progressDir.c_str(), + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + // + progCmd << " " + << this->GetTargetTotalNumberOfProgressFiles(t->second); + commands.push_back(progCmd.str()); + } + std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash(); + tmp += "Makefile2"; commands.push_back(lg->GetRecursiveMakeCall - ("CMakeFiles/Makefile2",localName.c_str())); + (tmp.c_str(),localName.c_str())); + { + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0 + progCmd << lg->Convert(progressDir.c_str(), + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + progCmd << " 0"; + commands.push_back(progCmd.str()); + } depends.clear(); depends.push_back("cmake_check_build_system"); localName = lg->GetRelativeTargetDirectory(t->second); @@ -773,7 +909,6 @@ cmGlobalUnixMakefileGenerator3 commands.clear(); commands.push_back(lg->GetRecursiveMakeCall (makefileName.c_str(), localName.c_str())); - this->AppendGlobalTargetDepends(depends,t->second); lg->WriteMakeRule(ruleFileStream, "Pre-install relink rule for target.", localName.c_str(), depends, commands, true); @@ -803,6 +938,101 @@ cmGlobalUnixMakefileGenerator3 } } +//---------------------------------------------------------------------------- +int cmGlobalUnixMakefileGenerator3 +::GetTargetTotalNumberOfProgressFiles(cmTarget& target) +{ + cmLocalUnixMakefileGenerator3 *lg = + static_cast<cmLocalUnixMakefileGenerator3 *> + (target.GetMakefile()->GetLocalGenerator()); + int result = static_cast<int>(lg->ProgressFiles[target.GetName()].size()); + std::vector<cmTarget *>& depends = this->GetTargetDepends(target); + + std::vector<cmTarget *>::iterator i; + for (i = depends.begin(); i != depends.end(); ++i) + { + result += this->GetTargetTotalNumberOfProgressFiles(**i); + } + + return result; +} + + +//---------------------------------------------------------------------------- +std::vector<cmTarget *>& cmGlobalUnixMakefileGenerator3 +::GetTargetDepends(cmTarget& target) +{ + // if the depends are already in the map then return + std::map<cmStdString, std::vector<cmTarget *> >::iterator tgtI = + this->TargetDependencies.find(target.GetName()); + if (tgtI != this->TargetDependencies.end()) + { + return tgtI->second; + } + + // A target should not depend on itself. + std::set<cmStdString> emitted; + emitted.insert(target.GetName()); + + // the vector of results + std::vector<cmTarget *>& result = + this->TargetDependencies[target.GetName()]; + + // Loop over all library dependencies but not for static libs + if (target.GetType() != cmTarget::STATIC_LIBRARY) + { + const cmTarget::LinkLibraryVectorType& tlibs = target.GetLinkLibraries(); + for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin(); + lib != tlibs.end(); ++lib) + { + // Don't emit the same library twice for this target. + if(emitted.insert(lib->first).second) + { + cmTarget *target2 = + target.GetMakefile()->FindTarget(lib->first.c_str()); + + // search each local generator until a match is found + if (!target2) + { + target2 = this->FindTarget(0,lib->first.c_str()); + } + + // if a match was found then ... + if (target2) + { + // Add this dependency. + result.push_back(target2); + } + } + } + } + + // Loop over all utility dependencies. + const std::set<cmStdString>& tutils = target.GetUtilities(); + for(std::set<cmStdString>::const_iterator util = tutils.begin(); + util != tutils.end(); ++util) + { + // Don't emit the same utility twice for this target. + if(emitted.insert(*util).second) + { + cmTarget *target2 = target.GetMakefile()->FindTarget(util->c_str()); + + // search each local generator until a match is found + if (!target2) + { + target2 = this->FindTarget(0,util->c_str()); + } + + // if a match was found then ... + if (target2) + { + // Add this dependency. + result.push_back(target2); + } + } + } + return result; +} //---------------------------------------------------------------------------- void diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 1b7733d5ee..47557b96bf 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -121,7 +121,16 @@ public: (const char* makeProgram, const char *projectName, const char* additionalOptions, const char *targetName, - const char* config, bool ignoreErrors); + const char* config, bool ignoreErrors, bool fast); + + // returns true if a progress rule should be added + int ShouldAddProgressRule(); + int GetNumberOfCompilableSourceFilesForTarget(cmTarget &tgt); + int GetTargetTotalNumberOfProgressFiles(cmTarget& target); + int GetNumberOfSourceFiles() { return this->NumberOfSourceFiles; }; + + // what targets does the specified target depend on + std::vector<cmTarget *>& GetTargetDepends(cmTarget& target); protected: void WriteMainMakefile2(); @@ -173,6 +182,12 @@ protected: typedef std::map<cmStdString, cmStdString> MultipleOutputPairsType; MultipleOutputPairsType MultipleOutputPairs; + + int NumberOfSourceFiles; + int NumberOfSourceFilesWritten; + + std::map<cmStdString, std::vector<cmTarget *> > TargetDependencies; + std::map<cmStdString, int > TargetSourceFileCount; }; #endif diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx index f076efbd0b..d2644d0622 100644 --- a/Source/cmGlobalVisualStudio6Generator.cxx +++ b/Source/cmGlobalVisualStudio6Generator.cxx @@ -73,7 +73,8 @@ std::string cmGlobalVisualStudio6Generator const char* additionalOptions, const char *targetName, const char* config, - bool ignoreErrors) + bool ignoreErrors, + bool) { // Ingoring errors is not implemented in visual studio 6 (void) ignoreErrors; diff --git a/Source/cmGlobalVisualStudio6Generator.h b/Source/cmGlobalVisualStudio6Generator.h index 07456a2b71..792e7b1955 100644 --- a/Source/cmGlobalVisualStudio6Generator.h +++ b/Source/cmGlobalVisualStudio6Generator.h @@ -60,7 +60,8 @@ public: const char* additionalOptions, const char *targetName, const char* config, - bool ignoreErrors); + bool ignoreErrors, + bool fast); /** * Generate the all required files for building this project/tree. This diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 791daeabd0..7bc0654c57 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -71,7 +71,7 @@ std::string cmGlobalVisualStudio7Generator ::GenerateBuildCommand(const char* makeProgram, const char *projectName, const char* additionalOptions, const char *targetName, - const char* config, bool ignoreErrors) + const char* config, bool ignoreErrors, bool) { // Ingoring errors is not implemented in visual studio 6 (void) ignoreErrors; diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index 5b14449abc..9ff97da953 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -60,7 +60,8 @@ public: const char* additionalOptions, const char *targetName, const char* config, - bool ignoreErrors); + bool ignoreErrors, + bool fast); /** * Generate the all required files for building this project/tree. This diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index d48723f07b..c7c50cd716 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -133,7 +133,8 @@ std::string cmGlobalXCodeGenerator const char* additionalOptions, const char *targetName, const char* config, - bool ignoreErrors) + bool ignoreErrors, + bool) { // Config is not used yet (void) ignoreErrors; @@ -365,7 +366,8 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(cmLocalGenerator* root) (this->CurrentReRunCMakeMakefile.c_str()); makefileStream.SetCopyIfDifferent(true); makefileStream << "# Generated by CMake, DO NOT EDIT\n"; - makefileStream << "CMakeFiles/cmake.check_cache: "; + makefileStream << cmake::GetCMakeFilesDirectoryPostSlash(); + makefileStream << "cmake.check_cache: "; for(std::vector<std::string>::const_iterator i = lfiles.begin(); i != lfiles.end(); ++i) { @@ -946,8 +948,9 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase, } else { - char c = '1' + count++; - tname[&cc] = std::string(target.GetName()) + c; + cmOStringStream str; + str << "_buildpart_" << count++ ; + tname[&cc] = std::string(target.GetName()) + str.str(); makefileStream << "\\\n\t" << tname[&cc]; } } diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 326bfd0fe8..991a223713 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -63,7 +63,8 @@ public: const char* additionalOptions, const char *targetName, const char* config, - bool ignoreErrors); + bool ignoreErrors, + bool fast); /** * Generate the all required files for building this project/tree. This diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index 4e7c77732b..5ee5d90c8b 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -22,23 +22,19 @@ bool cmIfFunctionBlocker:: IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) { - const char* name = lff.Name.c_str(); - const std::vector<cmListFileArgument>& args = lff.Arguments; // always let if statements through - if (cmSystemTools::LowerCase(lff.Name) == "if") + if (!cmSystemTools::Strucmp(lff.Name.c_str(),"if")) { return false; } // watch for our ELSE or ENDIF - if (cmSystemTools::LowerCase(lff.Name) == "else" || - cmSystemTools::LowerCase(lff.Name) == "endif") - { - if (args == this->Args) + if (!cmSystemTools::Strucmp(lff.Name.c_str(),"else") || + !cmSystemTools::Strucmp(lff.Name.c_str(),"endif")) { // if it was an else statement then we should change state // and block this Else Command - if (cmSystemTools::LowerCase(lff.Name) == "else") + if (!cmSystemTools::Strucmp(lff.Name.c_str(),"else")) { this->IsBlocking = !this->IsBlocking; return true; @@ -48,39 +44,22 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) mf.RemoveFunctionBlocker(lff); return true; } - else if(args.empty()) - { - std::string err = "Empty arguments for "; - err += name; - err += ". Did you mean "; - err += name; - err += "( "; - for(std::vector<cmListFileArgument>::const_iterator a = - this->Args.begin(); - a != this->Args.end();++a) - { - err += (a->Quoted?"\"":""); - err += a->Value; - err += (a->Quoted?"\"":""); - err += " "; - } - err += ")?"; - cmSystemTools::Error(err.c_str()); - } - } + return this->IsBlocking; } bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff, - cmMakefile&) + cmMakefile& mf) { - if (cmSystemTools::LowerCase(lff.Name) == "endif") + if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endif")) { - if (lff.Arguments == this->Args) + if (mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS") + || lff.Arguments == this->Args) { return true; } } + return false; } diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h index a8a7b813ae..e49c21fbc6 100644 --- a/Source/cmIfCommand.h +++ b/Source/cmIfCommand.h @@ -123,12 +123,14 @@ public: " IF(variable1 OR variable2)\n" "True if either variable would be considered true individually.\n" " IF(COMMAND command-name)\n" - "True if the given name is a file or directory.\n" + "True if the given name is a command that can be invoked.\n" " IF(EXISTS file-name)\n" " IF(EXISTS directory-name)\n" - "True if the given name is a directory.\n" + "True if the named file or directory exists. " + "Behavior is well-defined only for full paths.\n" " IF(IS_DIRECTORY directory-name)\n" - "True if the named file or directory exists.\n" + "True if the given name is a directory. " + "Behavior is well-defined only for full paths.\n" " IF(variable MATCHES regex)\n" " IF(string MATCHES regex)\n" "True if the given string or variable's value matches the given " diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index b7be4cbe73..860ecad74e 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -20,6 +20,7 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmTarget.h" +#include "cmake.h" //---------------------------------------------------------------------------- cmInstallTargetGenerator @@ -48,7 +49,8 @@ void cmInstallTargetGenerator::GenerateScript(std::ostream& os) if(this->Target->NeedRelinkBeforeInstall()) { fromDir = this->Target->GetMakefile()->GetStartOutputDirectory(); - fromDir += "/CMakeFiles/CMakeRelink.dir/"; + fromDir += cmake::GetCMakeFilesDirectory(); + fromDir += "/CMakeRelink.dir/"; } else { @@ -361,7 +363,7 @@ void cmInstallTargetGenerator { os << "\n -change \"" << i->first << "\" \"" << i->second << "\""; } - os << "\n \"" << destination << "/" + os << "\n \"$ENV{DESTDIR}" << destination << "/" << this->GetScriptReference(this->Target, "REMAPPED", true) << "\")\n"; os << "ENDIF(" << component_test << ")\n"; } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 802176503b..b9675f927a 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -52,7 +52,7 @@ void cmLocalGenerator::Configure() { // make sure the CMakeFiles dir is there std::string filesDir = this->Makefile->GetStartOutputDirectory(); - filesDir += "/CMakeFiles"; + filesDir += cmake::GetCMakeFilesDirectory(); cmSystemTools::MakeDirectory(filesDir.c_str()); // find & read the list file @@ -1418,6 +1418,9 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, outputRuntime && tgt.HaveInstallTreeRPATH() && linking_for_install; bool use_build_rpath = outputRuntime && tgt.HaveBuildTreeRPATH() && !linking_for_install; + bool use_link_rpath = + outputRuntime && linking_for_install && + tgt.GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH"); // Construct the RPATH. std::vector<std::string> runtimeDirs; @@ -1454,13 +1457,29 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, && libDir->find("${") == std::string::npos) { linkLibs += libPathFlag; + linkLibs += fullLibPath; + linkLibs += " "; + + // Put this directory in the rpath if using build-tree rpath + // support or if using the link path as an rpath. if(use_build_rpath) { - runtimeDirs.push_back( fullLibPath ); + runtimeDirs.push_back(fullLibPath); + } + else if(use_link_rpath) + { + // Do not add any path inside the source or build tree. + const char* topSourceDir = this->Makefile->GetHomeDirectory(); + const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory(); + if(!cmSystemTools::ComparePath(libDir->c_str(), topSourceDir) && + !cmSystemTools::ComparePath(libDir->c_str(), topBinaryDir) && + !cmSystemTools::IsSubDirectory(libDir->c_str(), topSourceDir) && + !cmSystemTools::IsSubDirectory(libDir->c_str(), topBinaryDir)) + { + runtimeDirs.push_back(fullLibPath); + } } } - linkLibs += fullLibPath; - linkLibs += " "; } } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index ccc9bef44e..6e4c60eab9 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -160,8 +160,7 @@ public: bool /* clear */) {}; /** Called from command-line hook to scan dependencies. */ - virtual bool ScanDependencies(std::vector<std::string> const& /* args */) - {return true;}; + virtual bool ScanDependencies(const char* /* tgtInfo */) { return true; } /** Compute the list of link libraries and directories for the given target and configuration. */ diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 95bf9aa6a1..8f7256729a 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -48,6 +48,7 @@ cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3() this->DefineWindowsNULL = false; this->UnixCD = true; this->ForceVerboseMakefiles=false; + this->ColorMakefile = false; } //---------------------------------------------------------------------------- @@ -75,6 +76,10 @@ void cmLocalUnixMakefileGenerator3::Generate() // Setup our configuration variables for this directory. this->ConfigureOutputPaths(); + // Record whether color makefiles are enabled to avoid checking many + // times later. + this->ColorMakefile = this->Makefile->IsOn("CMAKE_COLOR_MAKEFILE"); + // Generate the rule files for each target. cmTargets& targets = this->Makefile->GetTargets(); std::string empty; @@ -275,8 +280,10 @@ void cmLocalUnixMakefileGenerator3 depends.clear(); // Build the target for this pass. + std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash(); + tmp += "Makefile2"; commands.push_back(this->GetRecursiveMakeCall - ("CMakeFiles/Makefile2",localName.c_str())); + (tmp.c_str(),localName.c_str())); this->CreateCDCommand(commands, this->Makefile->GetHomeOutputDirectory(), this->Makefile->GetStartOutputDirectory()); @@ -291,6 +298,24 @@ void cmLocalUnixMakefileGenerator3 this->WriteMakeRule(ruleFileStream, "Convenience name for target.", t->second.GetName(), depends, commands, true); } + + // Add a fast rule to build the target + std::string makefileName = this->GetRelativeTargetDirectory(t->second); + makefileName += "/build.make"; + std::string makeTargetName = + this->GetRelativeTargetDirectory(t->second); + makeTargetName += "/build"; + localName = t->second.GetName(); + localName += "/fast"; + depends.clear(); + commands.clear(); + commands.push_back(this->GetRecursiveMakeCall + (makefileName.c_str(), makeTargetName.c_str())); + this->CreateCDCommand(commands, + this->Makefile->GetHomeOutputDirectory(), + this->Makefile->GetStartOutputDirectory()); + this->WriteMakeRule(ruleFileStream, "fast build rule for target.", + localName.c_str(), depends, commands, true); } } } @@ -299,7 +324,8 @@ void cmLocalUnixMakefileGenerator3 void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile() { std::string infoFileName = this->Makefile->GetStartOutputDirectory(); - infoFileName += "/CMakeFiles/CMakeDirectoryInformation.cmake"; + infoFileName += cmake::GetCMakeFilesDirectory(); + infoFileName += "/CMakeDirectoryInformation.cmake"; // Open the output file. cmGeneratedFileStream infoFileStream(infoFileName.c_str()); @@ -630,7 +656,8 @@ void cmLocalUnixMakefileGenerator3 // the --check-build-system flag. { // Build command to run CMake to check if anything needs regenerating. - std::string cmakefileName = "CMakeFiles/Makefile.cmake"; + std::string cmakefileName = cmake::GetCMakeFilesDirectoryPostSlash(); + cmakefileName += "Makefile.cmake"; std::string runRule = "$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)"; runRule += " --check-build-system "; @@ -761,9 +788,16 @@ cmLocalUnixMakefileGenerator3 ::AppendCustomCommand(std::vector<std::string>& commands, const cmCustomCommand& cc) { - std::vector<std::string> commands1; + // if the command specified a working directory use it. + const char* dir = this->Makefile->GetStartOutputDirectory(); + const char* workingDir = cc.GetWorkingDirectory(); + if(workingDir) + { + dir = workingDir; + } // Add each command line to the set of commands. + std::vector<std::string> commands1; for(cmCustomCommandLines::const_iterator cl = cc.GetCommandLines().begin(); cl != cc.GetCommandLines().end(); ++cl) { @@ -773,7 +807,12 @@ cmLocalUnixMakefileGenerator3 if (cmd.size()) { cmSystemTools::ReplaceString(cmd, "/./", "/"); + // Convert the command to a relative path only if the current + // working directory will be the start-output directory. + if(!workingDir) + { cmd = this->Convert(cmd.c_str(),START_OUTPUT); + } if(cmd.find("/") == cmd.npos && commandLine[0].find("/") != cmd.npos) { @@ -799,16 +838,11 @@ cmLocalUnixMakefileGenerator3 } } - // push back the custom commands - const char* dir = this->Makefile->GetStartOutputDirectory(); - // if the command specified a working directory use it. - if(cc.GetWorkingDirectory()) - { - dir = cc.GetWorkingDirectory(); - } + // Setup the proper working directory for the commands. this->CreateCDCommand(commands1, dir, this->Makefile->GetHomeOutputDirectory()); + // push back the custom commands commands.insert(commands.end(), commands1.begin(), commands1.end()); } @@ -860,8 +894,7 @@ cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands, // Choose the color for the text. std::string color_name; #ifdef CMAKE_BUILD_WITH_CMAKE - if(this->GlobalGenerator->GetToolSupportsColor() && - this->Makefile->IsOn("CMAKE_COLOR_MAKEFILE")) + if(this->GlobalGenerator->GetToolSupportsColor() && this->ColorMakefile) { // See cmake::ExecuteEchoColor in cmake.cxx for these options. // This color set is readable on both black and white backgrounds. @@ -1127,31 +1160,17 @@ cmLocalUnixMakefileGenerator3 } //---------------------------------------------------------------------------- -bool -cmLocalUnixMakefileGenerator3 -::ScanDependencies(std::vector<std::string> const& args) +bool cmLocalUnixMakefileGenerator3::ScanDependencies(const char* tgtInfo) { - // Format of arguments is: $(CMAKE_COMMAND), cmake_depends, - // GeneratorName, home_output_dir, start_output_dir, info file The - // caller has ensured that all required arguments exist. - // The info file for this target - std::string const& infoFile = args[5]; + std::string const& infoFile = tgtInfo; // Read the directory information file. - cmake cm; - cmGlobalGenerator gg; - gg.SetCMakeInstance(&cm); - std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator()); - lg->SetGlobalGenerator(&gg); - cmMakefile* mf = lg->GetMakefile(); - mf->SetHomeOutputDirectory(args[3].c_str()); - mf->SetStartOutputDirectory(args[4].c_str()); - lg->SetupPathConversions(); - + cmMakefile* mf = this->Makefile; bool haveDirectoryInfo = false; - std::string dirInfoFile = args[4]; - dirInfoFile += "/CMakeFiles/CMakeDirectoryInformation.cmake"; + std::string dirInfoFile = this->Makefile->GetStartOutputDirectory(); + dirInfoFile += cmake::GetCMakeFilesDirectory(); + dirInfoFile += "/CMakeDirectoryInformation.cmake"; if(mf->ReadListFile(0, dirInfoFile.c_str()) && !cmSystemTools::GetErrorOccuredFlag()) { @@ -1283,7 +1302,7 @@ cmLocalUnixMakefileGenerator3 includeRegexScan.c_str(), includeRegexComplain.c_str(), generatedFiles, includeCacheFileName); - scanner->SetHomeOutputDirectory(mf->GetHomeOutputDirectory()); + scanner->SetLocalGenerator(this); } #ifdef CMAKE_BUILD_WITH_CMAKE else if(lang == "Fortran") @@ -1313,7 +1332,7 @@ cmLocalUnixMakefileGenerator3 ++si; // make sure the object file is relative to home output std::string obj = *si; - obj = lg->Convert(obj.c_str(),HOME_OUTPUT,MAKEFILE); + obj = this->Convert(obj.c_str(),HOME_OUTPUT,MAKEFILE); scanner->Write(src.c_str(),obj.c_str(), ruleFileStream, internalRuleFileStream); } @@ -1381,7 +1400,7 @@ void cmLocalUnixMakefileGenerator3 this->AppendEcho(commands, text, cmLocalUnixMakefileGenerator3::EchoGlobal); - // Utility targets store their rules in pre- and post-build commands. + // Global targets store their rules in pre- and post-build commands. this->AppendCustomDepends(depends, glIt->second.GetPreBuildCommands()); this->AppendCustomDepends(depends, @@ -1390,8 +1409,27 @@ void cmLocalUnixMakefileGenerator3 glIt->second.GetPreBuildCommands()); this->AppendCustomCommands(commands, glIt->second.GetPostBuildCommands()); + std::string targetName = glIt->second.GetName(); this->WriteMakeRule(ruleFileStream, targetString.c_str(), - glIt->first.c_str(), depends, commands, true); + targetName.c_str(), depends, commands, true); + + // Provide a "/fast" version of the target. + depends.clear(); + if(targetName == "install") + { + // Provide a fast install target that does not depend on all + // but has the same command. + depends.push_back("preinstall/fast"); + } + else + { + // Just forward to the real target so at least it will work. + depends.push_back(targetName); + commands.clear(); + } + targetName += "/fast"; + this->WriteMakeRule(ruleFileStream, targetString.c_str(), + targetName.c_str(), depends, commands, true); } } @@ -1408,11 +1446,45 @@ void cmLocalUnixMakefileGenerator3 depends.push_back("cmake_check_build_system"); - commands.push_back - (this->GetRecursiveMakeCall("CMakeFiles/Makefile2",dir.c_str())); + std::string progressDir = this->Makefile->GetHomeOutputDirectory(); + progressDir += cmake::GetCMakeFilesDirectory(); + { + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # src files + progCmd << this->Convert(progressDir.c_str(), + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + cmGlobalUnixMakefileGenerator3 *gg = + static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator); + int n = gg->GetNumberOfSourceFiles(); + if(n > 100) + { + n = 100; + } + if (this->Parent) + { + n = 0; + } + progCmd << " " << n; + commands.push_back(progCmd.str()); + } + std::string mf2Dir = cmake::GetCMakeFilesDirectoryPostSlash(); + mf2Dir += "Makefile2"; + commands.push_back(this->GetRecursiveMakeCall(mf2Dir.c_str(), + dir.c_str())); this->CreateCDCommand(commands, this->Makefile->GetHomeOutputDirectory(), this->Makefile->GetStartOutputDirectory()); + if (!this->Parent) + { + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0 + progCmd << this->Convert(progressDir.c_str(), + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + progCmd << " 0"; + commands.push_back(progCmd.str()); + } this->WriteMakeRule(ruleFileStream, "The main all target", "all", depends, commands, true); @@ -1422,8 +1494,8 @@ void cmLocalUnixMakefileGenerator3 dir = this->Convert(dir.c_str(),HOME_OUTPUT,MAKEFILE); commands.clear(); depends.clear(); - commands.push_back - (this->GetRecursiveMakeCall("CMakeFiles/Makefile2",dir.c_str())); + commands.push_back(this->GetRecursiveMakeCall(mf2Dir.c_str(), + dir.c_str())); this->CreateCDCommand(commands, this->Makefile->GetHomeOutputDirectory(), this->Makefile->GetStartOutputDirectory()); @@ -1454,21 +1526,21 @@ void cmLocalUnixMakefileGenerator3 depends.push_back("cmake_check_build_system"); } commands.push_back - (this->GetRecursiveMakeCall("CMakeFiles/Makefile2", dir.c_str())); + (this->GetRecursiveMakeCall(mf2Dir.c_str(), dir.c_str())); this->CreateCDCommand(commands, this->Makefile->GetHomeOutputDirectory(), this->Makefile->GetStartOutputDirectory()); this->WriteMakeRule(ruleFileStream, "Prepare targets for installation.", "preinstall", depends, commands, true); - commands.clear(); - depends.push_back("preinstall"); + depends.clear(); this->WriteMakeRule(ruleFileStream, "Prepare targets for installation.", "preinstall/fast", depends, commands, true); // write the depend rule, really a recompute depends rule depends.clear(); commands.clear(); - std::string cmakefileName = "CMakeFiles/Makefile.cmake"; + std::string cmakefileName = cmake::GetCMakeFilesDirectoryPostSlash(); + cmakefileName += "Makefile.cmake"; this->Convert(cmakefileName.c_str(),HOME_OUTPUT, cmLocalGenerator::MAKEFILE); std::string runRule = @@ -1816,7 +1888,7 @@ cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p) std::string cmLocalUnixMakefileGenerator3::GetTargetDirectory(cmTarget& target) { - std::string dir = "CMakeFiles/"; + std::string dir = cmake::GetCMakeFilesDirectoryPostSlash(); dir += target.GetName(); dir += ".dir"; return dir; diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index c96ca0056c..bb72d13103 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -178,7 +178,7 @@ public: /** Called from command-line hook to scan dependencies. */ - virtual bool ScanDependencies(std::vector<std::string> const& args); + virtual bool ScanDependencies(const char* tgtInfo); /** Called from command-line hook to check dependencies. */ virtual void CheckDependencies(cmMakefile* mf, bool verbose, @@ -280,11 +280,14 @@ protected: cmTarget& target, const char* filename =0); bool ForceVerboseMakefiles; + std::map<cmStdString, std::vector<int> > ProgressFiles; + private: friend class cmMakefileTargetGenerator; friend class cmMakefileExecutableTargetGenerator; friend class cmMakefileLibraryTargetGenerator; friend class cmMakefileUtilityTargetGenerator; + friend class cmGlobalUnixMakefileGenerator3; std::map<cmStdString, IntegrityCheckSetMap> CheckDependFiles; @@ -306,6 +309,10 @@ private: std::string HomeRelativeOutputPath; + /* Copy the setting of CMAKE_COLOR_MAKEFILE from the makefile at the + beginning of generation to avoid many duplicate lookups. */ + bool ColorMakefile; + std::map<cmStdString,std::vector<cmTarget *> > LocalObjectFiles; /* does the work for each target */ diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 290adadc93..a5eb3cd734 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -22,6 +22,8 @@ #include "cmCacheManager.h" #include "cmake.h" +#include <ctype.h> // for isspace + cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator() { this->Version = 7; @@ -687,7 +689,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n"; } fout << "\t\t\t\tOutputFile=\"" - << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << ".\"/>\n"; + << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n"; break; } case cmTarget::SHARED_LIBRARY: @@ -958,6 +960,12 @@ void cmLocalVisualStudio7Generator::OutputDefineFlags(const char* flags, done = true; } + // Remove trailing whitespace from the definition. + while(!define.empty() && isspace(define[define.size()-1])) + { + define = define.substr(0, define.size()-1); + } + // Double-quotes in the value of the definition must be escaped // with a backslash. The entire definition should be quoted in // the generated xml attribute to avoid confusing the VS parser. @@ -1159,8 +1167,26 @@ void cmLocalVisualStudio7Generator << "\t\t\t\t\tName=\"" << aCompilerTool << "\"\n"; if(compileFlags.size()) { + std::string compileFlagsCopy = compileFlags; + std::map<cmStdString, cmStdString> fileFlagMap; + this->FillFlagMapFromCommandFlags + (fileFlagMap, + &cmLocalVisualStudio7GeneratorFlagTable[0], + compileFlagsCopy); + if(compileFlagsCopy.size() && + compileFlagsCopy.find_first_not_of(" ") + != compileFlagsCopy.npos) + { fout << "\t\t\t\t\tAdditionalOptions=\"" - << this->EscapeForXML(compileFlags.c_str()) << "\"\n"; + << this->EscapeForXML(compileFlagsCopy.c_str()) << "\"\n"; + } + for(std::map<cmStdString, + cmStdString>::iterator m = fileFlagMap.begin(); + m != fileFlagMap.end(); ++m) + { + fout << "\t\t\t\t\t" << m->first << "=\"" + << m->second << "\"\n"; + } } if(additionalDeps.length()) { diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index c8565a9619..e4de342be1 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -252,11 +252,14 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) { // record commands until we hit the ENDMACRO // at the ENDMACRO call we shift gears and start looking for invocations - if(cmSystemTools::LowerCase(lff.Name) == "endmacro") + if(!cmSystemTools::Strucmp(lff.Name.c_str(),"macro")) { - std::vector<std::string> expandedArguments; - mf.ExpandArguments(lff.Arguments, expandedArguments); - if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0])) + this->Depth++; + } + else if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endmacro")) + { + // if this is the endmacro for this macro then execute + if (!this->Depth) { std::string name = this->Args[0]; std::vector<std::string>::size_type cc; @@ -280,6 +283,11 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) mf.RemoveFunctionBlocker(lff); return true; } + else + { + // decrement for each nested macro that ends + this->Depth--; + } } // if it wasn't an endmacro and we are not executing then we must be @@ -292,15 +300,18 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) bool cmMacroFunctionBlocker:: ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf) { - if(cmSystemTools::LowerCase(lff.Name) == "endmacro") + if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endmacro")) { std::vector<std::string> expandedArguments; mf.ExpandArguments(lff.Arguments, expandedArguments); - if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0])) + if ((!expandedArguments.empty() && + (expandedArguments[0] == this->Args[0])) + || mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS")) { return true; } } + return false; } diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h index 99e8b91b8a..d93bdd86b1 100644 --- a/Source/cmMacroCommand.h +++ b/Source/cmMacroCommand.h @@ -28,7 +28,7 @@ class cmMacroFunctionBlocker : public cmFunctionBlocker { public: - cmMacroFunctionBlocker() {} + cmMacroFunctionBlocker() {this->Depth=0;} virtual ~cmMacroFunctionBlocker() {} virtual bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile &mf); virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile &mf); @@ -36,6 +36,7 @@ public: std::vector<std::string> Args; std::vector<cmListFileFunction> Functions; + int Depth; }; /** \class cmMacroCommand diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 866911dc73..d4cc69da6c 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -36,6 +36,8 @@ #include <cmsys/RegularExpression.hxx> +#include <ctype.h> // for isspace + // default is not to be building executables cmMakefile::cmMakefile() { @@ -265,7 +267,8 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff) cmOStringStream error; error << "Error in cmake code at\n" << lff.FilePath << ":" << lff.Line << ":\n" - << rm->GetError(); + << rm->GetError() << std::endl + << "Current CMake stack: " << this->GetListFileStack().c_str(); cmSystemTools::Error(error.str().c_str()); return false; } @@ -281,7 +284,8 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff) cmOStringStream error; error << "Error in cmake code at\n" << lff.FilePath << ":" << lff.Line << ":\n" - << usedCommand->GetError(); + << usedCommand->GetError() << std::endl + << "Current CMake stack: " << this->GetListFileStack().c_str(); cmSystemTools::Error(error.str().c_str()); result = false; if ( this->GetCMakeInstance()->GetScriptMode() ) @@ -325,6 +329,7 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff) << "Unknown CMake command \"" << lff.Name.c_str() << "\"."; cmSystemTools::Error(error.str().c_str()); result = false; + cmSystemTools::SetFatalErrorOccured(); } } @@ -803,7 +808,29 @@ void cmMakefile::AddDefineFlag(const char* flag) void cmMakefile::RemoveDefineFlag(const char* flag) { - cmSystemTools::ReplaceString(this->DefineFlags, flag, " "); + // Check the length of the flag to remove. + std::string::size_type len = strlen(flag); + if(len < 1) + { + return; + } + + // Remove all instances of the flag that are surrounded by + // whitespace or the beginning/end of the string. + for(std::string::size_type lpos = this->DefineFlags.find(flag, 0); + lpos != std::string::npos; lpos = this->DefineFlags.find(flag, lpos)) + { + std::string::size_type rpos = lpos + len; + if((lpos <= 0 || isspace(this->DefineFlags[lpos-1])) && + (rpos >= this->DefineFlags.size() || isspace(this->DefineFlags[rpos]))) + { + this->DefineFlags.erase(lpos, len); + } + else + { + ++lpos; + } + } } void cmMakefile::AddLinkLibrary(const char* lib, @@ -824,18 +851,39 @@ void cmMakefile::AddLinkLibraryForTarget(const char *target, this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0, lib); if(tgt) { + bool allowModules = true; + const char* versionValue + = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY"); + if (versionValue && (atof(versionValue) >= 2.4) ) + { + allowModules = false; + } // 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))) { cmOStringStream e; - e << "Attempt to add link library " << lib - << " which is not a library target to target " - << tgt->GetType() << " " << - target << "\n"; + e << "Attempt to add link target " << lib << " of type: " + << cmTarget::TargetTypeNames[(int)tgt->GetType()] + << "\nto target " << target + << ". You can only link to STATIC or SHARED libraries."; + // 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"; + } + // if no modules are allowed then this is always an error + if(!allowModules || + // if we allow modules but the type is not a module then it is + // still an error + (allowModules && tgt->GetType() != cmTarget::MODULE_LIBRARY)) + { cmSystemTools::Error(e.str().c_str()); } } + } i->second.AddLinkLibrary( *this, target, lib, llt ); } else @@ -1667,8 +1715,16 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source, { markerPos += markerStartSize; // move past marker // find the end variable marker starting at the markerPos + // make sure it is a valid variable between std::string::size_type endVariablePos = - source.find(endVariableMarker, markerPos); + source.find_first_not_of( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", + markerPos); + if(endVariablePos != std::string::npos && + source[endVariablePos] != endVariableMarker) + { + endVariablePos = std::string::npos; + } if(endVariablePos == std::string::npos) { // no end marker found so add the bogus start @@ -1815,6 +1871,11 @@ void cmMakefile::AddDefaultDefinitions() this->AddDefinition("CMAKE_MINOR_VERSION", temp); sprintf(temp, "%d", cmMakefile::GetMajorVersion()); this->AddDefinition("CMAKE_MAJOR_VERSION", temp); + sprintf(temp, "%d", cmMakefile::GetPatchVersion()); + this->AddDefinition("CMAKE_PATCH_VERSION", temp); + + this->AddDefinition("CMAKE_FILES_DIRECTORY", + cmake::GetCMakeFilesDirectory()); } #if defined(CMAKE_BUILD_WITH_CMAKE) @@ -2001,10 +2062,21 @@ cmSourceFile* cmMakefile::GetSource(const char* sourceName) const { // if the source is provided with a full path use it, otherwise // by default it is in the current source dir - std::string path = cmSystemTools::GetFilenamePath(sourceName); - if (path.empty()) + std::string path; + if (cmSystemTools::FileIsFullPath(sourceName)) + { + path = cmSystemTools::GetFilenamePath(sourceName); + } + else { path = this->GetCurrentDirectory(); + // even though it is not a full path, it may still be relative + std::string subpath = cmSystemTools::GetFilenamePath(sourceName); + if (!subpath.empty()) + { + path += "/"; + path += cmSystemTools::GetFilenamePath(sourceName); + } } std::string sname = @@ -2684,3 +2756,17 @@ std::vector<cmTest*> *cmMakefile::GetTests() return &this->Tests; } +std::string cmMakefile::GetListFileStack() +{ + std::string tmp; + for (std::deque<cmStdString>::iterator i = this->ListFileStack.begin(); + i != this->ListFileStack.end(); ++i) + { + if (i != this->ListFileStack.begin()) + { + tmp += ";"; + } + tmp += *i; + } + return tmp; +} diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 172ab7ae21..7751a03d72 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -539,6 +539,11 @@ public: void AddCMakeDependFile(const char* file) { this->ListFiles.push_back(file);} + /** + * Get the list file stack as a string + */ + std::string GetListFileStack(); + /** * Get the vector of files created by this makefile */ diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index c999106ebc..03b0cd23ab 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -22,6 +22,7 @@ #include "cmMakefile.h" #include "cmSourceFile.h" #include "cmTarget.h" +#include "cmake.h" //---------------------------------------------------------------------------- void cmMakefileExecutableTargetGenerator::WriteRuleFiles() @@ -29,12 +30,15 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles() // create the build.make file and directory, put in the common blocks this->CreateRuleFile(); - // Add in any rules for custom commands - this->WriteCustomCommandsForTarget(); - - // write in rules for object files + // write rules used to help build object files this->WriteCommonCodeRules(); + // write in rules for object files and custom commands + this->WriteTargetBuildRules(); + + // write the per-target per-language flags + this->WriteTargetLanguageFlags(); + // Write the dependency generation rule. this->WriteTargetDependRules(); @@ -165,7 +169,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) if(relink) { outpath = this->Makefile->GetStartOutputDirectory(); - outpath += "/CMakeFiles/CMakeRelink.dir"; + outpath += cmake::GetCMakeFilesDirectory(); + outpath += "/CMakeRelink.dir"; cmSystemTools::MakeDirectory(outpath.c_str()); outpath += "/"; } @@ -311,7 +316,6 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) symlink += targetOutPathReal; symlink += " "; symlink += targetOutPath; - commands.push_back(symlink); commands1.clear(); commands1.push_back(symlink); this->LocalGenerator->CreateCDCommand(commands1, @@ -380,19 +384,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) depends, commands, false); } - // Write convenience targets. - std::string dir = this->Makefile->GetStartOutputDirectory(); - dir += "/"; - dir += this->LocalGenerator->GetTargetDirectory(*this->Target); - std::string buildTargetRuleName = dir; - buildTargetRuleName += relink?"/preinstall":"/build"; - buildTargetRuleName = - this->Convert(buildTargetRuleName.c_str(), - cmLocalGenerator::HOME_OUTPUT, - cmLocalGenerator::MAKEFILE); - this->LocalGenerator->WriteConvenienceRule(*this->BuildFileStream, - targetFullPath.c_str(), - buildTargetRuleName.c_str()); + // Write the main driver rule to build everything in this target. + this->WriteTargetDriverRule(targetFullPath.c_str(), relink); // Clean all the possible executable names and symlinks and object files. this->CleanFiles.insert(this->CleanFiles.end(), diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 330465f08e..2c1675584c 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -22,6 +22,9 @@ #include "cmMakefile.h" #include "cmSourceFile.h" #include "cmTarget.h" +#include "cmake.h" + +#include <memory> // auto_ptr //---------------------------------------------------------------------------- void cmMakefileLibraryTargetGenerator::WriteRuleFiles() @@ -29,12 +32,15 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles() // create the build.make file and directory, put in the common blocks this->CreateRuleFile(); - // Add in any rules for custom commands - this->WriteCustomCommandsForTarget(); - - // write in rules for object files + // write rules used to help build object files this->WriteCommonCodeRules(); + // write in rules for object files and custom commands + this->WriteTargetBuildRules(); + + // write the per-target per-language flags + this->WriteTargetLanguageFlags(); + // Write the dependency generation rule. this->WriteTargetDependRules(); @@ -241,7 +247,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules if(relink) { outpath = this->Makefile->GetStartOutputDirectory(); - outpath += "/CMakeFiles/CMakeRelink.dir"; + outpath += cmake::GetCMakeFilesDirectory(); + outpath += "/CMakeRelink.dir"; cmSystemTools::MakeDirectory(outpath.c_str()); outpath += "/"; } @@ -371,9 +378,48 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules ->AppendCustomCommands(commands, this->Target->GetPreLinkCommands()); } + // Open the link script if it will be used. + bool useLinkScript = false; + std::string linkScriptName; + std::auto_ptr<cmGeneratedFileStream> linkScriptStream; + if(this->GlobalGenerator->GetUseLinkScript() && + (this->Target->GetType() == cmTarget::STATIC_LIBRARY || + this->Target->GetType() == cmTarget::SHARED_LIBRARY || + this->Target->GetType() == cmTarget::MODULE_LIBRARY)) + { + useLinkScript = true; + linkScriptName = this->TargetBuildDirectoryFull; + if(relink) + { + linkScriptName += "/relink.txt"; + } + else + { + linkScriptName += "/link.txt"; + } + std::auto_ptr<cmGeneratedFileStream> lss( + new cmGeneratedFileStream(linkScriptName.c_str())); + linkScriptStream = lss; + } + + std::vector<std::string> link_script_commands; + // Construct the main link rule. std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar); + if(useLinkScript) + { + cmSystemTools::ExpandListArgument(linkRule, link_script_commands); + std::string link_command = "$(CMAKE_COMMAND) -E cmake_link_script "; + link_command += this->Convert(linkScriptName.c_str(), + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::SHELL); + link_command += " --verbose=$(VERBOSE)"; + commands1.push_back(link_command); + } + else + { cmSystemTools::ExpandListArgument(linkRule, commands1); + } this->LocalGenerator->CreateCDCommand (commands1, this->Makefile->GetStartOutputDirectory(), @@ -413,11 +459,19 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules std::string variableName; std::string variableNameExternal; this->WriteObjectsVariable(variableName, variableNameExternal); - std::string buildObjs = "$("; + std::string buildObjs; + if(useLinkScript) + { + this->WriteObjectsString(buildObjs); + } + else + { + buildObjs = "$("; buildObjs += variableName; buildObjs += ") $("; buildObjs += variableNameExternal; buildObjs += ")"; + } std::string cleanObjs = "$("; cleanObjs += variableName; cleanObjs += ")"; @@ -425,7 +479,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules vars.TargetPDB = targetOutPathPDB.c_str(); vars.Language = linkLanguage; vars.Objects = buildObjs.c_str(); - std::string objdir = "CMakeFiles/"; + std::string objdir = cmake::GetCMakeFilesDirectoryPostSlash(); objdir += this->Target->GetName(); objdir += ".dir"; vars.ObjectDir = objdir.c_str(); @@ -488,13 +542,40 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules vars.LanguageCompileFlags = langFlags.c_str(); // Expand placeholders in the commands. this->LocalGenerator->TargetImplib = targetOutPathImport; + if(useLinkScript) + { + for(std::vector<std::string>::iterator i = link_script_commands.begin(); + i != link_script_commands.end(); ++i) + { + this->LocalGenerator->ExpandRuleVariables(*i, vars); + } + } + else + { for(std::vector<std::string>::iterator i = commands.begin(); i != commands.end(); ++i) { this->LocalGenerator->ExpandRuleVariables(*i, vars); } + } this->LocalGenerator->TargetImplib = ""; + // Optionally convert the build rule to use a script to avoid long + // command lines in the make shell. + if(useLinkScript) + { + for(std::vector<std::string>::iterator cmd = link_script_commands.begin(); + cmd != link_script_commands.end(); ++cmd) + { + // Do not write out empty commands or commands beginning in the + // shell no-op ":". + if(!cmd->empty() && (*cmd)[0] != ':') + { + (*linkScriptStream) << *cmd << "\n"; + } + } + } + // Write the build rule. this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0, targetFullPathReal.c_str(), @@ -522,18 +603,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules depends, commands, false); } - // Write convenience targets. - std::string dir = this->Makefile->GetStartOutputDirectory(); - dir += "/"; - dir += this->LocalGenerator->GetTargetDirectory(*this->Target); - std::string buildTargetRuleName = dir; - buildTargetRuleName += relink?"/preinstall":"/build"; - buildTargetRuleName = - this->Convert(buildTargetRuleName.c_str(), - cmLocalGenerator::HOME_OUTPUT,cmLocalGenerator::MAKEFILE); - this->LocalGenerator->WriteConvenienceRule(*this->BuildFileStream, - targetFullPath.c_str(), - buildTargetRuleName.c_str()); + // Write the main driver rule to build everything in this target. + this->WriteTargetDriverRule(targetFullPath.c_str(), relink); // Clean all the possible library names and symlinks and object files. this->CleanFiles.insert(this->CleanFiles.end(), diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index f3434d0424..a4f03c8c9e 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -23,6 +23,7 @@ #include "cmMakefile.h" #include "cmSourceFile.h" #include "cmTarget.h" +#include "cmake.h" #include "cmMakefileExecutableTargetGenerator.h" #include "cmMakefileLibraryTargetGenerator.h" @@ -99,7 +100,7 @@ void cmMakefileTargetGenerator::CreateRuleFile() } //---------------------------------------------------------------------------- -void cmMakefileTargetGenerator::WriteCustomCommandsForTarget() +void cmMakefileTargetGenerator::WriteTargetBuildRules() { // write the custom commands for this target // Look for files registered for cleaning in this directory. @@ -110,7 +111,56 @@ void cmMakefileTargetGenerator::WriteCustomCommandsForTarget() cmSystemTools::ExpandListArgument(additional_clean_files, this->CleanFiles); } - this->WriteCustomCommands(); + + // add custom commands to the clean rules? + const char* clean_no_custom = + this->Makefile->GetProperty("CLEAN_NO_CUSTOM"); + bool clean = cmSystemTools::IsOff(clean_no_custom); + + // First generate the object rule files. Save a list of all object + // files for this target. + const std::vector<cmSourceFile*>& sources = this->Target->GetSourceFiles(); + for(std::vector<cmSourceFile*>::const_iterator source = sources.begin(); + source != sources.end(); ++source) + { + if(cmCustomCommand* cc = (*source)->GetCustomCommand()) + { + this->GenerateCustomRuleFile(*cc); + if (clean) + { + const std::vector<std::string>& outputs = cc->GetOutputs(); + for(std::vector<std::string>::const_iterator o = outputs.begin(); + o != outputs.end(); ++o) + { + this->CleanFiles.push_back + (this->Convert(o->c_str(), + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::UNCHANGED)); + } + } + } + else if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY")) + { + if(!this->GlobalGenerator->IgnoreFile + ((*source)->GetSourceExtension().c_str())) + { + // Generate this object file's rule file. + this->WriteObjectRuleFiles(*(*source)); + } + else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT")) + { + // This is an external object file. Just add it. + this->ExternalObjects.push_back((*source)->GetFullPath()); + } + else + { + // We only get here if a source file is not an external object + // and has an extension that is listed as an ignored file type + // for this language. No message or diagnosis should be + // given. + } + } + } } @@ -159,37 +209,11 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() cmLocalGenerator::HOME_OUTPUT, cmLocalGenerator::MAKEFILE) << "\n\n"; +} - // First generate the object rule files. Save a list of all object - // files for this target. - const std::vector<cmSourceFile*>& sources = this->Target->GetSourceFiles(); - for(std::vector<cmSourceFile*>::const_iterator source = sources.begin(); - source != sources.end(); ++source) - { - if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY") && - !(*source)->GetCustomCommand()) - { - if(!this->GlobalGenerator->IgnoreFile - ((*source)->GetSourceExtension().c_str())) - { - // Generate this object file's rule file. - this->WriteObjectRuleFiles(*(*source)); - } - else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT")) - { - // This is an external object file. Just add it. - this->ExternalObjects.push_back((*source)->GetFullPath()); - } - else - { - // We only get here if a source file is not an external object - // and has an extension that is listed as an ignored file type - // for this language. No message or diagnosis should be - // given. - } - } - } - +//---------------------------------------------------------------------------- +void cmMakefileTargetGenerator::WriteTargetLanguageFlags() +{ // write language flags for target std::map<cmStdString,cmLocalUnixMakefileGenerator3::IntegrityCheckSet>& checkSet = @@ -374,6 +398,27 @@ cmMakefileTargetGenerator // Construct the build message. std::vector<std::string> no_commands; std::vector<std::string> commands; + + // add in a progress call if needed + cmGlobalUnixMakefileGenerator3* gg = + static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator); + int prog = gg->ShouldAddProgressRule(); + + std::string progressDir = this->Makefile->GetHomeOutputDirectory(); + progressDir += cmake::GetCMakeFilesDirectory(); + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; + progCmd << this->LocalGenerator->Convert(progressDir.c_str(), + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + if (prog) + { + progCmd << " " << prog; + this->LocalGenerator->ProgressFiles[this->Target->GetName()]. + push_back(prog); + } + commands.push_back(progCmd.str()); + std::string buildEcho = "Building "; buildEcho += lang; buildEcho += " object "; @@ -581,20 +626,31 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() cmLocalGenerator::FULL, cmLocalGenerator::SHELL)) << " && "; #endif - depCmd << "$(CMAKE_COMMAND) -E cmake_depends " - << " \"" + // Generate a call this signature: + // + // cmake -E cmake_depends <generator> + // <home-src-dir> <start-src-dir> + // <home-out-dir> <start-out-dir> + // <dep-info> + // + // This gives the dependency scanner enough information to recreate + // the state of our local generator sufficiently for its needs. + depCmd << "$(CMAKE_COMMAND) -E cmake_depends \"" << this->GlobalGenerator->GetName() << "\" " - << this->LocalGenerator->Convert - (this->Makefile->GetHomeOutputDirectory(), - cmLocalGenerator::FULL,cmLocalGenerator::SHELL) + << this->Convert(this->Makefile->GetHomeDirectory(), + cmLocalGenerator::FULL, cmLocalGenerator::SHELL) << " " - << this->LocalGenerator->Convert - (this->Makefile->GetStartOutputDirectory(), - cmLocalGenerator::FULL,cmLocalGenerator::SHELL) + << this->Convert(this->Makefile->GetStartDirectory(), + cmLocalGenerator::FULL, cmLocalGenerator::SHELL) + << " " + << this->Convert(this->Makefile->GetHomeOutputDirectory(), + cmLocalGenerator::FULL, cmLocalGenerator::SHELL) + << " " + << this->Convert(this->Makefile->GetStartOutputDirectory(), + cmLocalGenerator::FULL, cmLocalGenerator::SHELL) << " " << this->Convert(this->InfoFileNameFull.c_str(), - cmLocalGenerator::FULL, - cmLocalGenerator::SHELL); + cmLocalGenerator::FULL, cmLocalGenerator::SHELL); commands.push_back(depCmd.str()); // Write the rule. @@ -624,39 +680,6 @@ void cmMakefileTargetGenerator } //---------------------------------------------------------------------------- -void cmMakefileTargetGenerator::WriteCustomCommands() -{ - // add custom commands to the clean rules? - const char* clean_no_custom = - this->Makefile->GetProperty("CLEAN_NO_CUSTOM"); - bool clean = cmSystemTools::IsOff(clean_no_custom); - - // Generate the rule files for each custom command. - const std::vector<cmSourceFile*> &classes = - this->Makefile->GetSourceFiles(); - for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); - i != classes.end(); i++) - { - if(cmCustomCommand* cc = (*i)->GetCustomCommand()) - { - this->GenerateCustomRuleFile(*cc); - if (clean) - { - const std::vector<std::string>& outputs = cc->GetOutputs(); - for(std::vector<std::string>::const_iterator o = outputs.begin(); - o != outputs.end(); ++o) - { - this->CleanFiles.push_back - (this->Convert(o->c_str(), - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::UNCHANGED)); - } - } - } - } -} - -//---------------------------------------------------------------------------- void cmMakefileTargetGenerator ::GenerateCustomRuleFile(const cmCustomCommand& cc) { @@ -785,6 +808,112 @@ cmMakefileTargetGenerator *this->BuildFileStream << "\n" << "\n"; } +//---------------------------------------------------------------------------- +void +cmMakefileTargetGenerator +::WriteObjectsString(std::string& buildObjs) +{ + std::string object; + const char* no_quoted = + this->Makefile->GetDefinition("CMAKE_NO_QUOTED_OBJECTS"); + const char* space = ""; + for(std::vector<std::string>::const_iterator i = this->Objects.begin(); + i != this->Objects.end(); ++i) + { + if ( this->ExtraContent.find(i->c_str()) != this->ExtraContent.end() ) + { + continue; + } + buildObjs += space; + space = " "; + if(no_quoted) + { + buildObjs += + this->Convert(i->c_str(), cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::SHELL); + } + else + { + buildObjs += + this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str()); + } + } + for(std::vector<std::string>::const_iterator i = + this->ExternalObjects.begin(); + i != this->ExternalObjects.end(); ++i) + { + buildObjs += space; + space = " "; + if(no_quoted) + { + buildObjs += + this->Convert(i->c_str(), cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::SHELL); + } + else + { + buildObjs += + this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str()); + } + } +} + +//---------------------------------------------------------------------------- +void cmMakefileTargetGenerator::WriteTargetDriverRule(const char* main_output, + bool relink) +{ + // Compute the name of the driver target. + std::string dir = this->Makefile->GetStartOutputDirectory(); + dir += "/"; + dir += this->LocalGenerator->GetTargetDirectory(*this->Target); + std::string buildTargetRuleName = dir; + buildTargetRuleName += relink?"/preinstall":"/build"; + buildTargetRuleName = this->Convert(buildTargetRuleName.c_str(), + cmLocalGenerator::HOME_OUTPUT, + cmLocalGenerator::MAKEFILE); + + // Build the list of target outputs to drive. + std::vector<std::string> depends; + if(main_output) + { + depends.push_back(main_output); + } + + const char* comment = 0; + if(relink) + { + // Setup the comment for the preinstall driver. + comment = "Rule to relink during preinstall."; + } + else + { + // Setup the comment for the main build driver. + comment = "Rule to build all files generated by this target."; + + // Make sure all custom command outputs in this target are built. + const std::vector<cmSourceFile*>& sources = + this->Target->GetSourceFiles(); + for(std::vector<cmSourceFile*>::const_iterator source = sources.begin(); + source != sources.end(); ++source) + { + if(cmCustomCommand* cc = (*source)->GetCustomCommand()) + { + const std::vector<std::string>& outputs = cc->GetOutputs(); + for(std::vector<std::string>::const_iterator o = outputs.begin(); + o != outputs.end(); ++o) + { + depends.push_back(*o); + } + } + } + } + + // Write the driver rule. + std::vector<std::string> no_commands; + this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, comment, + buildTargetRuleName.c_str(), + depends, no_commands, true); +} //---------------------------------------------------------------------------- std::string cmMakefileTargetGenerator::GetFrameworkFlags() diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index c2422d75ac..a62430592b 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -55,11 +55,13 @@ protected: // create the file and directory etc void CreateRuleFile(); - // outputs the rules for any custom commands used by this target - void WriteCustomCommandsForTarget(); + // outputs the rules for object files and custom commands used by + // this target + void WriteTargetBuildRules(); // write some common code at the top of build.make void WriteCommonCodeRules(); + void WriteTargetLanguageFlags(); // write the provide require rules for this target void WriteTargetRequiresRules(); @@ -83,14 +85,16 @@ protected: void WriteObjectDependRules(cmSourceFile& source, std::vector<std::string>& depends); - // this is responsible for writing all of the rules for all this - // directories custom commands (but not utility targets) - void WriteCustomCommands(); + // write the build rule for a custom command void GenerateCustomRuleFile(const cmCustomCommand& cc); // write out the variable that lists the objects for this target void WriteObjectsVariable(std::string& variableName, std::string& variableNameExternal); + void WriteObjectsString(std::string& buildObjs); + + // write the driver rule to build target outputs + void WriteTargetDriverRule(const char* main_output, bool relink); // Return the a string with -F flags on apple std::string GetFrameworkFlags(); diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx index 474f8504eb..51a848feec 100644 --- a/Source/cmMakefileUtilityTargetGenerator.cxx +++ b/Source/cmMakefileUtilityTargetGenerator.cxx @@ -33,7 +33,7 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles() << "# Utility rule file for " << this->Target->GetName() << ".\n\n"; // write the custom commands for this target - this->WriteCustomCommandsForTarget(); + this->WriteTargetBuildRules(); // Collect the commands and dependencies. std::vector<std::string> commands; @@ -63,19 +63,8 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles() this->Target->GetName(), depends, commands, true); - // Write convenience targets. - std::string dir = this->Makefile->GetStartOutputDirectory(); - dir += "/"; - dir += this->LocalGenerator->GetTargetDirectory(*this->Target); - std::string buildTargetRuleName = dir; - buildTargetRuleName += "/build"; - buildTargetRuleName = - this->LocalGenerator->Convert(buildTargetRuleName.c_str(), - cmLocalGenerator::HOME_OUTPUT, - cmLocalGenerator::MAKEFILE); - this->LocalGenerator->WriteConvenienceRule(*this->BuildFileStream, - this->Target->GetName(), - buildTargetRuleName.c_str()); + // Write the main driver rule to build everything in this target. + this->WriteTargetDriverRule(this->Target->GetName(), false); // Write clean target this->WriteTargetCleanRules(); diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx index 2ba6fd7a24..5856b51b33 100644 --- a/Source/cmMessageCommand.cxx +++ b/Source/cmMessageCommand.cxx @@ -57,9 +57,10 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args) message += *i; } - if (send_error) + if (send_error || fatal_error) { - cmSystemTools::Error(message.c_str()); + //cmSystemTools::Error(message.c_str()); + this->SetError(message.c_str()); } else { @@ -76,6 +77,6 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args) { cmSystemTools::SetFatalErrorOccured(); } - return true; + return (!send_error && !fatal_error); } diff --git a/Source/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h index 9bd3483686..a605a77b27 100644 --- a/Source/cmSetTargetPropertiesCommand.h +++ b/Source/cmSetTargetPropertiesCommand.h @@ -112,6 +112,9 @@ public: "There are a few properties used to specify RPATH rules. " "INSTALL_RPATH is a semicolon-separated list specifying the rpath " "to use in installed targets (for platforms that support it). " + "INSTALL_RPATH_USE_LINK_PATH is a boolean that if set to true will " + "append directories in the linker search path and outside the " + "project to the INSTALL_RPATH. " "SKIP_BUILD_RPATH is a boolean specifying whether to skip automatic " "generation of an rpath allowing the target to run from the " "build tree. " @@ -122,7 +125,8 @@ public: "directory portion of the \"install_name\" field of shared libraries " "on Mac OSX to use in the installed targets. " "When the target is created the values of " - "the variables CMAKE_INSTALL_RPATH, CMAKE_SKIP_BUILD_RPATH, " + "the variables CMAKE_INSTALL_RPATH, " + "CMAKE_INSTALL_RPATH_USE_LINK_PATH, CMAKE_SKIP_BUILD_RPATH, " "CMAKE_BUILD_WITH_INSTALL_RPATH, and CMAKE_INSTALL_NAME_DIR " "are used to initialize these properties.\n" "PROJECT_LABEL can be used to change the name of " diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 0f34a97cbb..26bc47d9d7 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -23,6 +23,11 @@ #include <set> #include <queue> #include <stdlib.h> // required for atof +const char* cmTarget::TargetTypeNames[] = { + "EXECUTABLE", "STATIC_LIBRARY", + "SHARED_LIBRARY", "MODULE_LIBRARY", "UTILITY", "GLOBAL_TARGET", + "INSTALL_FILES", "INSTALL_PROGRAMS", "INSTALL_DIRECTORY" +}; //---------------------------------------------------------------------------- cmTarget::cmTarget() @@ -58,6 +63,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) // Setup default property values. this->SetPropertyDefault("INSTALL_NAME_DIR", ""); this->SetPropertyDefault("INSTALL_RPATH", ""); + this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF"); this->SetPropertyDefault("SKIP_BUILD_RPATH", "OFF"); this->SetPropertyDefault("BUILD_WITH_INSTALL_RPATH", "OFF"); @@ -1316,19 +1322,36 @@ void cmTarget::GetLibraryNamesInternal(std::string& name, soversion = version; } + // Get the components of the library name. + std::string prefix; + std::string base; + std::string suffix; + this->GetFullNameInternal(type, config, false, prefix, base, suffix); + // The library name. - name = this->GetFullNameInternal(type, config, false); + name = prefix+base+suffix; // The library's soname. +#if defined(__APPLE__) + soName = prefix+base; +#else soName = name; +#endif if(soversion) { soName += "."; soName += soversion; } +#if defined(__APPLE__) + soName += suffix; +#endif // The library's real name on disk. +#if defined(__APPLE__) + realName = prefix+base; +#else realName = name; +#endif if(version) { realName += "."; @@ -1339,6 +1362,9 @@ void cmTarget::GetLibraryNamesInternal(std::string& name, realName += "."; realName += soversion; } +#if defined(__APPLE__) + realName += suffix; +#endif // The import library name. if(type == cmTarget::SHARED_LIBRARY) diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 7980218075..557461f24f 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -36,7 +36,7 @@ public: enum TargetType { EXECUTABLE, STATIC_LIBRARY, SHARED_LIBRARY, MODULE_LIBRARY, UTILITY, GLOBAL_TARGET, INSTALL_FILES, INSTALL_PROGRAMS, INSTALL_DIRECTORY}; - + static const char* TargetTypeNames[]; enum CustomCommandType { PRE_BUILD, PRE_LINK, POST_BUILD }; /** diff --git a/Source/cmTryCompileCommand.cxx b/Source/cmTryCompileCommand.cxx index c7405ca154..f3fe8937ab 100644 --- a/Source/cmTryCompileCommand.cxx +++ b/Source/cmTryCompileCommand.cxx @@ -110,7 +110,9 @@ int cmTryCompileCommand::CoreTryCompileCode( // signature if (srcFileSignature) { - tmpString = argv[1] + "/CMakeFiles/CMakeTmp"; + tmpString = argv[1]; + tmpString += cmake::GetCMakeFilesDirectory(); + tmpString += "/CMakeTmp"; binaryDirectory = tmpString.c_str(); } // make sure the binary directory exists diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx index ba7b481cd5..f8f2e861c4 100644 --- a/Source/cmTryRunCommand.cxx +++ b/Source/cmTryRunCommand.cxx @@ -68,7 +68,9 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv) tryCompile, false); // now try running the command if it compiled - std::string binaryDirectory = argv[2] + "/CMakeFiles/CMakeTmp"; + std::string binaryDirectory = argv[2]; + binaryDirectory += cmake::GetCMakeFilesDirectory(); + binaryDirectory += "/CMakeTmp"; if (!res) { int retVal = -1; diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx index 3c785d7905..f88ed2b11c 100644 --- a/Source/cmWhileCommand.cxx +++ b/Source/cmWhileCommand.cxx @@ -28,7 +28,15 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) } // at end of for each execute recorded commands - if (cmSystemTools::LowerCase(lff.Name) == "endwhile") + if (!cmSystemTools::Strucmp(lff.Name.c_str(),"while")) + { + // record the number of while commands past this one + this->Depth++; + } + else if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endwhile")) + { + // if this is the endwhile for this while loop then execute + if (!this->Depth) { char* errorString = 0; @@ -53,6 +61,12 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) mf.RemoveFunctionBlocker(lff); return true; } + else + { + // decrement for each nested while that ends + this->Depth--; + } + } // record the command this->Functions.push_back(lff); @@ -62,11 +76,12 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) } bool cmWhileFunctionBlocker:: -ShouldRemove(const cmListFileFunction& lff, cmMakefile& ) +ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) { - if(cmSystemTools::LowerCase(lff.Name) == "endwhile") + if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endwhile")) { - if (lff.Arguments == this->Args) + if (lff.Arguments == this->Args + || mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS")) { return true; } diff --git a/Source/cmWhileCommand.h b/Source/cmWhileCommand.h index 10c261ca85..e1f44ebd23 100644 --- a/Source/cmWhileCommand.h +++ b/Source/cmWhileCommand.h @@ -29,7 +29,7 @@ class cmWhileFunctionBlocker : public cmFunctionBlocker { public: - cmWhileFunctionBlocker() {Executing = false;} + cmWhileFunctionBlocker() {Executing = false; Depth=0;} virtual ~cmWhileFunctionBlocker() {} virtual bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf); @@ -39,6 +39,8 @@ public: std::vector<cmListFileArgument> Args; std::vector<cmListFileFunction> Functions; bool Executing; +private: + int Depth; }; /** \class cmWhileCommand diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 53b7526243..2c64d2e7fd 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -31,6 +31,9 @@ # include <cmsys/Terminal.h> #endif +# include <cmsys/Directory.hxx> +#include <cmsys/Process.h> + // only build kdevelop generator on non-windows platforms // when not bootstrapping cmake #if !defined(_WIN32) @@ -267,7 +270,16 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) std::string entry = arg.substr(2); if(entry.size() == 0) { - entry = args[++i]; + ++i; + if(i < args.size()) + { + entry = args[i]; + } + else + { + cmSystemTools::Error("-D must be followed with VAR=VALUE."); + return false; + } } std::string var, value; cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED; @@ -291,7 +303,16 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) std::string path = arg.substr(2); if ( path.size() == 0 ) { - path = args[++i]; + ++i; + if(i < args.size()) + { + path = args[i]; + } + else + { + cmSystemTools::Error("-C must be followed by a file name."); + return false; + } } std::cerr << "loading initial cache file " << path.c_str() << "\n"; this->ReadListFile(path.c_str()); @@ -299,6 +320,11 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) else if(arg.find("-P",0) == 0) { i++; + if(i >= args.size()) + { + cmSystemTools::Error("-P must be followed by a file name."); + return false; + } std::string path = args[i]; if ( path.size() == 0 ) { @@ -425,7 +451,13 @@ void cmake::SetArgs(const std::vector<std::string>& args) std::string value = arg.substr(2); if(value.size() == 0) { - value = args[++i]; + ++i; + if(i >= args.size()) + { + cmSystemTools::Error("No generator specified for -G"); + return; + } + value = args[i]; } cmGlobalGenerator* gen = this->CreateGlobalGenerator(value.c_str()); @@ -837,6 +869,19 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args) return 0; } + // Echo string no new line + else if (args[1] == "echo_append" ) + { + unsigned int cc; + const char* space = ""; + for ( cc = 2; cc < args.size(); cc ++ ) + { + std::cout << space << args[cc]; + space = " "; + } + return 0; + } + #if defined(CMAKE_BUILD_WITH_CMAKE) // Command to create a symbolic link. Fails on platforms not // supporting them. @@ -855,15 +900,22 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args) // Remove file else if (args[1] == "remove" && args.size() > 2) { + bool force = false; for (std::string::size_type cc = 2; cc < args.size(); cc ++) { - if(args[cc] != "-f") + if(args[cc] == "\\-f" || args[cc] == "-f") { - if(args[cc] == "\\-f") + force = true; + } + else + { + // Complain if the file could not be removed, still exists, + // and the -f option was not given. + if(!cmSystemTools::RemoveFile(args[cc].c_str()) && !force && + cmSystemTools::FileExists(args[cc].c_str())) { - args[cc] = "-f"; + return 1; } - cmSystemTools::RemoveFile(args[cc].c_str()); } } return 0; @@ -931,6 +983,67 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args) return 1; } + // Command to start progress for a build + else if (args[1] == "cmake_progress_start" && args.size() == 4) + { + // bascially remove the directory + std::string dirName = args[2]; + dirName += "/Progress"; + cmSystemTools::RemoveADirectory(dirName.c_str()); + cmSystemTools::MakeDirectory(dirName.c_str()); + // write the count into the directory + std::string fName = dirName; + fName += "/count.txt"; + FILE *progFile = fopen(fName.c_str(),"w"); + if (progFile) + { + int count = atoi(args[3].c_str()); + fprintf(progFile,"%i\n",count); + fclose(progFile); + } + return 0; + } + + // Command to report progress for a build + else if (args[1] == "cmake_progress_report" && args.size() >= 3) + { + std::string dirName = args[2]; + dirName += "/Progress"; + std::string fName; + FILE *progFile; + unsigned int i; + for (i = 3; i < args.size(); ++i) + { + fName = dirName; + fName += "/"; + fName += args[i]; + progFile = fopen(fName.c_str(),"w"); + if (progFile) + { + fprintf(progFile,"empty"); + fclose(progFile); + } + } + int fileNum = static_cast<int> + (cmsys::Directory::GetNumberOfFilesInDirectory(dirName.c_str())); + // read the count + fName = dirName; + fName += "/count.txt"; + progFile = fopen(fName.c_str(),"r"); + if (progFile) + { + int count = 0; + fscanf(progFile,"%i",&count); + if (count > 0) + { + // print the progress + fprintf(stdout,"[%3i%%] ",((fileNum-3)*100)/count); + } + fclose(progFile); + } + return 0; + } + // Command to create a symbolic link. Fails on platforms not // supporting them. else if (args[1] == "create_symlink" && args.size() == 4) @@ -996,18 +1109,81 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args) // Internal CMake dependency scanning support. else if (args[1] == "cmake_depends" && args.size() >= 6) { + // Create a cmake object instance to process dependencies. cmake cm; - cmGlobalGenerator *ggd = cm.CreateGlobalGenerator(args[2].c_str()); - if (ggd) + std::string gen; + std::string homeDir; + std::string startDir; + std::string homeOutDir; + std::string startOutDir; + std::string depInfo; + if(args.size() >= 8) + { + // Full signature: + // + // -E cmake_depends <generator> + // <home-src-dir> <start-src-dir> + // <home-out-dir> <start-out-dir> + // <dep-info> + // + // All paths are provided. + gen = args[2]; + homeDir = args[3]; + startDir = args[4]; + homeOutDir = args[5]; + startOutDir = args[6]; + depInfo = args[7]; + } + else + { + // Support older signature for existing makefiles: + // + // -E cmake_depends <generator> + // <home-out-dir> <start-out-dir> + // <dep-info> + // + // Just pretend the source directories are the same as the + // binary directories so at least scanning will work. + gen = args[2]; + homeDir = args[3]; + startDir = args[4]; + homeOutDir = args[3]; + startOutDir = args[3]; + depInfo = args[5]; + } + + // Create a local generator configured for the directory in + // which dependencies will be scanned. + homeDir = cmSystemTools::CollapseFullPath(homeDir.c_str()); + startDir = cmSystemTools::CollapseFullPath(startDir.c_str()); + homeOutDir = cmSystemTools::CollapseFullPath(homeOutDir.c_str()); + startOutDir = cmSystemTools::CollapseFullPath(startOutDir.c_str()); + cm.SetHomeDirectory(homeDir.c_str()); + cm.SetStartDirectory(startDir.c_str()); + cm.SetHomeOutputDirectory(homeOutDir.c_str()); + cm.SetStartOutputDirectory(startOutDir.c_str()); + if(cmGlobalGenerator* ggd = cm.CreateGlobalGenerator(gen.c_str())) { - ggd->SetCMakeInstance(&cm); + cm.SetGlobalGenerator(ggd); std::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator()); lgd->SetGlobalGenerator(ggd); - return lgd->ScanDependencies(args)? 0 : 2; + lgd->GetMakefile()->SetStartDirectory(startDir.c_str()); + lgd->GetMakefile()->SetStartOutputDirectory(startOutDir.c_str()); + lgd->GetMakefile()->MakeStartDirectoriesCurrent(); + lgd->SetupPathConversions(); + + // Actually scan dependencies. + return lgd->ScanDependencies(depInfo.c_str())? 0 : 2; } return 1; } + // Internal CMake link script support. + else if (args[1] == "cmake_link_script" && args.size() >= 3) + { + return cmake::ExecuteLinkScript(args); + } + #ifdef CMAKE_BUILD_WITH_CMAKE // Internal CMake color makefile support. else if (args[1] == "cmake_echo_color") @@ -1865,9 +2041,7 @@ int cmake::CheckBuildSystem() // This method will check the integrity of the build system if the // option was given on the command line. It reads the given file to - // determine whether CMake should rerun. If it does rerun then the - // generation step will check the integrity of dependencies. If it - // does not then we need to check the integrity here. + // determine whether CMake should rerun. // If no file is provided for the check, we have to rerun. if(this->CheckBuildSystemArgument.size() == 0) @@ -1916,6 +2090,25 @@ int cmake::CheckBuildSystem() return 1; } + // Now that we know the generator used to build the project, use it + // to check the dependency integrity. + const char* genName = mf->GetDefinition("CMAKE_DEPENDS_GENERATOR"); + if (!genName || genName[0] == '\0') + { + genName = "Unix Makefiles"; + } + cmGlobalGenerator *ggd = this->CreateGlobalGenerator(genName); + if (ggd) + { + // Check the dependencies in case source files were removed. + std::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator()); + lgd->SetGlobalGenerator(ggd); + lgd->CheckDependencies(mf, verbose, this->ClearBuildSystem); + + // Check for multiple output pairs. + ggd->CheckMultipleOutputs(mf, verbose); + } + // Get the set of dependencies and outputs. const char* dependsStr = mf->GetDefinition("CMAKE_MAKEFILE_DEPENDS"); const char* outputsStr = mf->GetDefinition("CMAKE_MAKEFILE_OUTPUTS"); @@ -1960,24 +2153,6 @@ int cmake::CheckBuildSystem() } } - // compute depends based on the generator specified - const char* genName = mf->GetDefinition("CMAKE_DEPENDS_GENERATOR"); - if (!genName || genName[0] == '\0') - { - genName = "Unix Makefiles"; - } - cmGlobalGenerator *ggd = this->CreateGlobalGenerator(genName); - if (ggd) - { - // Check the dependencies in case source files were removed. - std::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator()); - lgd->SetGlobalGenerator(ggd); - lgd->CheckDependencies(mf, verbose, this->ClearBuildSystem); - - // Check for multiple output pairs. - ggd->CheckMultipleOutputs(mf, verbose); - } - // No need to rerun. return 0; } @@ -2193,7 +2368,7 @@ void cmake::GenerateGraphViz(const char* fileName) std::map<cmStdString, int> targetDeps; std::map<cmStdString, cmTarget*> targetPtrs; std::map<cmStdString, cmStdString> targetNamesNodes; - char tgtName[100]; + char tgtName[2048]; int cnt = 0; // First pass get the list of all cmake targets for ( lit = localGenerators.begin(); lit != localGenerators.end(); ++ lit ) @@ -2474,3 +2649,101 @@ int cmake::ExecuteEchoColor(std::vector<std::string>&) return 1; } #endif + +//---------------------------------------------------------------------------- +int cmake::ExecuteLinkScript(std::vector<std::string>& args) +{ + // The arguments are + // argv[0] == <cmake-executable> + // argv[1] == cmake_link_script + // argv[2] == <link-script-name> + // argv[3] == --verbose=? + bool verbose = false; + if(args.size() >= 4) + { + if(args[3].find("--verbose=") == 0) + { + if(!cmSystemTools::IsOff(args[3].substr(10).c_str())) + { + verbose = true; + } + } + } + + // Allocate a process instance. + cmsysProcess* cp = cmsysProcess_New(); + if(!cp) + { + std::cerr << "Error allocating process instance in link script." + << std::endl; + return 1; + } + + // Children should share stdout and stderr with this process. + cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDOUT, 1); + cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1); + + // Run the command lines verbatim. + cmsysProcess_SetOption(cp, cmsysProcess_Option_Verbatim, 1); + + // Read command lines from the script. + std::ifstream fin(args[2].c_str()); + if(!fin) + { + std::cerr << "Error opening link script \"" + << args[2] << "\"" << std::endl; + return 1; + } + + // Run one command at a time. + std::string command; + int result = 0; + while(result == 0 && cmSystemTools::GetLineFromStream(fin, command)) + { + // Setup this command line. + const char* cmd[2] = {command.c_str(), 0}; + cmsysProcess_SetCommand(cp, cmd); + + // Report the command if verbose output is enabled. + if(verbose) + { + std::cout << command << std::endl; + } + + // Run the command and wait for it to exit. + cmsysProcess_Execute(cp); + cmsysProcess_WaitForExit(cp, 0); + + // Report failure if any. + switch(cmsysProcess_GetState(cp)) + { + case cmsysProcess_State_Exited: + { + int value = cmsysProcess_GetExitValue(cp); + if(value != 0) + { + result = value; + } + } + break; + case cmsysProcess_State_Exception: + std::cerr << "Error running link command: " + << cmsysProcess_GetExceptionString(cp) << std::endl; + result = 1; + break; + case cmsysProcess_State_Error: + std::cerr << "Error running link command: " + << cmsysProcess_GetErrorString(cp) << std::endl; + result = 2; + break; + default: + break; + }; + } + + // Free the process instance. + cmsysProcess_Delete(cp); + + // Return the final resulting return value. + return result; +} diff --git a/Source/cmake.h b/Source/cmake.h index b2cea7bde5..d63cf7e3eb 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -67,6 +67,11 @@ class cmake static unsigned int GetMinorVersion(); static const char *GetReleaseVersion(); + ///! construct an instance of cmake + static const char *GetCMakeFilesDirectory() {return "/CMakeFiles";}; + static const char *GetCMakeFilesDirectoryPostSlash() { + return "CMakeFiles/";}; + //@{ /** * Set/Get the home directory (or output directory) in the project. The @@ -318,6 +323,7 @@ protected: void GenerateGraphViz(const char* fileName); static int ExecuteEchoColor(std::vector<std::string>& args); + static int ExecuteLinkScript(std::vector<std::string>& args); cmVariableWatch* VariableWatch; diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index bb01116f3c..c16cd1c26c 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -82,6 +82,9 @@ static const cmDocumentationEntry cmDocumentationOptions[] = {"--graphviz=[file]", "Generate graphviz of dependencies.", "Generate a graphviz input file that will contain all the library and " "executable dependencies in the project."}, + {"--debug-trycompile", "Do not delete the try compile directories..", + "Do not delete the files and directories created for try_compile calls. " + "This is useful in debugging failed try_compiles."}, {"--help-command cmd [file]", "Print help for a single command and exit.", "Full documentation specific to the given command is displayed."}, {"--help-command-list [file]", "List available listfile commands and exit.", @@ -236,10 +239,13 @@ int do_cmake(int ac, char** av) { cmSystemTools::Error("No script specified for argument -P"); } + else + { script_mode = true; args.push_back(av[i]); i++; args.push_back(av[i]); + } } else { diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx index b1ee992e1e..cdf254f7d9 100644 --- a/Source/kwsys/CommandLineArguments.cxx +++ b/Source/kwsys/CommandLineArguments.cxx @@ -364,7 +364,7 @@ void CommandLineArguments::DeleteRemainingArguments(int argc, char*** argv) int cc; for ( cc = 0; cc < argc; ++ cc ) { - delete [] *argv[cc]; + delete [] (*argv)[cc]; } delete [] *argv; } diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx index 3f7e6ad5ce..f7fb5e98c3 100644 --- a/Source/kwsys/Directory.cxx +++ b/Source/kwsys/Directory.cxx @@ -143,6 +143,47 @@ bool Directory::Load(const char* name) return _findclose(srchHandle) != -1; } +unsigned long Directory::GetNumberOfFilesInDirectory(const char* name) +{ +#if _MSC_VER < 1300 + long srchHandle; +#else + intptr_t srchHandle; +#endif + char* buf; + size_t n = strlen(name); + if ( name[n - 1] == '/' ) + { + buf = new char[n + 1 + 1]; + sprintf(buf, "%s*", name); + } + else + { + buf = new char[n + 2 + 1]; + sprintf(buf, "%s/*", name); + } + struct _finddata_t data; // data of current file + + // Now put them into the file array + srchHandle = _findfirst(buf, &data); + delete [] buf; + + if ( srchHandle == -1 ) + { + return 0; + } + + // Loop through names + unsigned long count = 0; + do + { + count++; + } + while ( _findnext(srchHandle, &data) != -1 ); + _findclose(srchHandle); + return count; +} + } // namespace KWSYS_NAMESPACE #else @@ -174,6 +215,24 @@ bool Directory::Load(const char* name) return 1; } +unsigned long Directory::GetNumberOfFilesInDirectory(const char* name) +{ + DIR* dir = opendir(name); + + if (!dir) + { + return 0; + } + + unsigned long count = 0; + for (dirent* d = readdir(dir); d; d = readdir(dir) ) + { + count++; + } + closedir(dir); + return count; +} + } // namespace KWSYS_NAMESPACE #endif diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in index 22aafcc7ea..ddb9104dd2 100644 --- a/Source/kwsys/Directory.hxx.in +++ b/Source/kwsys/Directory.hxx.in @@ -48,6 +48,12 @@ public: unsigned long GetNumberOfFiles() const; /** + * Return the number of files in the specified directory. + * A higher performance static method. + */ + static unsigned long GetNumberOfFilesInDirectory(const char*); + + /** * Return the file at the given index, the indexing is 0 based */ const char* GetFile(unsigned long) const; diff --git a/Source/kwsys/Process.h.in b/Source/kwsys/Process.h.in index 96d3225bb3..3d2db7b475 100644 --- a/Source/kwsys/Process.h.in +++ b/Source/kwsys/Process.h.in @@ -36,6 +36,7 @@ #define kwsysProcess_SetPipeShared kwsys_ns(Process_SetPipeShared) #define kwsysProcess_Option_Detach kwsys_ns(Process_Option_Detach) #define kwsysProcess_Option_HideWindow kwsys_ns(Process_Option_HideWindow) +#define kwsysProcess_Option_Verbatim kwsys_ns(Process_Option_Verbatim) #define kwsysProcess_GetOption kwsys_ns(Process_GetOption) #define kwsysProcess_SetOption kwsys_ns(Process_SetOption) #define kwsysProcess_Option_e kwsys_ns(Process_Option_e) @@ -154,6 +155,13 @@ kwsysEXPORT void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, * kwsysProcess_Option_HideWindow = Whether to hide window on Windows. * 0 = No (default) * 1 = Yes + * + * kwsysProcess_Option_Verbatim = Whether SetCommand and AddCommand + * should treat the first argument + * as a verbatim command line + * and ignore the rest of the arguments. + * 0 = No (default) + * 1 = Yes */ kwsysEXPORT int kwsysProcess_GetOption(kwsysProcess* cp, int optionId); kwsysEXPORT void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, @@ -161,7 +169,8 @@ kwsysEXPORT void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, enum kwsysProcess_Option_e { kwsysProcess_Option_HideWindow, - kwsysProcess_Option_Detach + kwsysProcess_Option_Detach, + kwsysProcess_Option_Verbatim }; /** @@ -343,6 +352,7 @@ kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp); # undef kwsysProcess_SetPipeShared # undef kwsysProcess_Option_Detach # undef kwsysProcess_Option_HideWindow +# undef kwsysProcess_Option_Verbatim # undef kwsysProcess_GetOption # undef kwsysProcess_SetOption # undef kwsysProcess_Option_e diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c index 0f4d1bcb48..ea257b0d2b 100644 --- a/Source/kwsys/ProcessUNIX.c +++ b/Source/kwsys/ProcessUNIX.c @@ -24,17 +24,18 @@ Implementation for UNIX -On UNIX, a child process is forked to exec the program. Three -output pipes from the child are read by the parent process using a -select call to block until data are ready. Two of the pipes are -stdout and stderr for the child. The third is a special error pipe -that has two purposes. First, if the child cannot exec the program, -the error is reported through the error pipe. Second, the error -pipe is left open until the child exits. This is used in -conjunction with the timeout on the select call to implement a -timeout for program even when it closes stdout and stderr. +On UNIX, a child process is forked to exec the program. Three output +pipes are read by the parent process using a select call to block +until data are ready. Two of the pipes are stdout and stderr for the +child. The third is a special pipe populated by a signal handler to +indicate that a child has terminated. This is used in conjunction +with the timeout on the select call to implement a timeout for program +even when it closes stdout and stderr and at the same time avoiding +races. + */ + /* TODO: @@ -59,6 +60,7 @@ do. #include <time.h> /* gettimeofday */ #include <signal.h> /* sigaction */ #include <dirent.h> /* DIR, dirent */ +#include <ctype.h> /* isspace */ /* The number of pipes for the child's output. The standard stdout and stderr pipes are the first two. One more pipe is used to @@ -68,7 +70,7 @@ do. #define KWSYSPE_PIPE_COUNT 3 #define KWSYSPE_PIPE_STDOUT 0 #define KWSYSPE_PIPE_STDERR 1 -#define KWSYSPE_PIPE_TERM 2 +#define KWSYSPE_PIPE_SIGNAL 2 /* The maximum amount to read from a pipe at a time. */ #define KWSYSPE_PIPE_BUFFER_SIZE 1024 @@ -89,7 +91,6 @@ typedef struct kwsysProcessCreateInformation_s int StdIn; int StdOut; int StdErr; - int TermPipe; int ErrorPipe[2]; } kwsysProcessCreateInformation; @@ -99,6 +100,7 @@ static void kwsysProcessCleanup(kwsysProcess* cp, int error); static void kwsysProcessCleanupDescriptor(int* pfd); static int kwsysProcessCreate(kwsysProcess* cp, int prIndex, kwsysProcessCreateInformation* si, int* readEnd); +static void kwsysProcessDestroy(kwsysProcess* cp); static int kwsysProcessSetupOutputPipeFile(int* p, const char* name); static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout, kwsysProcessTime* timeoutTime); @@ -117,6 +119,11 @@ static void kwsysProcessRestoreDefaultSignalHandlers(void); static pid_t kwsysProcessFork(kwsysProcess* cp, kwsysProcessCreateInformation* si); static void kwsysProcessKill(pid_t process_id); +static int kwsysProcessesAdd(kwsysProcess* cp); +static void kwsysProcessesRemove(kwsysProcess* cp); +static void kwsysProcessesSignalHandler(int signum, siginfo_t* info, + void* ucontext); +static char** kwsysProcessParseVerbatimCommand(const char* command); /*--------------------------------------------------------------------------*/ /* Structure containing data used to implement the child's execution. */ @@ -126,9 +133,13 @@ struct kwsysProcess_s char*** Commands; int NumberOfCommands; - /* Descriptors for the read ends of the child's output pipes. */ + /* Descriptors for the read ends of the child's output pipes and + the signal pipe. */ int PipeReadEnds[KWSYSPE_PIPE_COUNT]; + /* Write descriptor for child termination signal pipe. */ + int SignalPipe; + /* Buffer for pipe data. */ char PipeBuffer[KWSYSPE_PIPE_BUFFER_SIZE]; @@ -150,6 +161,9 @@ struct kwsysProcess_s /* Whether the child was created as a detached process. */ int Detached; + /* Whether to treat command lines as verbatim. */ + int Verbatim; + /* Time at which the child started. Negative for no timeout. */ kwsysProcessTime StartTime; @@ -159,15 +173,15 @@ struct kwsysProcess_s /* Flag for whether the timeout expired. */ int TimeoutExpired; - /* The old SIGCHLD handler. */ - struct sigaction OldSigChldAction; - /* The number of pipes left open during execution. */ int PipesLeft; /* File descriptor set for call to select. */ fd_set PipeSet; + /* The number of children still executing. */ + int CommandsLeft; + /* The current status of the child process. */ int State; @@ -300,7 +314,7 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) char*** newCommands; /* Make sure we have a command to add. */ - if(!cp || !command) + if(!cp || !command || !*command) { return 0; } @@ -323,7 +337,22 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) } /* Add the new command. */ + if(cp->Verbatim) { + /* In order to run the given command line verbatim we need to + parse it. */ + newCommands[cp->NumberOfCommands] = + kwsysProcessParseVerbatimCommand(*command); + if(!newCommands[cp->NumberOfCommands]) + { + /* Out of memory. */ + free(newCommands); + return 0; + } + } + else + { + /* Copy each argument string individually. */ char const* const* c = command; int n = 0; int i = 0; @@ -483,6 +512,7 @@ int kwsysProcess_GetOption(kwsysProcess* cp, int optionId) switch(optionId) { case kwsysProcess_Option_Detach: return cp->OptionDetach; + case kwsysProcess_Option_Verbatim: return cp->Verbatim; default: return 0; } } @@ -498,6 +528,7 @@ void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value) switch(optionId) { case kwsysProcess_Option_Detach: cp->OptionDetach = value; break; + case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break; default: break; } } @@ -558,8 +589,7 @@ const char* kwsysProcess_GetExceptionString(kwsysProcess* cp) void kwsysProcess_Execute(kwsysProcess* cp) { int i; - struct sigaction newSigChldAction; - kwsysProcessCreateInformation si = {-1, -1, -1, -1, {-1, -1}}; + kwsysProcessCreateInformation si = {-1, -1, -1, {-1, -1}}; /* Do not execute a second copy simultaneously. */ if(!cp || cp->State == kwsysProcess_State_Executing) @@ -597,15 +627,19 @@ void kwsysProcess_Execute(kwsysProcess* cp) } } - /* We want no special handling of SIGCHLD. Repeat call until it is - not interrupted. */ - memset(&newSigChldAction, 0, sizeof(struct sigaction)); - newSigChldAction.sa_handler = SIG_DFL; - while((sigaction(SIGCHLD, &newSigChldAction, &cp->OldSigChldAction) < 0) && - (errno == EINTR)); + /* If not running a detached child, add this object to the global + set of process objects that wish to be notified when a child + exits. */ + if(!cp->OptionDetach) + { + if(!kwsysProcessesAdd(cp)) + { + kwsysProcessCleanup(cp, 1); + return; + } + } - /* Setup the stderr and termination pipes to be shared by all processes. */ - for(i=KWSYSPE_PIPE_STDERR; i < KWSYSPE_PIPE_COUNT; ++i) + /* Setup the stderr pipe to be shared by all processes. */ { /* Create the pipe. */ int p[2]; @@ -616,15 +650,8 @@ void kwsysProcess_Execute(kwsysProcess* cp) } /* Store the pipe. */ - cp->PipeReadEnds[i] = p[0]; - if(i == KWSYSPE_PIPE_STDERR) - { + cp->PipeReadEnds[KWSYSPE_PIPE_STDERR] = p[0]; si.StdErr = p[1]; - } - else - { - si.TermPipe = p[1]; - } /* Set close-on-exec flag on the pipe's ends. */ if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) || @@ -632,7 +659,6 @@ void kwsysProcess_Execute(kwsysProcess* cp) { kwsysProcessCleanup(cp, 1); kwsysProcessCleanupDescriptor(&si.StdErr); - kwsysProcessCleanupDescriptor(&si.TermPipe); return; } } @@ -645,7 +671,6 @@ void kwsysProcess_Execute(kwsysProcess* cp) { kwsysProcessCleanup(cp, 1); kwsysProcessCleanupDescriptor(&si.StdErr); - kwsysProcessCleanupDescriptor(&si.TermPipe); return; } } @@ -688,7 +713,6 @@ void kwsysProcess_Execute(kwsysProcess* cp) { kwsysProcessCleanupDescriptor(&si.StdErr); } - kwsysProcessCleanupDescriptor(&si.TermPipe); kwsysProcessCleanupDescriptor(&si.ErrorPipe[0]); kwsysProcessCleanupDescriptor(&si.ErrorPipe[1]); return; @@ -703,7 +727,6 @@ void kwsysProcess_Execute(kwsysProcess* cp) { kwsysProcessCleanupDescriptor(&si.StdErr); } - kwsysProcessCleanupDescriptor(&si.TermPipe); /* Restore the working directory. */ if(cp->RealWorkingDirectory) @@ -823,9 +846,10 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length, if(n > 0) { /* We have data on this pipe. */ - if(i == KWSYSPE_PIPE_TERM) + if(i == KWSYSPE_PIPE_SIGNAL) { - /* This is data on the special termination pipe. Ignore it. */ + /* A child process has terminated. */ + kwsysProcessDestroy(cp); } else if(data && length) { @@ -970,7 +994,6 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length, /*--------------------------------------------------------------------------*/ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout) { - int result = 0; int status = 0; int prPipe = 0; @@ -989,26 +1012,6 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout) } } - /* Wait for each child to terminate. The process should have - already exited because KWSYSPE_PIPE_TERM has been closed by this - point. Repeat the call until it is not interrupted. */ - if(!cp->Detached) - { - int i; - for(i=0; i < cp->NumberOfCommands; ++i) - { - while(((result = waitpid(cp->ForkPIDs[i], - &cp->CommandExitCodes[i], 0)) < 0) && - (errno == EINTR)); - if(result <= 0 && cp->State != kwsysProcess_State_Error) - { - /* Unexpected error. Report the first time this happens. */ - strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE); - cp->State = kwsysProcess_State_Error; - } - } - } - /* Check if there was an error in one of the waitpid calls. */ if(cp->State == kwsysProcess_State_Error) { @@ -1080,22 +1083,35 @@ void kwsysProcess_Kill(kwsysProcess* cp) return; } + /* Close all the pipe read ends. Do this before killing the + children because Cygwin has problems killing processes that are + blocking to wait for writing to their output pipes. First close + the child exit report pipe write end to avoid causing a SIGPIPE + when the child terminates and our signal handler tries to report + it. */ + kwsysProcessCleanupDescriptor(&cp->SignalPipe); + for(i=0; i < KWSYSPE_PIPE_COUNT; ++i) + { + kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]); + } + cp->PipesLeft = 0; + /* Kill the children. */ cp->Killed = 1; for(i=0; i < cp->NumberOfCommands; ++i) { + int status; if(cp->ForkPIDs[i]) { + /* Kill the child. */ kwsysProcessKill(cp->ForkPIDs[i]); - } - } - /* Close all the pipe read ends. */ - for(i=0; i < KWSYSPE_PIPE_COUNT; ++i) - { - kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]); + /* Reap the child. Keep trying until the call is not + interrupted. */ + while((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && (errno == EINTR)); } - cp->PipesLeft = 0; + } + cp->CommandsLeft = 0; } /*--------------------------------------------------------------------------*/ @@ -1107,6 +1123,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp) { cp->PipeReadEnds[i] = -1; } + cp->SignalPipe = -1; cp->SelectError = 0; cp->StartTime.tv_sec = -1; cp->StartTime.tv_usec = -1; @@ -1114,6 +1131,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp) cp->TimeoutTime.tv_usec = -1; cp->TimeoutExpired = 0; cp->PipesLeft = 0; + cp->CommandsLeft = 0; FD_ZERO(&cp->PipeSet); cp->State = kwsysProcess_State_Starting; cp->Killed = 0; @@ -1194,6 +1212,7 @@ static void kwsysProcessCleanup(kwsysProcess* cp, int error) { /* Kill the child. */ kwsysProcessKill(cp->ForkPIDs[i]); + /* Reap the child. Keep trying until the call is not interrupted. */ while((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && @@ -1209,9 +1228,13 @@ static void kwsysProcessCleanup(kwsysProcess* cp, int error) } } - /* Restore the SIGCHLD handler. */ - while((sigaction(SIGCHLD, &cp->OldSigChldAction, 0) < 0) && - (errno == EINTR)); + /* If not creating a detached child, remove this object from the + global set of process objects that wish to be notified when a + child exits. */ + if(!cp->OptionDetach) + { + kwsysProcessesRemove(cp); + } /* Free memory. */ if(cp->ForkPIDs) @@ -1360,12 +1383,10 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex, } /* Clear the close-on-exec flag for stdin, stdout, and stderr. - Also clear it for the termination pipe. All other pipe handles - will be closed when exec succeeds. */ + All other pipe handles will be closed when exec succeeds. */ fcntl(0, F_SETFD, 0); fcntl(1, F_SETFD, 0); fcntl(2, F_SETFD, 0); - fcntl(si->TermPipe, F_SETFD, 0); /* Restore all default signal handlers. */ kwsysProcessRestoreDefaultSignalHandlers(); @@ -1377,6 +1398,9 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex, kwsysProcessChildErrorExit(si->ErrorPipe[1]); } + /* A child has been created. */ + ++cp->CommandsLeft; + /* We are done with the error reporting pipe write end. */ kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]); @@ -1425,6 +1449,47 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex, } /*--------------------------------------------------------------------------*/ +static void kwsysProcessDestroy(kwsysProcess* cp) +{ + /* A child process has terminated. Reap it if it is one handled by + this object. */ + int i; + for(i=0; i < cp->NumberOfCommands; ++i) + { + if(cp->ForkPIDs[i]) + { + int result; + while(((result = waitpid(cp->ForkPIDs[i], + &cp->CommandExitCodes[i], WNOHANG)) < 0) && + (errno == EINTR)); + if(result > 0) + { + /* This child has termianted. */ + cp->ForkPIDs[i] = 0; + if(--cp->CommandsLeft == 0) + { + /* All children have terminated. Close the signal pipe + write end so that no more notifications are sent to this + object. */ + kwsysProcessCleanupDescriptor(&cp->SignalPipe); + + /* TODO: Once the children have terminated, switch + WaitForData to use a non-blocking read to get the + rest of the data from the pipe. This is needed when + grandchildren keep the output pipes open. */ + } + } + else if(result < 0 && cp->State != kwsysProcess_State_Error) + { + /* Unexpected error. Report the first time this happens. */ + strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE); + cp->State = kwsysProcess_State_Error; + } + } + } +} + +/*--------------------------------------------------------------------------*/ static int kwsysProcessSetupOutputPipeFile(int* p, const char* name) { int fout; @@ -1909,12 +1974,15 @@ static pid_t kwsysProcessFork(kwsysProcess* cp, #elif defined(__hpux) || defined(__sparc) || defined(__sgi) || defined(_AIX) # define KWSYSPE_PS_COMMAND "ps -ef" # define KWSYSPE_PS_FORMAT "%*s %d %d %*[^\n]\n" +#elif defined(__CYGWIN__) +# define KWSYSPE_PS_COMMAND "ps aux" +# define KWSYSPE_PS_FORMAT "%d %d %*[^\n]\n" #endif /*--------------------------------------------------------------------------*/ static void kwsysProcessKill(pid_t process_id) { -#if defined(__linux__) +#if defined(__linux__) || defined(__CYGWIN__) DIR* procdir; #endif @@ -1922,7 +1990,7 @@ static void kwsysProcessKill(pid_t process_id) kill(process_id, SIGSTOP); /* Kill all children if we can find them. */ -#if defined(__linux__) +#if defined(__linux__) || defined(__CYGWIN__) /* First try using the /proc filesystem. */ if((procdir = opendir("/proc")) != NULL) { @@ -1980,8 +2048,8 @@ static void kwsysProcessKill(pid_t process_id) } else #endif -#if defined(KWSYSPE_PS_COMMAND) { +#if defined(KWSYSPE_PS_COMMAND) /* Try running "ps" to get the process information. */ FILE* ps = popen(KWSYSPE_PS_COMMAND, "r"); @@ -2005,9 +2073,461 @@ static void kwsysProcessKill(pid_t process_id) { pclose(ps); } - } #endif + } /* Kill the process. */ kill(process_id, SIGKILL); } + +/*--------------------------------------------------------------------------*/ +/* Global set of executing processes for use by the signal handler. + This global instance will be zero-initialized by the compiler. */ +typedef struct kwsysProcessInstances_s +{ + int Count; + int Size; + kwsysProcess** Processes; +} kwsysProcessInstances; +static kwsysProcessInstances kwsysProcesses; + +/* The old SIGCHLD handler. */ +static struct sigaction kwsysProcessesOldSigChldAction; + +/*--------------------------------------------------------------------------*/ +static void kwsysProcessesUpdate(kwsysProcessInstances* newProcesses) +{ + /* Block SIGCHLD while we update the set of pipes to check. + TODO: sigprocmask is undefined for threaded apps. See + pthread_sigmask. */ + sigset_t newset; + sigset_t oldset; + sigemptyset(&newset); + sigaddset(&newset, SIGCHLD); + sigprocmask(SIG_BLOCK, &newset, &oldset); + + /* Store the new set in that seen by the signal handler. */ + kwsysProcesses = *newProcesses; + + /* Restore the signal mask to the previous setting. */ + sigprocmask(SIG_SETMASK, &oldset, 0); +} + +/*--------------------------------------------------------------------------*/ +static int kwsysProcessesAdd(kwsysProcess* cp) +{ + /* Create a pipe through which the signal handler can notify the + given process object that a child has exited. */ + { + /* Create the pipe. */ + int oldfl[2]; + int p[2]; + if(pipe(p) < 0) + { + return 0; + } + + /* Store the pipes now to be sure they are cleaned up later. */ + cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL] = p[0]; + cp->SignalPipe = p[1]; + + /* Switch the pipe to non-blocking mode so that reading a byte can + be an atomic test-and-set. */ + if((oldfl[0] = fcntl(p[0], F_GETFL) < 0) || + (oldfl[1] = fcntl(p[1], F_GETFL) < 0) || + (fcntl(p[0], F_SETFL, oldfl[0] | O_NONBLOCK) < 0) || + (fcntl(p[1], F_SETFL, oldfl[1] | O_NONBLOCK) < 0)) + { + return 0; + } + + /* The children do not need this pipe. Set close-on-exec flag on + the pipe's ends. */ + if((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) || + (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0)) + { + return 0; + } + } + + /* Attempt to add the given signal pipe to the signal handler set. */ + { + + /* Make sure there is enough space for the new signal pipe. */ + kwsysProcessInstances oldProcesses = kwsysProcesses; + kwsysProcessInstances newProcesses = oldProcesses; + if(oldProcesses.Count == oldProcesses.Size) + { + /* Start with enough space for a small number of process instances + and double the size each time more is needed. */ + newProcesses.Size = oldProcesses.Size? oldProcesses.Size*2 : 4; + + /* Try allocating the new block of memory. */ + if((newProcesses.Processes = ((kwsysProcess**) + malloc(newProcesses.Size* + sizeof(kwsysProcess*))))) + { + /* Copy the old pipe set to the new memory. */ + if(oldProcesses.Count > 0) + { + memcpy(newProcesses.Processes, oldProcesses.Processes, + (oldProcesses.Count * sizeof(kwsysProcess*))); + } + } + else + { + /* Failed to allocate memory for the new signal pipe set. */ + return 0; + } + } + + /* Append the new signal pipe to the set. */ + newProcesses.Processes[newProcesses.Count++] = cp; + + /* Store the new set in that seen by the signal handler. */ + kwsysProcessesUpdate(&newProcesses); + + /* Free the original pipes if new ones were allocated. */ + if(newProcesses.Processes != oldProcesses.Processes) + { + free(oldProcesses.Processes); + } + + /* If this is the first process, enable the signal handler. */ + if(newProcesses.Count == 1) + { + /* Install our handler for SIGCHLD. Repeat call until it is not + interrupted. */ + struct sigaction newSigChldAction; + memset(&newSigChldAction, 0, sizeof(struct sigaction)); + newSigChldAction.sa_sigaction = kwsysProcessesSignalHandler; + newSigChldAction.sa_flags = SA_NOCLDSTOP | SA_RESTART | SA_SIGINFO; + while((sigaction(SIGCHLD, &newSigChldAction, + &kwsysProcessesOldSigChldAction) < 0) && + (errno == EINTR)); + } + } + + return 1; +} + +/*--------------------------------------------------------------------------*/ +static void kwsysProcessesRemove(kwsysProcess* cp) +{ + /* Attempt to remove the given signal pipe from the signal handler set. */ + { + /* Find the given process in the set. */ + kwsysProcessInstances newProcesses = kwsysProcesses; + int i; + for(i=0; i < newProcesses.Count; ++i) + { + if(newProcesses.Processes[i] == cp) + { + break; + } + } + if(i < newProcesses.Count) + { + /* Remove the process from the set. */ + --newProcesses.Count; + for(; i < newProcesses.Count; ++i) + { + newProcesses.Processes[i] = newProcesses.Processes[i+1]; + } + + /* If this was the last process, disable the signal handler. */ + if(newProcesses.Count == 0) + { + /* Restore the SIGCHLD handler. Repeat call until it is not + interrupted. */ + while((sigaction(SIGCHLD, &kwsysProcessesOldSigChldAction, 0) < 0) && + (errno == EINTR)); + + /* Free the table of process pointers since it is now empty. + This is safe because the signal handler has been removed. */ + newProcesses.Size = 0; + free(newProcesses.Processes); + newProcesses.Processes = 0; + } + + /* Store the new set in that seen by the signal handler. */ + kwsysProcessesUpdate(&newProcesses); + } + } + + /* Close the pipe through which the signal handler may have notified + the given process object that a child has exited. */ + kwsysProcessCleanupDescriptor(&cp->SignalPipe); +} + +/*--------------------------------------------------------------------------*/ +static void kwsysProcessesSignalHandler(int signum, siginfo_t* info, + void* ucontext) +{ + /* Signal all process objects that a child has terminated. */ + int i; + (void)signum; + (void)info; + (void)ucontext; + for(i=0; i < kwsysProcesses.Count; ++i) + { + /* Set the pipe in a signalled state. */ + char buf = 1; + kwsysProcess* cp = kwsysProcesses.Processes[i]; + read(cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL], &buf, 1); + write(cp->SignalPipe, &buf, 1); + } +} + +/*--------------------------------------------------------------------------*/ +static int kwsysProcessAppendByte(char* local, + char** begin, char** end, + int* size, char c) +{ + /* Allocate space for the character. */ + if((*end - *begin) >= *size) + { + int length = *end - *begin; + char* newBuffer = (char*)malloc(*size*2); + if(!newBuffer) + { + return 0; + } + memcpy(newBuffer, *begin, length*sizeof(char)); + if(*begin != local) + { + free(*begin); + } + *begin = newBuffer; + *end = *begin + length; + *size *= 2; + } + + /* Store the character. */ + *(*end)++ = c; + return 1; +} + +/*--------------------------------------------------------------------------*/ +static int kwsysProcessAppendArgument(char** local, + char*** begin, char*** end, + int* size, + char* arg_local, + char** arg_begin, char** arg_end, + int* arg_size) +{ + /* Append a null-terminator to the argument string. */ + if(!kwsysProcessAppendByte(arg_local, arg_begin, arg_end, arg_size, '\0')) + { + return 0; + } + + /* Allocate space for the argument pointer. */ + if((*end - *begin) >= *size) + { + int length = *end - *begin; + char** newPointers = (char**)malloc(*size*2*sizeof(char*)); + if(!newPointers) + { + return 0; + } + memcpy(newPointers, *begin, length*sizeof(char*)); + if(*begin != local) + { + free(*begin); + } + *begin = newPointers; + *end = *begin + length; + *size *= 2; + } + + /* Allocate space for the argument string. */ + **end = (char*)malloc(*arg_end - *arg_begin); + if(!**end) + { + return 0; + } + + /* Store the argument in the command array. */ + memcpy(**end, *arg_begin, *arg_end - *arg_begin); + ++(*end); + + /* Reset the argument to be empty. */ + *arg_end = *arg_begin; + + return 1; +} + +/*--------------------------------------------------------------------------*/ +#define KWSYSPE_LOCAL_BYTE_COUNT 1024 +#define KWSYSPE_LOCAL_ARGS_COUNT 32 +static char** kwsysProcessParseVerbatimCommand(const char* command) +{ + /* Create a buffer for argument pointers during parsing. */ + char* local_pointers[KWSYSPE_LOCAL_ARGS_COUNT]; + int pointers_size = KWSYSPE_LOCAL_ARGS_COUNT; + char** pointer_begin = local_pointers; + char** pointer_end = pointer_begin; + + /* Create a buffer for argument strings during parsing. */ + char local_buffer[KWSYSPE_LOCAL_BYTE_COUNT]; + int buffer_size = KWSYSPE_LOCAL_BYTE_COUNT; + char* buffer_begin = local_buffer; + char* buffer_end = buffer_begin; + + /* Parse the command string. Try to behave like a UNIX shell. */ + char** newCommand = 0; + const char* c = command; + int in_argument = 0; + int in_escape = 0; + int in_single = 0; + int in_double = 0; + int failed = 0; + for(;*c; ++c) + { + if(in_escape) + { + /* This character is escaped so do no special handling. */ + if(!in_argument) + { + in_argument = 1; + } + if(!kwsysProcessAppendByte(local_buffer, &buffer_begin, + &buffer_end, &buffer_size, *c)) + { + failed = 1; + break; + } + in_escape = 0; + } + else if(*c == '\\' && !in_single) + { + /* The next character should be escaped. */ + in_escape = 1; + } + else if(*c == '\'' && !in_double) + { + /* Enter or exit single-quote state. */ + if(in_single) + { + in_single = 0; + } + else + { + in_single = 1; + if(!in_argument) + { + in_argument = 1; + } + } + } + else if(*c == '"' && !in_single) + { + /* Enter or exit double-quote state. */ + if(in_double) + { + in_double = 0; + } + else + { + in_double = 1; + if(!in_argument) + { + in_argument = 1; + } + } + } + else if(isspace(*c)) + { + if(in_argument) + { + if(in_single || in_double) + { + /* This space belongs to a quoted argument. */ + if(!kwsysProcessAppendByte(local_buffer, &buffer_begin, + &buffer_end, &buffer_size, *c)) + { + failed = 1; + break; + } + } + else + { + /* This argument has been terminated by whitespace. */ + if(!kwsysProcessAppendArgument(local_pointers, &pointer_begin, + &pointer_end, &pointers_size, + local_buffer, &buffer_begin, + &buffer_end, &buffer_size)) + { + failed = 1; + break; + } + in_argument = 0; + } + } + } + else + { + /* This character belong to an argument. */ + if(!in_argument) + { + in_argument = 1; + } + if(!kwsysProcessAppendByte(local_buffer, &buffer_begin, + &buffer_end, &buffer_size, *c)) + { + failed = 1; + break; + } + } + } + + /* Finish the last argument. */ + if(in_argument) + { + if(!kwsysProcessAppendArgument(local_pointers, &pointer_begin, + &pointer_end, &pointers_size, + local_buffer, &buffer_begin, + &buffer_end, &buffer_size)) + { + failed = 1; + } + } + + /* If we still have memory allocate space for the new command + buffer. */ + if(!failed) + { + int n = pointer_end - pointer_begin; + newCommand = (char**)malloc((n+1)*sizeof(char*)); + } + + if(newCommand) + { + /* Copy the arguments into the new command buffer. */ + int n = pointer_end - pointer_begin; + memcpy(newCommand, pointer_begin, sizeof(char*)*n); + newCommand[n] = 0; + } + else + { + /* Free arguments already allocated. */ + while(pointer_end != pointer_begin) + { + free(*(--pointer_end)); + } + } + + /* Free temporary buffers. */ + if(pointer_begin != local_pointers) + { + free(pointer_begin); + } + if(buffer_begin != local_buffer) + { + free(buffer_begin); + } + + /* Return the final command buffer. */ + return newCommand; +} diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c index 97e5706764..6929c3e443 100644 --- a/Source/kwsys/ProcessWin32.c +++ b/Source/kwsys/ProcessWin32.c @@ -104,8 +104,14 @@ static void kwsysProcessDestroy(kwsysProcess* cp, int event); static int kwsysProcessSetupOutputPipeFile(PHANDLE handle, const char* name); static int kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle); static void kwsysProcessCleanupHandle(PHANDLE h); +static void kwsysProcessCleanupHandleSafe(PHANDLE h, DWORD nStdHandle); static void kwsysProcessCleanup(kwsysProcess* cp, int error); static void kwsysProcessCleanErrorMessage(kwsysProcess* cp); +static int kwsysProcessComputeCommandLength(kwsysProcess* cp, + char const* const* command); +static void kwsysProcessComputeCommandLine(kwsysProcess* cp, + char const* const* command, + char* cmd); static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout, kwsysProcessTime* timeoutTime); static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime, @@ -205,6 +211,9 @@ struct kwsysProcess_s /* Whether to hide the child process's window. */ int HideWindow; + /* Whether to treat command lines as verbatim. */ + int Verbatim; + /* On Win9x platforms, the path to the forwarding executable. */ char* Win9x; @@ -645,7 +654,7 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) char** newCommands; /* Make sure we have a command to add. */ - if(!cp || !command) + if(!cp || !command || !*command) { return 0; } @@ -675,66 +684,8 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) because they come before the closing double-quote for the argument. */ { - char* cmd; - char const* const* arg; - int length = 0; /* First determine the length of the final string. */ - for(arg = command; *arg; ++arg) - { - /* Keep track of how many backslashes have been encountered in a - row in this argument. */ - int backslashes = 0; - int spaces = 0; - const char* c; - - /* Scan the string for spaces. If there are no spaces, we can - pass the argument verbatim. */ - for(c=*arg; *c; ++c) - { - if(*c == ' ' || *c == '\t') - { - spaces = 1; - break; - } - } - - /* Add the length of the argument, plus 1 for the space - separating the arguments. */ - length += (int)strlen(*arg) + 1; - - if(spaces) - { - /* Add 2 for double quotes since spaces are present. */ - length += 2; - - /* Scan the string to find characters that need escaping. */ - for(c=*arg; *c; ++c) - { - if(*c == '\\') - { - /* Found a backslash. It may need to be escaped later. */ - ++backslashes; - } - else if(*c == '"') - { - /* Found a double-quote. We need to escape it and all - immediately preceding backslashes. */ - length += backslashes + 1; - backslashes = 0; - } - else - { - /* Found another character. This eliminates the possibility - that any immediately preceding backslashes will be - escaped. */ - backslashes = 0; - } - } - - /* We need to escape all ending backslashes. */ - length += backslashes; - } - } + int length = kwsysProcessComputeCommandLength(cp, command); /* Allocate enough space for the command. We do not need an extra byte for the terminating null because we allocated a space for @@ -748,94 +699,8 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) } /* Construct the command line in the allocated buffer. */ - cmd = newCommands[cp->NumberOfCommands]; - for(arg = command; *arg; ++arg) - { - /* Keep track of how many backslashes have been encountered in a - row in an argument. */ - int backslashes = 0; - int spaces = 0; - const char* c; - - /* Scan the string for spaces. If there are no spaces, we can - pass the argument verbatim. */ - for(c=*arg; *c; ++c) - { - if(*c == ' ' || *c == '\t') - { - spaces = 1; - break; - } - } - - /* Add the separating space if this is not the first argument. */ - if(arg != command) - { - *cmd++ = ' '; - } - - if(spaces) - { - /* Add the opening double-quote for this argument. */ - *cmd++ = '"'; - - /* Add the characters of the argument, possibly escaping them. */ - for(c=*arg; *c; ++c) - { - if(*c == '\\') - { - /* Found a backslash. It may need to be escaped later. */ - ++backslashes; - *cmd++ = '\\'; - } - else if(*c == '"') - { - /* Add enough backslashes to escape any that preceded the - double-quote. */ - while(backslashes > 0) - { - --backslashes; - *cmd++ = '\\'; - } - - /* Add the backslash to escape the double-quote. */ - *cmd++ = '\\'; - - /* Add the double-quote itself. */ - *cmd++ = '"'; - } - else - { - /* We encountered a normal character. This eliminates any - escaping needed for preceding backslashes. Add the - character. */ - backslashes = 0; - *cmd++ = *c; - } - } - - /* Add enough backslashes to escape any trailing ones. */ - while(backslashes > 0) - { - --backslashes; - *cmd++ = '\\'; - } - - /* Add the closing double-quote for this argument. */ - *cmd++ = '"'; - } - else - { - /* No spaces. Add the argument verbatim. */ - for(c=*arg; *c; ++c) - { - *cmd++ = *c; - } - } - } - - /* Add the terminating null character to the command line. */ - *cmd = 0; + kwsysProcessComputeCommandLine(cp, command, + newCommands[cp->NumberOfCommands]); } /* Save the new array of commands. */ @@ -967,6 +832,7 @@ int kwsysProcess_GetOption(kwsysProcess* cp, int optionId) { case kwsysProcess_Option_Detach: return cp->OptionDetach; case kwsysProcess_Option_HideWindow: return cp->HideWindow; + case kwsysProcess_Option_Verbatim: return cp->Verbatim; default: return 0; } } @@ -983,6 +849,7 @@ void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value) { case kwsysProcess_Option_Detach: cp->OptionDetach = value; break; case kwsysProcess_Option_HideWindow: cp->HideWindow = value; break; + case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break; default: break; } } @@ -1145,7 +1012,8 @@ void kwsysProcess_Execute(kwsysProcess* cp) &si.StartupInfo.hStdError)) { kwsysProcessCleanup(cp, 1); - kwsysProcessCleanupHandle(&si.StartupInfo.hStdError); + kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError, + STD_ERROR_HANDLE); return; } } @@ -1166,9 +1034,12 @@ void kwsysProcess_Execute(kwsysProcess* cp) /* Release resources that may have been allocated for this process before an error occurred. */ kwsysProcessCleanupHandle(&readEnd); - kwsysProcessCleanupHandle(&si.StartupInfo.hStdInput); - kwsysProcessCleanupHandle(&si.StartupInfo.hStdOutput); - kwsysProcessCleanupHandle(&si.StartupInfo.hStdError); + kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdInput, + STD_INPUT_HANDLE); + kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdOutput, + STD_OUTPUT_HANDLE); + kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError, + STD_ERROR_HANDLE); kwsysProcessCleanupHandle(&si.ErrorPipeRead); kwsysProcessCleanupHandle(&si.ErrorPipeWrite); return; @@ -1183,7 +1054,7 @@ void kwsysProcess_Execute(kwsysProcess* cp) processes in the pipeline. The stdout and stdin pipes are not shared among all children and are therefore closed by kwsysProcessCreate after each child is created. */ - kwsysProcessCleanupHandle(&si.StartupInfo.hStdError); + kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError, STD_ERROR_HANDLE); /* Restore the working directory. */ if(cp->RealWorkingDirectory) @@ -1493,7 +1364,7 @@ void kwsysProcess_Kill(kwsysProcess* cp) /* Make sure we are executing a process. */ if(!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired || - cp->Killed || cp->Terminated) + cp->Killed) { return; } @@ -1501,6 +1372,12 @@ void kwsysProcess_Kill(kwsysProcess* cp) /* Disable the reading threads. */ kwsysProcessDisablePipeThreads(cp); + /* Skip actually killing the child if it has already terminated. */ + if(cp->Terminated) + { + return; + } + /* Kill the children. */ cp->Killed = 1; if(cp->Win9x) @@ -1897,8 +1774,10 @@ int kwsysProcessCreate(kwsysProcess* cp, int index, process's copies of the inherited stdout and stdin handles. The stderr handle is shared among all children and is closed by kwsysProcess_Execute after all children have been created. */ - kwsysProcessCleanupHandle(&si->StartupInfo.hStdInput); - kwsysProcessCleanupHandle(&si->StartupInfo.hStdOutput); + kwsysProcessCleanupHandleSafe(&si->StartupInfo.hStdInput, + STD_INPUT_HANDLE); + kwsysProcessCleanupHandleSafe(&si->StartupInfo.hStdOutput, + STD_OUTPUT_HANDLE); return 1; } @@ -1984,13 +1863,27 @@ int kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name) /*--------------------------------------------------------------------------*/ int kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle) { + /* Check whether the handle to be shared is already inherited. */ + DWORD flags; + int inherited = 0; + if(GetHandleInformation(GetStdHandle(nStdHandle), &flags) && + (flags & HANDLE_FLAG_INHERIT)) + { + inherited = 1; + } + /* Cleanup the previous handle. */ kwsysProcessCleanupHandle(handle); - /* Duplicate the standard handle to be sure it is inherited and can - be closed later. Do not close the original handle when + /* If the standard handle is not inherited then duplicate it to + create an inherited copy. Do not close the original handle when duplicating! */ - if(DuplicateHandle(GetCurrentProcess(), GetStdHandle(nStdHandle), + if(inherited) + { + *handle = GetStdHandle(nStdHandle); + return 1; + } + else if(DuplicateHandle(GetCurrentProcess(), GetStdHandle(nStdHandle), GetCurrentProcess(), handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) { @@ -2046,6 +1939,19 @@ void kwsysProcessCleanupHandle(PHANDLE h) /*--------------------------------------------------------------------------*/ +/* Close the given handle if it is open and not a standard handle. + Reset its value to 0. */ +void kwsysProcessCleanupHandleSafe(PHANDLE h, DWORD nStdHandle) +{ + if(h && *h && (*h != GetStdHandle(nStdHandle))) + { + CloseHandle(*h); + *h = 0; + } +} + +/*--------------------------------------------------------------------------*/ + /* Close all handles created by kwsysProcess_Execute. */ void kwsysProcessCleanup(kwsysProcess* cp, int error) { @@ -2159,6 +2065,189 @@ void kwsysProcessCleanErrorMessage(kwsysProcess* cp) } /*--------------------------------------------------------------------------*/ +int kwsysProcessComputeCommandLength(kwsysProcess* cp, + char const* const* command) +{ + int length = 0; + if(cp->Verbatim) + { + /* Treat the first argument as a verbatim command line. Use its + length directly and add space for the null-terminator. */ + length = (int)strlen(*command)+1; + } + else + { + /* Compute the length of the command line when it is converted to + a single string. Space for the null-terminator is allocated by + the whitespace character allocated for the first argument that + will not be used. */ + char const* const* arg; + for(arg = command; *arg; ++arg) + { + /* Keep track of how many backslashes have been encountered in a + row in this argument. */ + int backslashes = 0; + int spaces = 0; + const char* c; + + /* Scan the string for spaces. If there are no spaces, we can + pass the argument verbatim. */ + for(c=*arg; *c; ++c) + { + if(*c == ' ' || *c == '\t') + { + spaces = 1; + break; + } + } + + /* Add the length of the argument, plus 1 for the space + separating the arguments. */ + length += (int)strlen(*arg) + 1; + + if(spaces) + { + /* Add 2 for double quotes since spaces are present. */ + length += 2; + + /* Scan the string to find characters that need escaping. */ + for(c=*arg; *c; ++c) + { + if(*c == '\\') + { + /* Found a backslash. It may need to be escaped later. */ + ++backslashes; + } + else if(*c == '"') + { + /* Found a double-quote. We need to escape it and all + immediately preceding backslashes. */ + length += backslashes + 1; + backslashes = 0; + } + else + { + /* Found another character. This eliminates the possibility + that any immediately preceding backslashes will be + escaped. */ + backslashes = 0; + } + } + + /* We need to escape all ending backslashes. */ + length += backslashes; + } + } + } + + return length; +} + +/*--------------------------------------------------------------------------*/ +void kwsysProcessComputeCommandLine(kwsysProcess* cp, + char const* const* command, + char* cmd) +{ + if(cp->Verbatim) + { + /* Copy the verbatim command line into the buffer. */ + strcpy(cmd, *command); + } + else + { + /* Construct the command line in the allocated buffer. */ + char const* const* arg; + for(arg = command; *arg; ++arg) + { + /* Keep track of how many backslashes have been encountered in a + row in an argument. */ + int backslashes = 0; + int spaces = 0; + const char* c; + + /* Scan the string for spaces. If there are no spaces, we can + pass the argument verbatim. */ + for(c=*arg; *c; ++c) + { + if(*c == ' ' || *c == '\t') + { + spaces = 1; + break; + } + } + + /* Add the separating space if this is not the first argument. */ + if(arg != command) + { + *cmd++ = ' '; + } + + if(spaces) + { + /* Add the opening double-quote for this argument. */ + *cmd++ = '"'; + + /* Add the characters of the argument, possibly escaping them. */ + for(c=*arg; *c; ++c) + { + if(*c == '\\') + { + /* Found a backslash. It may need to be escaped later. */ + ++backslashes; + *cmd++ = '\\'; + } + else if(*c == '"') + { + /* Add enough backslashes to escape any that preceded the + double-quote. */ + while(backslashes > 0) + { + --backslashes; + *cmd++ = '\\'; + } + + /* Add the backslash to escape the double-quote. */ + *cmd++ = '\\'; + + /* Add the double-quote itself. */ + *cmd++ = '"'; + } + else + { + /* We encountered a normal character. This eliminates any + escaping needed for preceding backslashes. Add the + character. */ + backslashes = 0; + *cmd++ = *c; + } + } + + /* Add enough backslashes to escape any trailing ones. */ + while(backslashes > 0) + { + --backslashes; + *cmd++ = '\\'; + } + + /* Add the closing double-quote for this argument. */ + *cmd++ = '"'; + } + else + { + /* No spaces. Add the argument verbatim. */ + for(c=*arg; *c; ++c) + { + *cmd++ = *c; + } + } + } + + /* Add the terminating null character to the command line. */ + *cmd = 0; + } +} + +/*--------------------------------------------------------------------------*/ /* Get the time at which either the process or user timeout will expire. Returns 1 if the user timeout is first, and 0 otherwise. */ int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout, diff --git a/Source/kwsys/Terminal.c b/Source/kwsys/Terminal.c index 0837e10323..e3265a1280 100644 --- a/Source/kwsys/Terminal.c +++ b/Source/kwsys/Terminal.c @@ -142,10 +142,13 @@ static const char* kwsysTerminalVT100Names[] = "con80x50", "con80x60", "console", + "cygwin", "konsole", "linux", "msys", "rxvt", + "rxvt-unicode", + "screen", "vt100", "xterm", "xterm-color", diff --git a/Source/kwsys/kwsysPlatformCxxTests.cmake b/Source/kwsys/kwsysPlatformCxxTests.cmake index 6da82d6cbf..777545736c 100644 --- a/Source/kwsys/kwsysPlatformCxxTests.cmake +++ b/Source/kwsys/kwsysPlatformCxxTests.cmake @@ -7,10 +7,12 @@ MACRO(KWSYS_PLATFORM_CXX_TEST var description invert) COMPILE_DEFINITIONS -DTEST_${var} ${KWSYS_PLATFORM_CXX_TEST_DEFINES} OUTPUT_VARIABLE OUTPUT) IF(${var}_COMPILED) - FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND + ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "${description} compiled with the following output:\n${OUTPUT}\n\n") ELSE(${var}_COMPILED) - FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND + ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "${description} failed to compile with the following output:\n${OUTPUT}\n\n") ENDIF(${var}_COMPILED) IF(${invert} MATCHES INVERT) diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c index 36222b929e..57802b2ad7 100644 --- a/Source/kwsys/testProcess.c +++ b/Source/kwsys/testProcess.c @@ -32,7 +32,7 @@ int runChild(const char* cmd[], int state, int exception, int value, int share, int output, int delay, double timeout, int poll, - int repeat); + int repeat, int disown); int test1(int argc, const char* argv[]) { @@ -84,14 +84,6 @@ int test4(int argc, const char* argv[]) return 0; } -/* Quick hack to test grandchild killing. */ -/*#define TEST5_GRANDCHILD_KILL*/ -#ifdef TEST5_GRANDCHILD_KILL -# define TEST5_TIMEOUT 10 -#else -# define TEST5_TIMEOUT 30 -#endif - int test5(int argc, const char* argv[]) { int r; @@ -99,18 +91,14 @@ int test5(int argc, const char* argv[]) (void)argc; cmd[0] = argv[0]; cmd[1] = "run"; -#ifdef TEST5_GRANDCHILD_KILL - cmd[2] = "3"; -#else cmd[2] = "4"; -#endif cmd[3] = 0; fprintf(stdout, "Output on stdout before recursive test.\n"); fprintf(stderr, "Output on stderr before recursive test.\n"); fflush(stdout); fflush(stderr); r = runChild(cmd, kwsysProcess_State_Exception, - kwsysProcess_Exception_Fault, 1, 1, 1, 0, 15, 0, 1); + kwsysProcess_Exception_Fault, 1, 1, 1, 0, 15, 0, 1, 0); fprintf(stdout, "Output on stdout after recursive test.\n"); fprintf(stderr, "Output on stderr after recursive test.\n"); fflush(stdout); @@ -163,10 +151,56 @@ int test7(int argc, const char* argv[]) return 0; } +int test8(int argc, const char* argv[]) +{ + /* Create a disowned grandchild to test handling of processes + that exit before their children. */ + int r; + const char* cmd[4]; + (void)argc; + cmd[0] = argv[0]; + cmd[1] = "run"; + cmd[2] = "108"; + cmd[3] = 0; + fprintf(stdout, "Output on stdout before grandchild test.\n"); + fprintf(stderr, "Output on stderr before grandchild test.\n"); + fflush(stdout); + fflush(stderr); + r = runChild(cmd, kwsysProcess_State_Disowned, kwsysProcess_Exception_None, + 1, 1, 1, 0, 10, 0, 1, 1); + fprintf(stdout, "Output on stdout after grandchild test.\n"); + fprintf(stderr, "Output on stderr after grandchild test.\n"); + fflush(stdout); + fflush(stderr); + return r; +} + +int test8_grandchild(int argc, const char* argv[]) +{ + (void)argc; (void)argv; + fprintf(stdout, "Output on stdout from grandchild before sleep.\n"); + fprintf(stderr, "Output on stderr from grandchild before sleep.\n"); + fflush(stdout); + fflush(stderr); + /* TODO: Instead of closing pipes here leave them open to make sure + the grandparent can stop listening when the parent exits. This + part of the test cannot be enabled until the feature is + implemented. */ + fclose(stdout); + fclose(stderr); +#if defined(_WIN32) + Sleep(15000); +#else + sleep(15); +#endif + return 0; +} + + int runChild2(kwsysProcess* kp, const char* cmd[], int state, int exception, int value, int share, int output, int delay, double timeout, - int poll) + int poll, int disown) { int result = 0; char* data = 0; @@ -183,6 +217,10 @@ int runChild2(kwsysProcess* kp, kwsysProcess_SetPipeShared(kp, kwsysProcess_Pipe_STDOUT, 1); kwsysProcess_SetPipeShared(kp, kwsysProcess_Pipe_STDERR, 1); } + if(disown) + { + kwsysProcess_SetOption(kp, kwsysProcess_Option_Detach, 1); + } kwsysProcess_Execute(kp); if(poll) @@ -190,7 +228,7 @@ int runChild2(kwsysProcess* kp, pUserTimeout = &userTimeout; } - if(!share) + if(!share && !disown) { int p; while((p = kwsysProcess_WaitForData(kp, &data, &length, pUserTimeout))) @@ -236,7 +274,14 @@ int runChild2(kwsysProcess* kp, } } + if(disown) + { + kwsysProcess_Disown(kp); + } + else + { kwsysProcess_WaitForExit(kp, 0); + } switch (kwsysProcess_GetState(kp)) { @@ -258,6 +303,8 @@ int runChild2(kwsysProcess* kp, kwsysProcess_GetExceptionString(kp)); result = ((exception != kwsysProcess_GetExitException(kp)) || (value != kwsysProcess_GetExitValue(kp))); break; + case kwsysProcess_State_Disowned: + printf("Child was disowned.\n"); break; case kwsysProcess_State_Error: printf("Error in administrating child process: [%s]\n", kwsysProcess_GetErrorString(kp)); break; @@ -301,7 +348,7 @@ int runChild2(kwsysProcess* kp, int runChild(const char* cmd[], int state, int exception, int value, int share, int output, int delay, double timeout, - int poll, int repeat) + int poll, int repeat, int disown) { int result = 1; kwsysProcess* kp = kwsysProcess_New(); @@ -313,7 +360,7 @@ int runChild(const char* cmd[], int state, int exception, int value, while(repeat-- > 0) { result = runChild2(kp, cmd, state, exception, value, share, - output, delay, timeout, poll); + output, delay, timeout, poll, disown); } kwsysProcess_Delete(kp); return result; @@ -347,7 +394,7 @@ int main(int argc, const char* argv[]) n = atoi(argv[2]); } /* Check arguments. */ - if(n >= 1 && n <= 7 && argc == 3) + if(((n >= 1 && n <= 8) || n == 108) && argc == 3) { /* This is the child process for a requested test number. */ switch (n) @@ -359,14 +406,16 @@ int main(int argc, const char* argv[]) case 5: return test5(argc, argv); case 6: test6(argc, argv); return 0; case 7: return test7(argc, argv); + case 8: return test8(argc, argv); + case 108: return test8_grandchild(argc, argv); } fprintf(stderr, "Invalid test number %d.\n", n); return 1; } - else if(n >= 1 && n <= 7) + else if(n >= 1 && n <= 8) { /* This is the parent process for a requested test number. */ - int states[7] = + int states[8] = { kwsysProcess_State_Exited, kwsysProcess_State_Exited, @@ -374,9 +423,10 @@ int main(int argc, const char* argv[]) kwsysProcess_State_Exception, kwsysProcess_State_Exited, kwsysProcess_State_Expired, + kwsysProcess_State_Exited, kwsysProcess_State_Exited }; - int exceptions[7] = + int exceptions[8] = { kwsysProcess_Exception_None, kwsysProcess_Exception_None, @@ -384,14 +434,15 @@ int main(int argc, const char* argv[]) kwsysProcess_Exception_Fault, kwsysProcess_Exception_None, kwsysProcess_Exception_None, + kwsysProcess_Exception_None, kwsysProcess_Exception_None }; - int values[7] = {0, 123, 1, 1, 0, 0, 0}; - int outputs[7] = {1, 1, 1, 1, 1, 0, 1}; - int delays[7] = {0, 0, 0, 0, 0, 1, 0}; - double timeouts[7] = {10, 10, 10, 10, TEST5_TIMEOUT, 10, -1}; - int polls[7] = {0, 0, 0, 0, 0, 0, 1}; - int repeat[7] = {2, 1, 1, 1, 1, 1, 1}; + int values[8] = {0, 123, 1, 1, 0, 0, 0, 0}; + int outputs[8] = {1, 1, 1, 1, 1, 0, 1, 1}; + int delays[8] = {0, 0, 0, 0, 0, 1, 0, 0}; + double timeouts[8] = {10, 10, 10, 10, 30, 10, -1, 10}; + int polls[8] = {0, 0, 0, 0, 0, 0, 1, 0}; + int repeat[8] = {2, 1, 1, 1, 1, 1, 1, 1}; int r; const char* cmd[4]; #ifdef _WIN32 @@ -425,7 +476,7 @@ int main(int argc, const char* argv[]) fflush(stderr); r = runChild(cmd, states[n-1], exceptions[n-1], values[n-1], 0, outputs[n-1], delays[n-1], timeouts[n-1], - polls[n-1], repeat[n-1]); + polls[n-1], repeat[n-1], 0); fprintf(stdout, "Output on stdout after test %d.\n", n); fprintf(stderr, "Output on stderr after test %d.\n", n); fflush(stdout); @@ -444,7 +495,7 @@ int main(int argc, const char* argv[]) int exception = kwsysProcess_Exception_None; int value = 0; double timeout = 0; - int r = runChild(cmd, state, exception, value, 0, 1, 0, timeout, 0, 1); + int r = runChild(cmd, state, exception, value, 0, 1, 0, timeout, 0, 1, 0); return r; } else diff --git a/Tests/Complex/Executable/CMakeLists.txt b/Tests/Complex/Executable/CMakeLists.txt index 6a217f03c7..dae57753e2 100644 --- a/Tests/Complex/Executable/CMakeLists.txt +++ b/Tests/Complex/Executable/CMakeLists.txt @@ -55,6 +55,14 @@ IF ("${LF_VALUE}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt;${CMAKE_C ADD_DEFINITIONS(-DCMAKE_FOUND_LISTFILE_STACK) ENDIF ("${LF_VALUE}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt;${CMAKE_CURRENT_SOURCE_DIR}/Included.cmake") +# Test add/remove definitions. +ADD_DEFINITIONS( + -DCOMPLEX_DEFINED_PRE + -DCOMPLEX_DEFINED + -DCOMPLEX_DEFINED_POST + -DCOMPLEX_DEFINED + ) +REMOVE_DEFINITIONS(-DCOMPLEX_DEFINED) # Test pre-build/pre-link/post-build rules for an executable. ADD_CUSTOM_COMMAND(TARGET complex PRE_BUILD diff --git a/Tests/Complex/Executable/complex.cxx b/Tests/Complex/Executable/complex.cxx index a80487b9fb..816414c7cc 100644 --- a/Tests/Complex/Executable/complex.cxx +++ b/Tests/Complex/Executable/complex.cxx @@ -42,6 +42,18 @@ void cmPassed(const char* Message, const char* m2="") cm_passed++; } +#ifndef COMPLEX_DEFINED_PRE +# error "COMPLEX_DEFINED_PRE not defined!" +#endif + +#ifdef COMPLEX_DEFINED +# error "COMPLEX_DEFINED is defined but it should not!" +#endif + +#ifndef COMPLEX_DEFINED_POST +# error "COMPLEX_DEFINED_POST not defined!" +#endif + #ifndef CMAKE_IS_REALLY_FUN This is a problem. Looks like ADD_DEFINITIONS and REMOVE_DEFINITIONS does not work #endif diff --git a/Tests/ComplexOneConfig/Executable/CMakeLists.txt b/Tests/ComplexOneConfig/Executable/CMakeLists.txt index 6a217f03c7..dae57753e2 100644 --- a/Tests/ComplexOneConfig/Executable/CMakeLists.txt +++ b/Tests/ComplexOneConfig/Executable/CMakeLists.txt @@ -55,6 +55,14 @@ IF ("${LF_VALUE}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt;${CMAKE_C ADD_DEFINITIONS(-DCMAKE_FOUND_LISTFILE_STACK) ENDIF ("${LF_VALUE}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt;${CMAKE_CURRENT_SOURCE_DIR}/Included.cmake") +# Test add/remove definitions. +ADD_DEFINITIONS( + -DCOMPLEX_DEFINED_PRE + -DCOMPLEX_DEFINED + -DCOMPLEX_DEFINED_POST + -DCOMPLEX_DEFINED + ) +REMOVE_DEFINITIONS(-DCOMPLEX_DEFINED) # Test pre-build/pre-link/post-build rules for an executable. ADD_CUSTOM_COMMAND(TARGET complex PRE_BUILD diff --git a/Tests/ComplexOneConfig/Executable/complex.cxx b/Tests/ComplexOneConfig/Executable/complex.cxx index a80487b9fb..816414c7cc 100644 --- a/Tests/ComplexOneConfig/Executable/complex.cxx +++ b/Tests/ComplexOneConfig/Executable/complex.cxx @@ -42,6 +42,18 @@ void cmPassed(const char* Message, const char* m2="") cm_passed++; } +#ifndef COMPLEX_DEFINED_PRE +# error "COMPLEX_DEFINED_PRE not defined!" +#endif + +#ifdef COMPLEX_DEFINED +# error "COMPLEX_DEFINED is defined but it should not!" +#endif + +#ifndef COMPLEX_DEFINED_POST +# error "COMPLEX_DEFINED_POST not defined!" +#endif + #ifndef CMAKE_IS_REALLY_FUN This is a problem. Looks like ADD_DEFINITIONS and REMOVE_DEFINITIONS does not work #endif diff --git a/Tests/ComplexRelativePaths/Executable/CMakeLists.txt b/Tests/ComplexRelativePaths/Executable/CMakeLists.txt index 6a217f03c7..dae57753e2 100644 --- a/Tests/ComplexRelativePaths/Executable/CMakeLists.txt +++ b/Tests/ComplexRelativePaths/Executable/CMakeLists.txt @@ -55,6 +55,14 @@ IF ("${LF_VALUE}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt;${CMAKE_C ADD_DEFINITIONS(-DCMAKE_FOUND_LISTFILE_STACK) ENDIF ("${LF_VALUE}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt;${CMAKE_CURRENT_SOURCE_DIR}/Included.cmake") +# Test add/remove definitions. +ADD_DEFINITIONS( + -DCOMPLEX_DEFINED_PRE + -DCOMPLEX_DEFINED + -DCOMPLEX_DEFINED_POST + -DCOMPLEX_DEFINED + ) +REMOVE_DEFINITIONS(-DCOMPLEX_DEFINED) # Test pre-build/pre-link/post-build rules for an executable. ADD_CUSTOM_COMMAND(TARGET complex PRE_BUILD diff --git a/Tests/ComplexRelativePaths/Executable/complex.cxx b/Tests/ComplexRelativePaths/Executable/complex.cxx index a80487b9fb..816414c7cc 100644 --- a/Tests/ComplexRelativePaths/Executable/complex.cxx +++ b/Tests/ComplexRelativePaths/Executable/complex.cxx @@ -42,6 +42,18 @@ void cmPassed(const char* Message, const char* m2="") cm_passed++; } +#ifndef COMPLEX_DEFINED_PRE +# error "COMPLEX_DEFINED_PRE not defined!" +#endif + +#ifdef COMPLEX_DEFINED +# error "COMPLEX_DEFINED is defined but it should not!" +#endif + +#ifndef COMPLEX_DEFINED_POST +# error "COMPLEX_DEFINED_POST not defined!" +#endif + #ifndef CMAKE_IS_REALLY_FUN This is a problem. Looks like ADD_DEFINITIONS and REMOVE_DEFINITIONS does not work #endif diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index 97c4d812aa..2fb4725dae 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -131,22 +131,31 @@ ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/foo.c ${PROJECT_BINARY_DIR}/foo.c ) -# These object dependencies can be removed to test the -# auto-object-depends feature of the Makefile generator. Currently -# the feature does not seem to work in Visual Studio generators so -# these dependencies are needed. -#SET_SOURCE_FILES_PROPERTIES(${PROJECT_BINARY_DIR}/foo.c -#PROPERTIES -# OBJECT_DEPENDS "${PROJECT_BINARY_DIR}/doc1.h;${PROJECT_BINARY_DIR}/foo.h" -#) - -# add the library +# Add custom command to generate not_included.h, which is a header +# file that is not included by any source in this project. This will +# test whether all custom command outputs explicitly listed as sources +# get generated even if they are not needed by an object file. +ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/not_included.h + DEPENDS ${PROJECT_SOURCE_DIR}/foo.h.in + COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/foo.h.in + ${PROJECT_BINARY_DIR}/not_included.h + ) + +# Tell the executable where to find not_included.h. +CONFIGURE_FILE( + ${PROJECT_SOURCE_DIR}/config.h.in + ${PROJECT_BINARY_DIR}/config.h + @ONLY IMMEDIATE + ) + +# add the executable ADD_EXECUTABLE(CustomCommand ${PROJECT_BINARY_DIR}/foo.h ${PROJECT_BINARY_DIR}/foo.c ${PROJECT_BINARY_DIR}/wrapped.c ${PROJECT_BINARY_DIR}/wrapped_help.c ${PROJECT_BINARY_DIR}/generated.c + ${PROJECT_BINARY_DIR}/not_included.h ) TARGET_LINK_LIBRARIES(CustomCommand GeneratedHeader) diff --git a/Tests/CustomCommand/config.h.in b/Tests/CustomCommand/config.h.in new file mode 100644 index 0000000000..86c97bd959 --- /dev/null +++ b/Tests/CustomCommand/config.h.in @@ -0,0 +1 @@ +#define PROJECT_BINARY_DIR "@PROJECT_BINARY_DIR@" diff --git a/Tests/CustomCommand/foo.in b/Tests/CustomCommand/foo.in index 62b04b20b9..308505b4fb 100644 --- a/Tests/CustomCommand/foo.in +++ b/Tests/CustomCommand/foo.in @@ -1,5 +1,8 @@ #include "doc1.h" #include "foo.h" +#include "config.h" + +#include <stdio.h> int generated(); int wrapped(); @@ -8,7 +11,16 @@ int main () { if (generated()*wrapped()*doc() == 3*5*7) { + FILE* fin = fopen(PROJECT_BINARY_DIR "/not_included.h", "r"); + if(fin) + { + fclose(fin); return 0; + } + else + { + return -2; + } } return -1; diff --git a/Tests/MakeClean/ToClean/CMakeLists.txt b/Tests/MakeClean/ToClean/CMakeLists.txt index 5703f2e874..05ea15cc0e 100644 --- a/Tests/MakeClean/ToClean/CMakeLists.txt +++ b/Tests/MakeClean/ToClean/CMakeLists.txt @@ -6,7 +6,7 @@ ADD_EXECUTABLE(toclean toclean.cxx) # List some build-time-generated files. GET_TARGET_PROPERTY(TOCLEAN_FILES toclean LOCATION) SET(TOCLEAN_FILES ${TOCLEAN_FILES} - "${ToClean_BINARY_DIR}/CMakeFiles/toclean.dir/toclean${CMAKE_CXX_OUTPUT_EXTENSION}") + "${ToClean_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/toclean.dir/toclean${CMAKE_CXX_OUTPUT_EXTENSION}") # Create a file that must be registered for cleaning. FILE(WRITE "${ToClean_BINARY_DIR}/Registered.txt" diff --git a/Tests/TryCompile/CMakeLists.txt b/Tests/TryCompile/CMakeLists.txt index 7ea918dbc3..f2c6bc44c3 100644 --- a/Tests/TryCompile/CMakeLists.txt +++ b/Tests/TryCompile/CMakeLists.txt @@ -2,7 +2,7 @@ PROJECT(TryCompile) # try to compile a file that should compile TRY_COMPILE(SHOULD_PASS - ${TryCompile_BINARY_DIR}/CMakeFiles/CMakeTmp + ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp ${TryCompile_SOURCE_DIR}/pass.c OUTPUT_VARIABLE TRY_OUT) IF(NOT SHOULD_PASS) @@ -11,7 +11,7 @@ ENDIF(NOT SHOULD_PASS) # try to compile a file that should not compile TRY_COMPILE(SHOULD_FAIL - ${TryCompile_BINARY_DIR}/CMakeFiles/CMakeTmp + ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp ${TryCompile_SOURCE_DIR}/fail.c OUTPUT_VARIABLE TRY_OUT) IF(SHOULD_FAIL) @@ -20,7 +20,7 @@ ENDIF(SHOULD_FAIL) # try to compile a file that should compile TRY_COMPILE(SHOULD_PASS - ${TryCompile_BINARY_DIR}/CMakeFiles/CMakeTmp + ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp ${TryCompile_SOURCE_DIR}/pass.c OUTPUT_VARIABLE TRY_OUT) IF(NOT SHOULD_PASS) @@ -29,7 +29,7 @@ ENDIF(NOT SHOULD_PASS) # try to compile a file that should not compile TRY_COMPILE(SHOULD_FAIL - ${TryCompile_BINARY_DIR}/CMakeFiles/CMakeTmp + ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp ${TryCompile_SOURCE_DIR}/fail.c OUTPUT_VARIABLE TRY_OUT) IF(SHOULD_FAIL) @@ -46,7 +46,7 @@ ELSE(NOT SHOULD_FAIL) MESSAGE("Test failed") ENDIF(NOT SHOULD_FAIL) TRY_COMPILE(CMAKE_ANSI_FOR_SCOPE - ${TryCompile_BINARY_DIR}/CMakeFiles/CMakeTmp + ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp ${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx OUTPUT_VARIABLE OUT) IF (CMAKE_ANSI_FOR_SCOPE) MESSAGE("Compiler supports ansi for") @@ -55,7 +55,7 @@ ELSE(CMAKE_ANSI_FOR_SCOPE) ENDIF(CMAKE_ANSI_FOR_SCOPE) TRY_COMPILE(CMAKE_ANSI_FOR_SCOPE - ${TryCompile_BINARY_DIR}/CMakeFiles/CMakeTmp + ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp ${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx OUTPUT_VARIABLE OUT) IF (CMAKE_ANSI_FOR_SCOPE) MESSAGE("Compiler supports ansi for") diff --git a/Tests/Wrapping/Wrap.c b/Tests/Wrapping/Wrap.c index 5b47c960ea..0a1ff501e8 100644 --- a/Tests/Wrapping/Wrap.c +++ b/Tests/Wrapping/Wrap.c @@ -1,7 +1,23 @@ #include <stdio.h> -int main() +#ifdef __CLASSIC_C__ +int main(argc, argv) + int argc; + char ** argv; +#else +int main(int argc, const char* argv[]) +#endif { - printf("Hello\n"); + FILE* fout = fopen(argv[argc-1], "w"); + printf("Wrap creating \"%s\"\n", argv[argc-1]); + if(fout) + { + fprintf(fout, "int foo() { return 0; }\n"); + fclose(fout); + } + else + { + return -1; + } return 0; } diff --git a/Tests/Wrapping/fakefluid.cxx b/Tests/Wrapping/fakefluid.cxx index 25c6e93a0a..6e71eab851 100644 --- a/Tests/Wrapping/fakefluid.cxx +++ b/Tests/Wrapping/fakefluid.cxx @@ -4,8 +4,10 @@ int main(int ac, char** av) { for(int i =0; i < ac; ++i) { - if(strcmp(av[i], "-o") == 0) + if(strcmp(av[i], "-o") == 0 || + strcmp(av[i], "-h") == 0) { + fprintf(stdout, "fakefluid is creating file \"%s\"\n", av[i+1]); FILE* file = fopen(av[i+1], "w"); fprintf(file, "// hello\n"); fclose(file); diff --git a/Utilities/cmcurl/CMake/CheckTypeSize.cmake b/Utilities/cmcurl/CMake/CheckTypeSize.cmake index 700a54d78d..e573d5b640 100644 --- a/Utilities/cmcurl/CMake/CheckTypeSize.cmake +++ b/Utilities/cmcurl/CMake/CheckTypeSize.cmake @@ -22,9 +22,12 @@ MACRO(CHECK_TYPE_SIZE TYPE VARIABLE) FOREACH(def ${CMAKE_EXTRA_INCLUDE_FILES}) SET(CHECK_TYPE_SIZE_PREMAIN "${CHECK_TYPE_SIZE_PREMAIN}#include \"${def}\"\n") ENDFOREACH(def) - CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/CMake/CheckTypeSize.c.in" - "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckTypeSize.c" IMMEDIATE @ONLY) - FILE(READ "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckTypeSize.c" + CONFIGURE_FILE( + "${CMAKE_CURRENT_SOURCE_DIR}/CMake/CheckTypeSize.c.in" + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c" + IMMEDIATE @ONLY) + FILE(READ + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c" CHECK_TYPE_SIZE_FILE_CONTENT) MESSAGE(STATUS "Check size of ${TYPE}") IF(CMAKE_REQUIRED_LIBRARIES) @@ -33,17 +36,17 @@ MACRO(CHECK_TYPE_SIZE TYPE VARIABLE) ENDIF(CMAKE_REQUIRED_LIBRARIES) TRY_RUN(${VARIABLE} HAVE_${VARIABLE} ${CMAKE_BINARY_DIR} - "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckTypeSize.c" + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c" CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_TYPE_SIZE_FLAGS} "${CHECK_TYPE_SIZE_ADD_LIBRARIES}" OUTPUT_VARIABLE OUTPUT) IF(HAVE_${VARIABLE}) MESSAGE(STATUS "Check size of ${TYPE} - done") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining size of ${TYPE} passed with the following output:\n${OUTPUT}\n\n") ELSE(HAVE_${VARIABLE}) MESSAGE(STATUS "Check size of ${TYPE} - failed") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining size of ${TYPE} failed with the following output:\n${OUTPUT}\nCheckTypeSize.c:\n${CHECK_TYPE_SIZE_FILE_CONTENT}\n\n") ENDIF(HAVE_${VARIABLE}) ENDIF("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$") diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt index 6cec6712be..72c157d4f4 100644 --- a/Utilities/cmcurl/CMakeLists.txt +++ b/Utilities/cmcurl/CMakeLists.txt @@ -383,7 +383,7 @@ MACRO(CURL_INTERNAL_TEST CURL_TEST) ELSE(${CURL_TEST}) MESSAGE(STATUS "Performing Curl Test ${CURL_TEST} - Failed") SET(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}") - FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Performing Curl Test ${CURL_TEST} failed with the following output:\n" "${OUTPUT}\n") ENDIF(${CURL_TEST}) @@ -411,14 +411,15 @@ MACRO(CURL_INTERNAL_TEST_RUN CURL_TEST) ELSE(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST}) MESSAGE(STATUS "Performing Curl Test ${CURL_TEST} - Failed") SET(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}") - FILE(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log" + FILE(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log" "Performing Curl Test ${CURL_TEST} failed with the following output:\n" "${OUTPUT}") IF(${CURL_TEST}_COMPILE) - FILE(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log" + FILE(APPEND + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log" "There was a running problem of this test\n") ENDIF(${CURL_TEST}_COMPILE) - FILE(APPEND "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log" + FILE(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log" "\n\n") ENDIF(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST}) ENDIF("${CURL_TEST}_COMPILE" MATCHES "^${CURL_TEST}_COMPILE$") diff --git a/Utilities/cmcurl/mprintf.c b/Utilities/cmcurl/mprintf.c index 12d12084d6..2bb973254e 100644 --- a/Utilities/cmcurl/mprintf.c +++ b/Utilities/cmcurl/mprintf.c @@ -1134,7 +1134,7 @@ int curl_msprintf(char *buffer, const char *format, ...) return retcode; } -#if !defined( WIN32) || defined(__UCLIBC__) /* not needed on win32 */ +#if !(defined( WIN32) || defined(__UCLIBC__)) /* not needed on win32 */ extern int fputc(int, FILE *); #endif diff --git a/Utilities/cmtar/CMakeLists.txt b/Utilities/cmtar/CMakeLists.txt index 3ef4100619..1c3b470502 100644 --- a/Utilities/cmtar/CMakeLists.txt +++ b/Utilities/cmtar/CMakeLists.txt @@ -67,6 +67,7 @@ FOREACH(file "ctype.h" "fnmatch.h" "inttypes.h" + "io.h" "libgen.h" "memory.h" "sys/mkdev.h" diff --git a/Utilities/cmtar/append.c b/Utilities/cmtar/append.c index 6b746ea9a2..38e829451d 100644 --- a/Utilities/cmtar/append.c +++ b/Utilities/cmtar/append.c @@ -31,8 +31,9 @@ #ifdef HAVE_UNISTD_H # include <unistd.h> #endif -#ifdef _MSC_VER -#include <io.h> + +#ifdef HAVE_IO_H +# include <io.h> #endif struct tar_dev diff --git a/Utilities/cmtar/compat/fnmatch.c b/Utilities/cmtar/compat/fnmatch.c index d10e8a35e2..936f21ec18 100644 --- a/Utilities/cmtar/compat/fnmatch.c +++ b/Utilities/cmtar/compat/fnmatch.c @@ -70,11 +70,7 @@ static char rcsid[] = "$OpenBSD: fnmatch.c,v 1.6 1998/03/19 00:29:59 millert Exp #define RANGE_NOMATCH 0 #define RANGE_ERROR (-1) -#ifdef NO_IBM_COMPILER_HORKAGE static int rangematch (const char *, char, int, char **); -#else -static int rangematch (); -#endif int fnmatch(pattern, string, flags) @@ -195,7 +191,8 @@ rangematch(pattern, test, flags, newp) * consistency with the regular expression syntax. * J.T. Conklin (conklin@ngai.kaleida.com) */ - if ((negate = (*pattern == '!' || *pattern == '^'))) + negate = (*pattern == '!' || *pattern == '^'); + if (negate) ++pattern; if (flags & FNM_CASEFOLD) diff --git a/Utilities/cmtar/config.h.in b/Utilities/cmtar/config.h.in index 948afde5aa..1ab4362e81 100644 --- a/Utilities/cmtar/config.h.in +++ b/Utilities/cmtar/config.h.in @@ -30,6 +30,9 @@ /* Define to 1 if you have the <inttypes.h> header file. */ #cmakedefine HAVE_INTTYPES_H @HAVE_INTTYPES_H@ +/* Define to 1 if you have the <io.h> header file. */ +#cmakedefine HAVE_IO_H @HAVE_IO_H@ + /* Define to 1 if you have the `lchown' function. */ #cmakedefine HAVE_LCHOWN @HAVE_LCHOWN@ diff --git a/Utilities/cmtar/extract.c b/Utilities/cmtar/extract.c index 3ebdeeb273..cb1fab3c9c 100644 --- a/Utilities/cmtar/extract.c +++ b/Utilities/cmtar/extract.c @@ -470,11 +470,13 @@ tar_extract_hardlink(TAR * t, char *realname) return -1; } +#ifndef WIN32 if (pathname) { free(pathname); } return 0; +#endif } @@ -545,11 +547,13 @@ tar_extract_symlink(TAR *t, char *realname) return -1; } +#ifndef WIN32 if (pathname) { free(pathname); } return 0; +#endif } @@ -620,11 +624,13 @@ tar_extract_chardev(TAR *t, char *realname) return -1; } +#ifndef WIN32 if (pathname) { free(pathname); } return 0; +#endif } @@ -694,11 +700,13 @@ tar_extract_blockdev(TAR *t, char *realname) return -1; } +#ifndef WIN32 if (pathname) { free(pathname); } return 0; +#endif } @@ -867,9 +875,11 @@ tar_extract_fifo(TAR *t, char *realname) return -1; } +#ifndef WIN32 if (pathname) { free(pathname); } return 0; +#endif } diff --git a/Utilities/cmtar/handle.c b/Utilities/cmtar/handle.c index 4f6dd10b64..a86bbc5d88 100644 --- a/Utilities/cmtar/handle.c +++ b/Utilities/cmtar/handle.c @@ -24,7 +24,7 @@ # include <stdlib.h> #endif -#if defined ( _MSC_VER) || defined(__WATCOMC__) +#ifdef HAVE_IO_H #include <io.h> //Yogi: hack. this should work on windows where there is no O_ACCMODE defined #ifndef O_ACCMODE diff --git a/Utilities/cmxmlrpc/CMake/TryCompileFromSource.cmake b/Utilities/cmxmlrpc/CMake/TryCompileFromSource.cmake index 6cf5fac2df..1e1006b35c 100644 --- a/Utilities/cmxmlrpc/CMake/TryCompileFromSource.cmake +++ b/Utilities/cmxmlrpc/CMake/TryCompileFromSource.cmake @@ -15,31 +15,32 @@ MACRO(TRY_COMPILE_FROM_SOURCE SOURCE VAR) ENDFOREACH(inc) SET(src "${src}\nint main() { ${SOURCE} ; return 0; }") - FILE(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/src2.c" - "${src}") - EXEC_PROGRAM("${CMAKE_COMMAND}" "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp" + FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src2.c" + "${src}\n") + EXEC_PROGRAM("${CMAKE_COMMAND}" + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp" ARGS -E copy src2.c src.c) MESSAGE(STATUS "Performing Test ${VAR}") TRY_COMPILE(${VAR} ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/src.c + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c CMAKE_FLAGS "${TRY_COMPILE_FROM_SOURCE_ADD_LIBRARIES}" OUTPUT_VARIABLE OUTPUT) IF(${VAR}) SET(${VAR} 1 CACHE INTERNAL "Test ${FUNCTION}") MESSAGE(STATUS "Performing Test ${VAR} - Success") - FILE(WRITE ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n" "${OUTPUT}\n" - "Source file was:\n${src}\n" APPEND) + "Source file was:\n${src}\n") ELSE(${VAR}) MESSAGE(STATUS "Performing Test ${VAR} - Failed") SET(${VAR} "" CACHE INTERNAL "Test ${FUNCTION}") - FILE(WRITE ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Performing C SOURCE FILE Test ${VAR} failed with the following output:\n" "${OUTPUT}\n" - "Source file was:\n${src}\n" APPEND) + "Source file was:\n${src}\n") ENDIF(${VAR}) ENDIF("${VAR}" MATCHES "^${VAR}$" OR "${VAR}" MATCHES "UNKNOWN") ENDMACRO(TRY_COMPILE_FROM_SOURCE) diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in index 47187f5a9d..b57552ec04 100644 --- a/cmake_uninstall.cmake.in +++ b/cmake_uninstall.cmake.in @@ -6,16 +6,17 @@ FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) STRING(REGEX REPLACE "\n" ";" files "${files}") FOREACH(file ${files}) MESSAGE(STATUS "Uninstalling \"${file}\"") - IF(NOT EXISTS "${file}") - MESSAGE(FATAL_ERROR "File \"${file}\" does not exists.") - ENDIF(NOT EXISTS "${file}") - EXEC_PROGRAM("@CMAKE_COMMAND@" ARGS "-E remove \"${file}\"" + IF(EXISTS "${file}") + EXEC_PROGRAM( + "@CMAKE_COMMAND@" ARGS "-E remove \"${file}\"" OUTPUT_VARIABLE rm_out - RETURN_VARIABLE rm_retval) - IF("${rm_retval}" GREATER 0) + RETURN_VALUE rm_retval + ) + IF("${rm_retval}" STREQUAL 0) + ELSE("${rm_retval}" STREQUAL 0) MESSAGE(FATAL_ERROR "Problem when removing \"${file}\"") - ENDIF("${rm_retval}" GREATER 0) + ENDIF("${rm_retval}" STREQUAL 0) + ELSE(EXISTS "${file}") + MESSAGE(STATUS "File \"${file}\" does not exist.") + ENDIF(EXISTS "${file}") ENDFOREACH(file) - - - |