diff --git a/ChangeLog.manual b/ChangeLog.manual index 6560136ca..3165fe66d 100644 --- a/ChangeLog.manual +++ b/ChangeLog.manual @@ -1,3 +1,144 @@ +Changes in CMake 2.8.9-rc3 (since 2.8.9-rc2) +-------------------------------------------- +Alexey Ozeritsky (1): + Fixed: FindLAPACK does not find MKL 10.3 when using gcc 4.x + +Brad King (3): + pre-commit: Reject C++ code with lines too long + Tests/X11: Add missing include for 'rand' + Tests/ObjC++: Use standard header + +David Cole (1): + CPack: Use bin subdir when looking for dpkg and rpmbuild + +Eric NOULARD (2): + Do not run cpack at CMake time it is not available. + Find dpkg and rpmbuild in usual Fink and MacPort paths + +Nicolas Despres (17): + Ninja: Cannot pass a reference to an anonymous object. + Ninja: Add support for OS X app bundles. + Ninja: Add support for OX X library framework. + Ensure 3rd party libraries are writable. + Remove trailing white-spaces. + Re-factor OS X bundle and framework generation. + Ninja: Copy resource files in the bundle. + Ninja: Add support for CFBundle. + Enable BundleTest with CLang too. + Re-factor CFBundle generation. + Ninja: Use same echo message as makefiles. + Re-factor bundle content copying rules generation. + Re-factor Mac OS X content directory computation. + Re-factor framework directory computation. + Re-factor OS X content generator start up. + Fix memory leak in Makefile generator. + Add missing this->. + +Peter Kuemmel (1): + Ninja: dep files and multiple -arch flags not possible on mac + +Peter Kümmel (24): + Ninja: windres is also used for cross-compiling + Ninja: search for windres with prefix + Ninja: there could be null pointers + Ninja: more searching for windres + Ninja: path is already declared + Ninja: fix GCC 4.7 warning -Wconversion + Ninja: fix sytle + Ninja: also stop when .rc's .d file couldn't be generated + Ninja: readd quotes to src file path before patching it + Ninja: cmcldeps needs absolute paths for RCs + Ninja: on Mac no multiple -arch because of -M + Ninja: fix mis-matching endif() argument + Ninja: also mingw needs TARGET_PDB + Ninja: line length + Ninja: make TARGET_PDB a real .gdb file name + Ninja: make debug symbol suffix configurable by CMAKE_DEBUG_SYMBOL_SUFFIX + Ninja: remove 'friend' in ninja code + Ninja: remove warnings + Ninja: remove 'this' from member initializer list + Ninja: fixes for bcc + Ninja: enable ninja on Mac so all Mac CDash-builds are tested, cleanup later + Ninja: void function can't return a value + Ninja: enable ninja support everywhere + Ninja: also bootstrap ninja files + +Changes in CMake 2.8.9-rc2 (since 2.8.9-rc1) +-------------------------------------------- +Alex Neundorf (4): + -remove trailing whitespace + documentation: preparation for making the man section configurable + man documentation: detect man section from the given filename + Eclipse: fix #13313, always set LANG to C, also if unset + +Bill Hoffman (1): + Remove process execution code from cmcldeps and have it use cmake code. + +Brad King (12): + KWIML: Generalize interface to report broken integer literal macros + KWIML: Teach ABI.h about 'long long' and 'char' on old HP + KWIML: Teach INT.h that no HP platform implements SCN*8 formats + KWIML: Teach INT about broken UINT32_C on old HP + Fix project command documentation typo (#13384) + CTestUpdateSVN: Do not create repo directory first (#13349) + Tests/CustomCommand: Do not use 'main' in a library + AIX-GNU: Link shared libs with -brtl,-bnoipath (#13352) + include: Ignore empty string as file name (#13388) + Add ASM platform information for GNU compiler on AIX (#13390) + if: Document that macro arguments are not variables (#13393) + install: Fix COMPONENT option + +Clinton Stimpson (3): + GetPrerequisites.cmake: detect executables built with the -pie linker flag. + cmake-gui: Fix code to respect current locale. + DeployQt4: workaround bug 13258 where ARGV1 is leaked into a sub function. + +David Cole (7): + STYLE: Fix line length, remove extra blank line + CTest: Refactor error output into ErrorMessageUnknownDashDValue + CTest: Rename local variable for clarity + CTest: Extend -D command line arg handling for variable definitions + CTest: Allow -Dvar=value with no space between the D and the var + CTest: Add test to verify -D variable definitions work + Ninja: Fix typo: tagets -> targets + +Eric NOULARD (3): + Enhance documentation of install command w.r.t. the "Undefined" component. + CPack fix regression between 2.8.7 and 2.8.8 when running cpack with no arg. + Do not provide defaul value for CPACK_PACKAGE_DIRECTORY if found in config. + +Nicolas Despres (1): + Ninja: Clean all symlink created for libraries. + +Peter Kuemmel (6): + Ninja: print error message when command failed + Ninja: also consider variables when checking command line length + Ninja: also consider rule command length for rsp file + Ninja: remove int/size_t warning + Ninja: add soname test case + Ninja: don't shadow 'outputs' variable + +Peter Kümmel (6): + Ninja: also write link libraries to rsp file + Ninja: remove some unused default arguments + Ninja: error on missing rspfile_content + Ninja: disable work around when linking with mingw + Ninja: enable response file support on Mac (length 262144) + Ninja: sysconf() is declared in unistd.h + +Philip Lowman (2): + FindBoost: Fix bug where Boost_FOUND could be false when version specified + FindBoost: Future proof to 1.56 + +Rolf Eike Beer (2): + FindJava: improve version matching (#12878) + fix 2 space bugs in variable documentation + +Stephen Kelly (3): + Use full paths in compile_commands.json for out of source builds. + Construct the full path before escaping it. + Fix PositionIndependentTargets test with clang trunk. + Changes in CMake 2.8.9-rc1 (since 2.8.8) ---------------------------------------- Alex Neundorf (12): diff --git a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake index 1b4532deb..455f95fe3 100644 --- a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake +++ b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake @@ -80,15 +80,10 @@ ENDMACRO(_DETERMINE_GCC_SYSTEM_INCLUDE_DIRS _lang) SET(_orig_lc_all $ENV{LC_ALL}) SET(_orig_lc_messages $ENV{LC_MESSAGES}) SET(_orig_lang $ENV{LANG}) -IF(_orig_lc_all) - SET(ENV{LC_ALL} C) -ENDIF() -IF(_orig_lc_messages) - SET(ENV{LC_MESSAGES} C) -ENDIF() -IF(_orig_lang) - SET(ENV{LANG} C) -ENDIF() + +SET(ENV{LC_ALL} C) +SET(ENV{LC_MESSAGES} C) +SET(ENV{LANG} C) # Now check for C, works for gcc and Intel compiler at least IF (NOT CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS) @@ -109,12 +104,6 @@ IF (NOT CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS) ENDIF () # Restore original LC_ALL, LC_MESSAGES, and LANG -IF(_orig_lc_all) - SET(ENV{LC_ALL} ${_orig_lc_all}) -ENDIF() -IF(_orig_lc_messages) - SET(ENV{LC_MESSAGES} ${_orig_lc_messages}) -ENDIF() -IF(_orig_lang) - SET(ENV{LANG} ${_orig_lang}) -ENDIF() +SET(ENV{LC_ALL} ${_orig_lc_all}) +SET(ENV{LC_MESSAGES} ${_orig_lc_messages}) +SET(ENV{LANG} ${_orig_lang}) diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index e5721192c..657595731 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -63,6 +63,14 @@ ##end # ##variable +# CPACK_PACKAGE_DIRECTORY - The directory in which CPack is doing its +# packaging. If it is not set then this will default (internally) to the +# build dir. This variable may be defined in CPack config file or from +# the cpack command line option "-B". If set the command line option +# override the value found in the config file. +##end +# +##variable # CPACK_PACKAGE_VERSION_MAJOR - Package major Version ##end # diff --git a/Modules/DeployQt4.cmake b/Modules/DeployQt4.cmake index b37695d4b..edf4b4e76 100644 --- a/Modules/DeployQt4.cmake +++ b/Modules/DeployQt4.cmake @@ -290,7 +290,7 @@ function(install_qt4_executable executable) endforeach() endif() - resolve_qt4_paths(libs) + resolve_qt4_paths(libs "") install(CODE "INCLUDE(\"${DeployQt4_cmake_dir}/DeployQt4.cmake\") diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index 9eadfd125..1cf31c4a6 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -484,8 +484,7 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") # mkl >= 10.3 if (CMAKE_C_COMPILER MATCHES ".+gcc.*") list(APPEND BLAS_SEARCH_LIBS - "mkl_blas95_lp64 mkl_intel_lp64 mkl_gnu_thread mkl_core") - set(LM "${LM};-lgomp") + "mkl_blas95_lp64 mkl_intel_lp64 mkl_gnu_thread mkl_core gomp") else () list(APPEND BLAS_SEARCH_LIBS "mkl_blas95_lp64 mkl_intel_lp64 mkl_intel_thread mkl_core iomp5") @@ -516,8 +515,7 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") # mkl >= 10.3 if (CMAKE_C_COMPILER MATCHES ".+gcc.*") list(APPEND BLAS_SEARCH_LIBS - "mkl_intel_lp64 mkl_gnu_thread mkl_core") - set(LM "${LM};-lgomp") + "mkl_intel_lp64 mkl_gnu_thread mkl_core gomp") else () list(APPEND BLAS_SEARCH_LIBS "mkl_intel_lp64 mkl_intel_thread mkl_core iomp5") diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index 7504ea44c..ad6b1598d 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -66,7 +66,8 @@ # 1.36, 1.36.0, 1.36.1, 1.37, 1.37.0, 1.38, 1.38.0, 1.39, 1.39.0, # 1.40, 1.40.0, 1.41, 1.41.0, 1.42, 1.42.0, 1.43, 1.43.0, 1.44, 1.44.0, # 1.45, 1.45.0, 1.46, 1.46.0, 1.46.1, 1.47, 1.47.0, 1.48, 1.48.0, -# 1.49, 1.49.0, 1.50, 1.50.0 +# 1.49, 1.49.0, 1.50, 1.50.0, 1.51, 1.51.0, 1.52, 1.52.0, +# 1.53, 1.53.0, 1.54, 1.54.0, 1.55, 1.55.0, 1.56, 1.56.0 # # NOTE: If you add a new major 1.x version in Boost_ADDITIONAL_VERSIONS you should # add both 1.x and 1.x.0 as shown above. Official Boost include directories @@ -246,7 +247,7 @@ # Copyright 2007 Wengo # Copyright 2007 Mike Jackson # Copyright 2008 Andreas Pakulat -# Copyright 2008-2010 Philip Lowman +# Copyright 2008-2012 Philip Lowman # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -298,6 +299,7 @@ endif() #------------------------------------------------------------------------------- # FindBoost functions & macros # + ############################################ # # Check the existence of the libraries. @@ -428,18 +430,95 @@ function(_Boost_CHECK_SPELLING _var) endif() endfunction() +# Guesses Boost's compiler prefix used in built library names +# Returns the guess by setting the variable pointed to by _ret +function(_Boost_GUESS_COMPILER_PREFIX _ret) + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel" + OR "${CMAKE_CXX_COMPILER}" MATCHES "icl" + OR "${CMAKE_CXX_COMPILER}" MATCHES "icpc") + if(WIN32) + set (_boost_COMPILER "-iw") + else() + set (_boost_COMPILER "-il") + endif() + elseif (MSVC11) + set(_boost_COMPILER "-vc110") + elseif (MSVC10) + set(_boost_COMPILER "-vc100") + elseif (MSVC90) + set(_boost_COMPILER "-vc90") + elseif (MSVC80) + set(_boost_COMPILER "-vc80") + elseif (MSVC71) + set(_boost_COMPILER "-vc71") + elseif (MSVC70) # Good luck! + set(_boost_COMPILER "-vc7") # yes, this is correct + elseif (MSVC60) # Good luck! + set(_boost_COMPILER "-vc6") # yes, this is correct + elseif (BORLAND) + set(_boost_COMPILER "-bcb") + elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "SunPro") + set(_boost_COMPILER "-sw") + elseif (MINGW) + if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34) + set(_boost_COMPILER "-mgw") # no GCC version encoding prior to 1.34 + else() + _Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION) + set(_boost_COMPILER "-mgw${_boost_COMPILER_VERSION}") + endif() + elseif (UNIX) + if (CMAKE_COMPILER_IS_GNUCXX) + if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34) + set(_boost_COMPILER "-gcc") # no GCC version encoding prior to 1.34 + else() + _Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION) + # Determine which version of GCC we have. + if(APPLE) + if(Boost_MINOR_VERSION) + if(${Boost_MINOR_VERSION} GREATER 35) + # In Boost 1.36.0 and newer, the mangled compiler name used + # on Mac OS X/Darwin is "xgcc". + set(_boost_COMPILER "-xgcc${_boost_COMPILER_VERSION}") + else(${Boost_MINOR_VERSION} GREATER 35) + # In Boost <= 1.35.0, there is no mangled compiler name for + # the Mac OS X/Darwin version of GCC. + set(_boost_COMPILER "") + endif(${Boost_MINOR_VERSION} GREATER 35) + else(Boost_MINOR_VERSION) + # We don't know the Boost version, so assume it's + # pre-1.36.0. + set(_boost_COMPILER "") + endif(Boost_MINOR_VERSION) + else() + set(_boost_COMPILER "-gcc${_boost_COMPILER_VERSION}") + endif() + endif() + endif (CMAKE_COMPILER_IS_GNUCXX) + else() + # TODO at least Boost_DEBUG here? + set(_boost_COMPILER "") + endif() + set(${_ret} ${_boost_COMPILER} PARENT_SCOPE) +endfunction() + # # End functions/macros # #------------------------------------------------------------------------------- - - +#------------------------------------------------------------------------------- +# main. +#------------------------------------------------------------------------------- if(NOT DEFINED Boost_USE_MULTITHREADED) set(Boost_USE_MULTITHREADED TRUE) endif() +# Check the version of Boost against the requested version. +if(Boost_FIND_VERSION AND NOT Boost_FIND_VERSION_MINOR) + message(SEND_ERROR "When requesting a specific version of Boost, you must provide at least the major and minor version numbers, e.g., 1.34") +endif() + if(Boost_FIND_VERSION_EXACT) # The version may appear in a directory with or without the patch # level, even when the patch level is non-zero. @@ -450,6 +529,8 @@ else(Boost_FIND_VERSION_EXACT) # The user has not requested an exact version. Among known # versions, find those that are acceptable to the user request. set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS} + "1.56.0" "1.56" "1.55.0" "1.55" "1.54.0" "1.54" + "1.53.0" "1.53" "1.52.0" "1.52" "1.51.0" "1.51" "1.50.0" "1.50" "1.49.0" "1.49" "1.48.0" "1.48" "1.47.0" "1.47" "1.46.1" "1.46.0" "1.46" "1.45.0" "1.45" "1.44.0" "1.44" "1.43.0" "1.43" "1.42.0" "1.42" "1.41.0" "1.41" "1.40.0" "1.40" "1.39.0" "1.39" "1.38.0" "1.38" "1.37.0" "1.37" @@ -480,51 +561,7 @@ endif(Boost_FIND_VERSION_EXACT) # Boost. set(Boost_ERROR_REASON) -set( _boost_IN_CACHE TRUE) -if(Boost_INCLUDE_DIR) - - # On versions < 1.35, remove the System library from the considered list - # since it wasn't added until 1.35. - if(Boost_VERSION AND Boost_FIND_COMPONENTS) - if(Boost_VERSION LESS 103500) - list(REMOVE_ITEM Boost_FIND_COMPONENTS system) - endif() - endif() - - foreach(COMPONENT ${Boost_FIND_COMPONENTS}) - string(TOUPPER ${COMPONENT} COMPONENT) - if(NOT Boost_${COMPONENT}_FOUND) - set( _boost_IN_CACHE FALSE) - endif(NOT Boost_${COMPONENT}_FOUND) - endforeach(COMPONENT) -else(Boost_INCLUDE_DIR) - set( _boost_IN_CACHE FALSE) -endif(Boost_INCLUDE_DIR) - -if(_boost_IN_CACHE) - # in cache already - set(Boost_FOUND TRUE) - foreach(COMPONENT ${Boost_FIND_COMPONENTS}) - string(TOUPPER ${COMPONENT} COMPONENT) - _Boost_ADJUST_LIB_VARS( ${COMPONENT} ) - set(Boost_LIBRARIES ${Boost_LIBRARIES} ${Boost_${COMPONENT}_LIBRARY}) - endforeach(COMPONENT) - set(Boost_INCLUDE_DIRS ${Boost_INCLUDE_DIR}) - if(Boost_VERSION AND NOT "${Boost_VERSION}" STREQUAL "0") - math(EXPR Boost_MAJOR_VERSION "${Boost_VERSION} / 100000") - math(EXPR Boost_MINOR_VERSION "${Boost_VERSION} / 100 % 1000") - math(EXPR Boost_SUBMINOR_VERSION "${Boost_VERSION} % 100") - endif(Boost_VERSION AND NOT "${Boost_VERSION}" STREQUAL "0") if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "boost ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION} " - "is already in the cache. To view debugging messages, please clear the cache.") - endif() -else(_boost_IN_CACHE) - # Need to search for boost - if(Boost_DEBUG) - message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "Boost not in cache") # Output some of their choices message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " "_boost_TEST_VERSIONS = ${_boost_TEST_VERSIONS}") @@ -738,78 +775,17 @@ else(_boost_IN_CACHE) message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " "using user-specified Boost_COMPILER = ${_boost_COMPILER}") endif() - else(Boost_COMPILER) + else() # Attempt to guess the compiler suffix # NOTE: this is not perfect yet, if you experience any issues # please report them and use the Boost_COMPILER variable # to work around the problems. - if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel" - OR "${CMAKE_CXX_COMPILER}" MATCHES "icl" - OR "${CMAKE_CXX_COMPILER}" MATCHES "icpc") - if(WIN32) - set (_boost_COMPILER "-iw") - else() - set (_boost_COMPILER "-il") - endif() - elseif (MSVC11) - set(_boost_COMPILER "-vc110") - elseif (MSVC10) - set(_boost_COMPILER "-vc100") - elseif (MSVC90) - set(_boost_COMPILER "-vc90") - elseif (MSVC80) - set(_boost_COMPILER "-vc80") - elseif (MSVC71) - set(_boost_COMPILER "-vc71") - elseif (MSVC70) # Good luck! - set(_boost_COMPILER "-vc7") # yes, this is correct - elseif (MSVC60) # Good luck! - set(_boost_COMPILER "-vc6") # yes, this is correct - elseif (BORLAND) - set(_boost_COMPILER "-bcb") - elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "SunPro") - set(_boost_COMPILER "-sw") - elseif (MINGW) - if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34) - set(_boost_COMPILER "-mgw") # no GCC version encoding prior to 1.34 - else() - _Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION) - set(_boost_COMPILER "-mgw${_boost_COMPILER_VERSION}") - endif() - elseif (UNIX) - if (CMAKE_COMPILER_IS_GNUCXX) - if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34) - set(_boost_COMPILER "-gcc") # no GCC version encoding prior to 1.34 - else() - _Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION) - # Determine which version of GCC we have. - if(APPLE) - if(Boost_MINOR_VERSION) - if(${Boost_MINOR_VERSION} GREATER 35) - # In Boost 1.36.0 and newer, the mangled compiler name used - # on Mac OS X/Darwin is "xgcc". - set(_boost_COMPILER "-xgcc${_boost_COMPILER_VERSION}") - else(${Boost_MINOR_VERSION} GREATER 35) - # In Boost <= 1.35.0, there is no mangled compiler name for - # the Mac OS X/Darwin version of GCC. - set(_boost_COMPILER "") - endif(${Boost_MINOR_VERSION} GREATER 35) - else(Boost_MINOR_VERSION) - # We don't know the Boost version, so assume it's - # pre-1.36.0. - set(_boost_COMPILER "") - endif(Boost_MINOR_VERSION) - else() - set(_boost_COMPILER "-gcc${_boost_COMPILER_VERSION}") - endif() - endif() - endif (CMAKE_COMPILER_IS_GNUCXX) - endif() + _Boost_GUESS_COMPILER_PREFIX(_boost_COMPILER) if(Boost_DEBUG) message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " "guessed _boost_COMPILER = ${_boost_COMPILER}") endif() - endif(Boost_COMPILER) + endif() set (_boost_MULTITHREADED "-mt") if( NOT Boost_USE_MULTITHREADED ) @@ -944,6 +920,13 @@ else(_boost_IN_CACHE) endif() endif() + # On versions < 1.35, remove the System library from the considered list + # since it wasn't added until 1.35. + if(Boost_VERSION AND Boost_FIND_COMPONENTS) + if(Boost_VERSION LESS 103500) + list(REMOVE_ITEM Boost_FIND_COMPONENTS system) + endif() + endif() foreach(COMPONENT ${Boost_FIND_COMPONENTS}) string(TOUPPER ${COMPONENT} UPPERCOMPONENT) @@ -1030,10 +1013,18 @@ else(_boost_IN_CACHE) if( Boost_USE_STATIC_LIBS ) set(CMAKE_FIND_LIBRARY_SUFFIXES ${_boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) endif() + # ------------------------------------------------------------------------ # End finding boost libraries # ------------------------------------------------------------------------ + # ------------------------------------------------------------------------ + # Begin long process of determining Boost_FOUND, starting with version + # number checks, followed by + # TODO: Ideally the version check logic should happen prior to searching + # for libraries... + # ------------------------------------------------------------------------ + set(Boost_INCLUDE_DIRS ${Boost_INCLUDE_DIR} ) @@ -1042,10 +1033,6 @@ else(_boost_IN_CACHE) if(Boost_INCLUDE_DIR) set( Boost_FOUND TRUE ) - # Check the version of Boost against the requested version. - if (Boost_FIND_VERSION AND NOT Boost_FIND_VERSION_MINOR) - message(SEND_ERROR "When requesting a specific version of Boost, you must provide at least the major and minor version numbers, e.g., 1.34") - endif (Boost_FIND_VERSION AND NOT Boost_FIND_VERSION_MINOR) if(Boost_MAJOR_VERSION LESS "${Boost_FIND_VERSION_MAJOR}" ) set( Boost_FOUND FALSE ) set(_Boost_VERSION_AGE "old") @@ -1147,7 +1134,7 @@ else(_boost_IN_CACHE) # Look for the boost library path. # Note that the user may not have installed any libraries - # so it is quite possible the Boost_LIBRARY_PATH may not exist. + # so it is quite possible the Boost_LIBRARY_DIRS may not exist. set(_boost_LIB_DIR ${Boost_INCLUDE_DIR}) if("${_boost_LIB_DIR}" MATCHES "boost-[0-9]+") @@ -1179,6 +1166,10 @@ else(_boost_IN_CACHE) set( Boost_FOUND FALSE) endif(Boost_INCLUDE_DIR) + # ------------------------------------------------------------------------ + # Notification to end user about what was found + # ------------------------------------------------------------------------ + if(Boost_FOUND) if(NOT Boost_FIND_QUIETLY) message(STATUS "Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}") @@ -1201,7 +1192,7 @@ else(_boost_IN_CACHE) else() if(NOT Boost_FIND_QUIETLY) # we opt not to automatically output Boost_ERROR_REASON here as - # it could be quite lengthy and somewhat imposing in it's requests + # it could be quite lengthy and somewhat imposing in its requests # Since Boost is not always a required dependency we'll leave this # up to the end-user. if(Boost_DEBUG OR Boost_DETAILED_FAILURE_MSG) @@ -1218,4 +1209,3 @@ else(_boost_IN_CACHE) Boost_INCLUDE_DIRS Boost_LIBRARY_DIRS ) -endif(_boost_IN_CACHE) diff --git a/Modules/FindJava.cmake b/Modules/FindJava.cmake index 34a7077e8..345702122 100644 --- a/Modules/FindJava.cmake +++ b/Modules/FindJava.cmake @@ -107,9 +107,9 @@ IF(Java_JAVA_EXECUTABLE) # 2. OpenJDK 1.6 # 3. GCJ 1.5 # 4. Kaffe 1.4.2 - IF(var MATCHES "java version \"[0-9]+\\.[0-9]+\\.[0-9_.]+[oem-]*\".*") + IF(var MATCHES "java version \"[0-9]+\\.[0-9]+\\.[0-9_.]+.*\".*") # This is most likely Sun / OpenJDK, or maybe GCJ-java compat layer - STRING( REGEX REPLACE ".* version \"([0-9]+\\.[0-9]+\\.[0-9_.]+)[oem-]*\".*" + STRING( REGEX REPLACE ".* version \"([0-9]+\\.[0-9]+\\.[0-9_.]+.*)\".*" "\\1" Java_VERSION_STRING "${var}" ) ELSEIF(var MATCHES "java full version \"kaffe-[0-9]+\\.[0-9]+\\.[0-9_]+\".*") # Kaffe style @@ -124,7 +124,7 @@ IF(Java_JAVA_EXECUTABLE) STRING( REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" Java_VERSION_MINOR "${Java_VERSION_STRING}" ) STRING( REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" Java_VERSION_PATCH "${Java_VERSION_STRING}" ) # warning tweak version can be empty: - STRING( REGEX REPLACE "[0-9]+\\.[0-9]+\\.[0-9]+\\_?\\.?([0-9]*)$" "\\1" Java_VERSION_TWEAK "${Java_VERSION_STRING}" ) + STRING( REGEX REPLACE "[0-9]+\\.[0-9]+\\.[0-9]+[_\\.]?([0-9]*).*$" "\\1" Java_VERSION_TWEAK "${Java_VERSION_STRING}" ) if( Java_VERSION_TWEAK STREQUAL "" ) # check case where tweak is not defined set(Java_VERSION ${Java_VERSION_MAJOR}.${Java_VERSION_MINOR}.${Java_VERSION_PATCH}) else( ) diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake index 8761f400f..d215685dd 100644 --- a/Modules/GetPrerequisites.cmake +++ b/Modules/GetPrerequisites.cmake @@ -195,6 +195,14 @@ function(is_file_executable file result_var) return() endif("${file_ov}" MATCHES "text") endif("${file_ov}" MATCHES "executable") + + # Also detect position independent executables on Linux, + # where "file" gives "shared object ... (uses shared libraries)" + if("${file_ov}" MATCHES "shared object.*\(uses shared libs\)") + set(${result_var} 1 PARENT_SCOPE) + return() + endif() + else(file_cmd) message(STATUS "warning: No 'file' command, skipping execute_process...") endif(file_cmd) diff --git a/Modules/Platform/AIX-GNU-ASM.cmake b/Modules/Platform/AIX-GNU-ASM.cmake new file mode 100644 index 000000000..c256df6f9 --- /dev/null +++ b/Modules/Platform/AIX-GNU-ASM.cmake @@ -0,0 +1,2 @@ +include(Platform/AIX-GNU) +__aix_compiler_gnu(ASM) diff --git a/Modules/Platform/AIX-GNU.cmake b/Modules/Platform/AIX-GNU.cmake index 543f3e8cf..81ba3657f 100644 --- a/Modules/Platform/AIX-GNU.cmake +++ b/Modules/Platform/AIX-GNU.cmake @@ -21,5 +21,6 @@ set(__AIX_COMPILER_GNU 1) macro(__aix_compiler_gnu lang) set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-blibpath:") set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":") - set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS} -Wl,-G") + set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS} -Wl,-G,-brtl,-bnoipath") + set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-brtl,-bnoipath,-bexpall") # +s, flag for exe link to use shared lib endmacro() diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index 1a2ee5e96..4a37eca87 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -115,7 +115,9 @@ macro(__windows_compiler_gnu lang) list(APPEND CMAKE_${lang}_ABI_FILES "Platform/Windows-GNU-${lang}-ABI") # Support very long lists of object files. - if("${CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG}" STREQUAL "@") + # TODO: check for which gcc versions this is still needed, not needed for gcc >= 4.4. + # Ninja generator doesn't support this work around. + if("${CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG}" STREQUAL "@" AND NOT CMAKE_GENERATOR MATCHES "Ninja") foreach(rule CREATE_SHARED_MODULE CREATE_SHARED_LIBRARY LINK_EXECUTABLE) # The gcc/collect2/ld toolchain does not use response files # internally so we cannot pass long object lists. Instead pass diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 2c6bc7665..e9c5a587e 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -219,6 +219,8 @@ SET(SRCS cmMakefileExecutableTargetGenerator.cxx cmMakefileLibraryTargetGenerator.cxx cmMakefileUtilityTargetGenerator.cxx + cmOSXBundleGenerator.cxx + cmOSXBundleGenerator.h cmNewLineStyle.h cmNewLineStyle.cxx cmOrderDirectories.cxx @@ -357,39 +359,25 @@ IF (WIN32) ENDIF(NOT UNIX) ENDIF (WIN32) -# Turn on Ninja by default, but disable it -# on platforms where it does not pass all tests. -# Enforce Ninja support by setting CMAKE_USE_NINJA -set(_CMAKE_DEFAULT_NINJA_VALUE TRUE) -if(APPLE) - SET(_CMAKE_DEFAULT_NINJA_VALUE FALSE) -endif() -SET(CMAKE_ENABLE_NINJA ${_CMAKE_DEFAULT_NINJA_VALUE} CACHE BOOL - "Enable the ninja generator for CMake. When enabled, some CMake tests still fail on OSX") -MARK_AS_ADVANCED(CMAKE_ENABLE_NINJA) -IF(CMAKE_ENABLE_NINJA) - MESSAGE(STATUS "Ninja generator enabled.") - SET(SRCS ${SRCS} - cmGlobalNinjaGenerator.cxx - cmGlobalNinjaGenerator.h - cmNinjaTypes.h - cmLocalNinjaGenerator.cxx - cmLocalNinjaGenerator.h - cmNinjaTargetGenerator.cxx - cmNinjaTargetGenerator.h - cmNinjaNormalTargetGenerator.cxx - cmNinjaNormalTargetGenerator.h - cmNinjaUtilityTargetGenerator.cxx - cmNinjaUtilityTargetGenerator.h - ) - ADD_DEFINITIONS(-DCMAKE_USE_NINJA) - IF(WIN32 AND NOT CYGWIN AND NOT BORLAND) - SET_SOURCE_FILES_PROPERTIES(cmcldeps.cxx PROPERTIES COMPILE_DEFINITIONS _WIN32_WINNT=0x0501) - ADD_EXECUTABLE(cmcldeps cmcldeps.cxx) - INSTALL_TARGETS(/bin cmcldeps) - ENDIF() -ELSE() - MESSAGE(STATUS "Ninja generator disabled, enable it with -DCMAKE_ENABLE_NINJA=ON") +# Ninja support +SET(SRCS ${SRCS} + cmGlobalNinjaGenerator.cxx + cmGlobalNinjaGenerator.h + cmNinjaTypes.h + cmLocalNinjaGenerator.cxx + cmLocalNinjaGenerator.h + cmNinjaTargetGenerator.cxx + cmNinjaTargetGenerator.h + cmNinjaNormalTargetGenerator.cxx + cmNinjaNormalTargetGenerator.h + cmNinjaUtilityTargetGenerator.cxx + cmNinjaUtilityTargetGenerator.h + ) +IF(WIN32 AND NOT CYGWIN AND NOT BORLAND) + SET_SOURCE_FILES_PROPERTIES(cmcldeps.cxx PROPERTIES COMPILE_DEFINITIONS _WIN32_WINNT=0x0501) + ADD_EXECUTABLE(cmcldeps cmcldeps.cxx) + TARGET_LINK_LIBRARIES(cmcldeps CMakeLib) + INSTALL_TARGETS(/bin cmcldeps) ENDIF() # create a library used by the command line and the GUI diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index f4f94cc2f..44c8ed569 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -3,4 +3,4 @@ SET(CMake_VERSION_MAJOR 2) SET(CMake_VERSION_MINOR 8) SET(CMake_VERSION_PATCH 9) SET(CMake_VERSION_TWEAK 0) -SET(CMake_VERSION_RC 1) +SET(CMake_VERSION_RC 3) diff --git a/Source/CPack/cmCPackDebGenerator.h b/Source/CPack/cmCPackDebGenerator.h index 7f2352f15..d678cfacf 100644 --- a/Source/CPack/cmCPackDebGenerator.h +++ b/Source/CPack/cmCPackDebGenerator.h @@ -35,7 +35,10 @@ public: { #ifdef __APPLE__ // on MacOS enable CPackDeb iff dpkg is found - return cmSystemTools::FindProgram("dpkg") != "" ? true : false; + std::vector locations; + locations.push_back("/sw/bin"); // Fink + locations.push_back("/opt/local/bin"); // MacPorts + return cmSystemTools::FindProgram("dpkg",locations) != "" ? true : false; #else // legacy behavior on other systems return true; diff --git a/Source/CPack/cmCPackRPMGenerator.h b/Source/CPack/cmCPackRPMGenerator.h index eec8204da..a7722bc58 100644 --- a/Source/CPack/cmCPackRPMGenerator.h +++ b/Source/CPack/cmCPackRPMGenerator.h @@ -39,6 +39,9 @@ public: { #ifdef __APPLE__ // on MacOS enable CPackRPM iff rpmbuild is found + std::vector locations; + locations.push_back("/sw/bin"); // Fink + locations.push_back("/opt/local/bin"); // MacPorts return cmSystemTools::FindProgram("rpmbuild") != "" ? true : false; #else // legacy behavior on other systems diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 6f5055ca8..b6035854e 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -207,8 +207,7 @@ int main (int argc, char *argv[]) std::string helpHTML; std::string cpackProjectName; - std::string cpackProjectDirectory - = cmsys::SystemTools::GetCurrentWorkingDirectory(); + std::string cpackProjectDirectory; std::string cpackBuildConfig; std::string cpackProjectVersion; std::string cpackProjectPatch; @@ -294,8 +293,12 @@ int main (int argc, char *argv[]) cmDocumentation doc; doc.addCPackStandardDocSections(); - /* Were we invoked to display doc or to do some work ? */ - if(doc.CheckOptions(argc, argv,"-G") || nocwd) + /* Were we invoked to display doc or to do some work ? + * Unlike cmake launching cpack with zero argument + * should launch cpack using "cpackConfigFile" if it exists + * in the current directory. + */ + if((doc.CheckOptions(argc, argv,"-G") || nocwd) && !(argc==1)) { help = true; } @@ -370,10 +373,24 @@ int main (int argc, char *argv[]) globalMF->AddDefinition("CPACK_PACKAGE_VENDOR", cpackProjectVendor.c_str()); } + // if this is not empty it has been set on the command line + // go for it. Command line override values set in config file. if ( !cpackProjectDirectory.empty() ) { globalMF->AddDefinition("CPACK_PACKAGE_DIRECTORY", - cpackProjectDirectory.c_str()); + cpackProjectDirectory.c_str()); + } + // The value has not been set on the command line + else + { + // get a default value (current working directory) + cpackProjectDirectory = cmsys::SystemTools::GetCurrentWorkingDirectory(); + // use default value iff no value has been provided by the config file + if (!globalMF->IsSet("CPACK_PACKAGE_DIRECTORY")) + { + globalMF->AddDefinition("CPACK_PACKAGE_DIRECTORY", + cpackProjectDirectory.c_str()); + } } if ( !cpackBuildConfig.empty() ) { diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index d3ab2efda..8643cb3f7 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -435,6 +435,15 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg) return 2; } + // Add definitions of variables passed in on the command line: + const std::map &defs = + this->CTest->GetDefinitions(); + for (std::map::const_iterator it = defs.begin(); + it != defs.end(); ++it) + { + this->Makefile->AddDefinition(it->first.c_str(), it->second.c_str()); + } + // finally read in the script if (!this->Makefile->ReadListFile(0, script.c_str()) || cmSystemTools::GetErrorOccuredFlag()) diff --git a/Source/QtDialog/AddCacheEntry.cxx b/Source/QtDialog/AddCacheEntry.cxx index 00aaf69da..e7fedc5c5 100644 --- a/Source/QtDialog/AddCacheEntry.cxx +++ b/Source/QtDialog/AddCacheEntry.cxx @@ -15,7 +15,7 @@ #include static const int NumTypes = 4; -static const QString TypeStrings[NumTypes] = +static const QByteArray TypeStrings[NumTypes] = { "BOOL", "PATH", "FILEPATH", "STRING" }; static const QCMakeProperty::PropertyType Types[NumTypes] = { QCMakeProperty::BOOL, QCMakeProperty::PATH, diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt index 056e48ec3..07ec10674 100644 --- a/Source/QtDialog/CMakeLists.txt +++ b/Source/QtDialog/CMakeLists.txt @@ -36,14 +36,14 @@ ELSE(NOT QT4_FOUND) QMacInstallDialog.cxx QMacInstallDialog.h ) - QT4_WRAP_UI(UI_SRCS + QT4_WRAP_UI(UI_SRCS CMakeSetupDialog.ui Compilers.ui CrossCompiler.ui AddCacheEntry.ui MacInstallDialog.ui ) - QT4_WRAP_CPP(MOC_SRCS + QT4_WRAP_CPP(MOC_SRCS AddCacheEntry.h Compilers.h CMakeSetupDialog.h @@ -76,7 +76,7 @@ ELSE(NOT QT4_FOUND) SET_TARGET_PROPERTIES(cmake-gui PROPERTIES OUTPUT_NAME ${CMAKE_BUNDLE_NAME}) ENDIF(APPLE) - SET(CMAKE_INSTALL_DESTINATION_ARGS + SET(CMAKE_INSTALL_DESTINATION_ARGS BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}") ENDIF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4) @@ -112,11 +112,12 @@ ELSE(NOT QT4_FOUND) endif(APPLE) install(CODE " include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\") + set(BU_CHMOD_BUNDLE_ITEMS ON) fixup_bundle(\"${fixup_exe}\" \"\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\") ") endif(APPLE OR WIN32) CONFIGURE_FILE("${QtDialog_SOURCE_DIR}/QtDialogCPack.cmake.in" - "${QtDialog_BINARY_DIR}/QtDialogCPack.cmake" @ONLY) + "${QtDialog_BINARY_DIR}/QtDialogCPack.cmake" @ONLY) ENDIF(NOT QT4_FOUND) diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index b4f3d7216..c942bc4ad 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -125,7 +125,7 @@ int main(int argc, char** argv) // pick up translation files if they exists in the data directory QDir translationsDir = cmExecDir; - translationsDir.cd(".." CMAKE_DATA_DIR); + translationsDir.cd(QString::fromLocal8Bit(".." CMAKE_DATA_DIR)); translationsDir.cd("i18n"); QTranslator translator; QString transfile = QString("cmake_%1").arg(QLocale::system().name()); @@ -157,15 +157,15 @@ int main(int argc, char** argv) arg.Parse(); if(!sourceDirectory.empty() && !binaryDirectory.empty()) { - dialog.setSourceDirectory(sourceDirectory.c_str()); - dialog.setBinaryDirectory(binaryDirectory.c_str()); + dialog.setSourceDirectory(QString::fromLocal8Bit(sourceDirectory.c_str())); + dialog.setBinaryDirectory(QString::fromLocal8Bit(binaryDirectory.c_str())); } else { QStringList args = app.arguments(); if(args.count() == 2) { - cmsys_stl::string filePath = cmSystemTools::CollapseFullPath(args[1].toAscii().data()); + cmsys_stl::string filePath = cmSystemTools::CollapseFullPath(args[1].toLocal8Bit().data()); // check if argument is a directory containing CMakeCache.txt cmsys_stl::string buildFilePath = @@ -184,12 +184,18 @@ int main(int argc, char** argv) if(cmSystemTools::FileExists(buildFilePath.c_str())) { - dialog.setBinaryDirectory(cmSystemTools::GetFilenamePath(buildFilePath).c_str()); + dialog.setBinaryDirectory( + QString::fromLocal8Bit( + cmSystemTools::GetFilenamePath(buildFilePath).c_str() + ) + ); } else if(cmSystemTools::FileExists(srcFilePath.c_str())) { - dialog.setSourceDirectory(filePath.c_str()); - dialog.setBinaryDirectory(cmSystemTools::CollapseFullPath(".").c_str()); + dialog.setSourceDirectory(QString::fromLocal8Bit(filePath.c_str())); + dialog.setBinaryDirectory( + QString::fromLocal8Bit(cmSystemTools::CollapseFullPath(".").c_str()) + ); } } } diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index 5cd4f29dd..c0dde1c2c 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -299,9 +299,8 @@ bool CMakeSetupDialog::prepareConfigure() if(!dir.exists()) { QString msg = tr("Build directory does not exist, " - "should I create it?") - + "\n\n" - + tr("Directory: "); + "should I create it?\n\n" + "Directory: "); msg += bindir; QString title = tr("Create Directory"); QMessageBox::StandardButton btn; @@ -490,9 +489,9 @@ void CMakeSetupDialog::closeEvent(QCloseEvent* e) // don't close if we're busy, unless the user really wants to if(this->CurrentState == Configuring) { - QString msg = "You are in the middle of a Configure.\n" + QString msg = tr("You are in the middle of a Configure.\n" "If you Exit now the configure information will be lost.\n" - "Are you sure you want to Exit?"; + "Are you sure you want to Exit?"); QString title = tr("Confirm Exit"); QMessageBox::StandardButton btn; btn = QMessageBox::critical(this, title, msg, @@ -715,33 +714,33 @@ bool CMakeSetupDialog::setupFirstConfigure() QString mode = dialog.getCrossIncludeMode(); m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE", - "CMake Find Include Mode", mode, false); + tr("CMake Find Include Mode"), mode, false); mode = dialog.getCrossLibraryMode(); m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY", - "CMake Find Library Mode", mode, false); + tr("CMake Find Library Mode"), mode, false); mode = dialog.getCrossProgramMode(); m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM", - "CMake Find Program Mode", mode, false); + tr("CMake Find Program Mode"), mode, false); QString rootPath = dialog.getCrossRoot(); m->insertProperty(QCMakeProperty::PATH, "CMAKE_FIND_ROOT_PATH", - "CMake Find Root Path", rootPath, false); + tr("CMake Find Root Path"), rootPath, false); QString systemName = dialog.getSystemName(); m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_NAME", - "CMake System Name", systemName, false); + tr("CMake System Name"), systemName, false); QString cxxCompiler = dialog.getCXXCompiler(); m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER", - "CXX compiler.", cxxCompiler, false); + tr("CXX compiler."), cxxCompiler, false); QString cCompiler = dialog.getCCompiler(); m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_C_COMPILER", - "C compiler.", cCompiler, false); + tr("C compiler."), cCompiler, false); } else if(dialog.crossCompilerToolChainFile()) { QString toolchainFile = dialog.getCrossCompilerToolChainFile(); m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_TOOLCHAIN_FILE", - "Cross Compile ToolChain File", toolchainFile, false); + tr("Cross Compile ToolChain File"), toolchainFile, false); } return true; } @@ -772,7 +771,7 @@ void CMakeSetupDialog::doReloadCache() void CMakeSetupDialog::doDeleteCache() { QString title = tr("Delete Cache"); - QString msg = "Are you sure you want to delete the cache?"; + QString msg = tr("Are you sure you want to delete the cache?"); QMessageBox::StandardButton btn; btn = QMessageBox::information(this, title, msg, QMessageBox::Yes | QMessageBox::No); @@ -786,9 +785,9 @@ void CMakeSetupDialog::doDeleteCache() void CMakeSetupDialog::doAbout() { - QString msg = "CMake %1\n" + QString msg = tr("CMake %1\n" "Using Qt %2\n" - "www.cmake.org"; + "www.cmake.org"); msg = msg.arg(cmVersion::GetCMakeVersion()); msg = msg.arg(qVersion()); diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx index f522760c0..2a79877da 100644 --- a/Source/QtDialog/FirstConfigure.cxx +++ b/Source/QtDialog/FirstConfigure.cxx @@ -17,10 +17,10 @@ StartCompilerSetup::StartCompilerSetup(QWidget* p) l->addWidget(this->GeneratorOptions); l->addSpacing(6); - this->CompilerSetupOptions[0] = new QRadioButton("Use default native compilers", this); - this->CompilerSetupOptions[1] = new QRadioButton("Specify native compilers", this); - this->CompilerSetupOptions[2] = new QRadioButton("Specify toolchain file for cross-compiling", this); - this->CompilerSetupOptions[3] = new QRadioButton("Specify options for cross-compiling", this); + this->CompilerSetupOptions[0] = new QRadioButton(tr("Use default native compilers"), this); + this->CompilerSetupOptions[1] = new QRadioButton(tr("Specify native compilers"), this); + this->CompilerSetupOptions[2] = new QRadioButton(tr("Specify toolchain file for cross-compiling"), this); + this->CompilerSetupOptions[3] = new QRadioButton(tr("Specify options for cross-compiling"), this); l->addWidget(this->CompilerSetupOptions[0]); l->addWidget(this->CompilerSetupOptions[1]); l->addWidget(this->CompilerSetupOptions[2]); @@ -159,9 +159,9 @@ CrossCompilerSetup::CrossCompilerSetup(QWidget* p) // fill in combo boxes QStringList modes; - modes << "Search in Target Root, then native system"; - modes << "Search only in Target Root"; - modes << "Search only in native system"; + modes << tr("Search in Target Root, then native system"); + modes << tr("Search only in Target Root"); + modes << tr("Search only in native system"); crossProgramMode->addItems(modes); crossLibraryMode->addItems(modes); crossIncludeMode->addItems(modes); diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 73050f30c..8554ff894 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -46,16 +46,16 @@ QCMake::QCMake(QObject* p) } #endif - QString cmakeCommand = QString("cmake")+cmSystemTools::GetExecutableExtension(); + QString cmakeCommand = QString("cmake")+QString::fromLocal8Bit(cmSystemTools::GetExecutableExtension()); cmakeCommand = execDir.filePath(cmakeCommand); cmSystemTools::DisableRunCommandOutput(); cmSystemTools::SetRunCommandHideConsole(true); cmSystemTools::SetErrorCallback(QCMake::errorCallback, this); - cmSystemTools::FindExecutableDirectory(cmakeCommand.toAscii().data()); + cmSystemTools::FindExecutableDirectory(cmakeCommand.toLocal8Bit().data()); this->CMakeInstance = new cmake; - this->CMakeInstance->SetCMakeCommand(cmakeCommand.toAscii().data()); + this->CMakeInstance->SetCMakeCommand(cmakeCommand.toLocal8Bit().data()); #if defined(Q_OS_MAC) this->CMakeInstance->SetCMakeEditCommand("cmake-gui.app/Contents/MacOS/cmake-gui"); #else @@ -79,7 +79,7 @@ QCMake::QCMake(QObject* p) { continue; } - this->AvailableGenerators.append(iter->c_str()); + this->AvailableGenerators.append(QString::fromLocal8Bit(iter->c_str())); } } @@ -97,7 +97,7 @@ void QCMake::loadCache(const QString& dir) void QCMake::setSourceDirectory(const QString& _dir) { QString dir = - cmSystemTools::GetActualCaseForPath(_dir.toAscii().data()).c_str(); + QString::fromLocal8Bit(cmSystemTools::GetActualCaseForPath(_dir.toLocal8Bit().data()).c_str()); if(this->SourceDirectory != dir) { this->SourceDirectory = QDir::fromNativeSeparators(dir); @@ -108,7 +108,7 @@ void QCMake::setSourceDirectory(const QString& _dir) void QCMake::setBinaryDirectory(const QString& _dir) { QString dir = - cmSystemTools::GetActualCaseForPath(_dir.toAscii().data()).c_str(); + QString::fromLocal8Bit(cmSystemTools::GetActualCaseForPath(_dir.toLocal8Bit().data()).c_str()); if(this->BinaryDirectory != dir) { this->BinaryDirectory = QDir::fromNativeSeparators(dir); @@ -132,14 +132,14 @@ void QCMake::setBinaryDirectory(const QString& _dir) cmCacheManager::CacheIterator itm = cachem->NewIterator(); if ( itm.Find("CMAKE_HOME_DIRECTORY")) { - setSourceDirectory(itm.GetValue()); + setSourceDirectory(QString::fromLocal8Bit(itm.GetValue())); } if ( itm.Find("CMAKE_GENERATOR")) { const char* extraGen = cachem->GetCacheValue("CMAKE_EXTRA_GENERATOR"); std::string curGen = cmExternalMakefileProjectGenerator:: CreateFullGeneratorName(itm.GetValue(), extraGen); - this->setGenerator(curGen.c_str()); + this->setGenerator(QString::fromLocal8Bit(curGen.c_str())); } } } @@ -160,12 +160,12 @@ void QCMake::configure() UINT lastErrorMode = SetErrorMode(0); #endif - this->CMakeInstance->SetHomeDirectory(this->SourceDirectory.toAscii().data()); - this->CMakeInstance->SetStartDirectory(this->SourceDirectory.toAscii().data()); - this->CMakeInstance->SetHomeOutputDirectory(this->BinaryDirectory.toAscii().data()); - this->CMakeInstance->SetStartOutputDirectory(this->BinaryDirectory.toAscii().data()); + this->CMakeInstance->SetHomeDirectory(this->SourceDirectory.toLocal8Bit().data()); + this->CMakeInstance->SetStartDirectory(this->SourceDirectory.toLocal8Bit().data()); + this->CMakeInstance->SetHomeOutputDirectory(this->BinaryDirectory.toLocal8Bit().data()); + this->CMakeInstance->SetStartOutputDirectory(this->BinaryDirectory.toLocal8Bit().data()); this->CMakeInstance->SetGlobalGenerator( - this->CMakeInstance->CreateGlobalGenerator(this->Generator.toAscii().data())); + this->CMakeInstance->CreateGlobalGenerator(this->Generator.toLocal8Bit().data())); this->CMakeInstance->LoadCache(); this->CMakeInstance->SetSuppressDevWarnings(this->SuppressDevWarnings); this->CMakeInstance->SetWarnUninitialized(this->WarnUninitializedMode); @@ -222,11 +222,11 @@ void QCMake::setProperties(const QCMakePropertyList& newProps) } QCMakeProperty prop; - prop.Key = i.GetName(); + prop.Key = QString::fromLocal8Bit(i.GetName()); int idx = props.indexOf(prop); if(idx == -1) { - toremove.append(i.GetName()); + toremove.append(QString::fromLocal8Bit(i.GetName())); } else { @@ -237,7 +237,7 @@ void QCMake::setProperties(const QCMakePropertyList& newProps) } else { - i.SetValue(prop.Value.toString().toAscii().data()); + i.SetValue(prop.Value.toString().toLocal8Bit().data()); } props.removeAt(idx); } @@ -247,47 +247,47 @@ void QCMake::setProperties(const QCMakePropertyList& newProps) // remove some properites foreach(QString s, toremove) { - this->CMakeInstance->UnwatchUnusedCli(s.toAscii().data()); + this->CMakeInstance->UnwatchUnusedCli(s.toLocal8Bit().data()); - cachem->RemoveCacheEntry(s.toAscii().data()); + cachem->RemoveCacheEntry(s.toLocal8Bit().data()); } // add some new properites foreach(QCMakeProperty s, props) { - this->CMakeInstance->WatchUnusedCli(s.Key.toAscii().data()); + this->CMakeInstance->WatchUnusedCli(s.Key.toLocal8Bit().data()); if(s.Type == QCMakeProperty::BOOL) { - this->CMakeInstance->AddCacheEntry(s.Key.toAscii().data(), + this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(), s.Value.toBool() ? "ON" : "OFF", - s.Help.toAscii().data(), + s.Help.toLocal8Bit().data(), cmCacheManager::BOOL); } else if(s.Type == QCMakeProperty::STRING) { - this->CMakeInstance->AddCacheEntry(s.Key.toAscii().data(), - s.Value.toString().toAscii().data(), - s.Help.toAscii().data(), + this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(), + s.Value.toString().toLocal8Bit().data(), + s.Help.toLocal8Bit().data(), cmCacheManager::STRING); } else if(s.Type == QCMakeProperty::PATH) { - this->CMakeInstance->AddCacheEntry(s.Key.toAscii().data(), - s.Value.toString().toAscii().data(), - s.Help.toAscii().data(), + this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(), + s.Value.toString().toLocal8Bit().data(), + s.Help.toLocal8Bit().data(), cmCacheManager::PATH); } else if(s.Type == QCMakeProperty::FILEPATH) { - this->CMakeInstance->AddCacheEntry(s.Key.toAscii().data(), - s.Value.toString().toAscii().data(), - s.Help.toAscii().data(), + this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(), + s.Value.toString().toLocal8Bit().data(), + s.Help.toLocal8Bit().data(), cmCacheManager::FILEPATH); } } - cachem->SaveCache(this->BinaryDirectory.toAscii().data()); + cachem->SaveCache(this->BinaryDirectory.toLocal8Bit().data()); } QCMakePropertyList QCMake::properties() const @@ -307,9 +307,9 @@ QCMakePropertyList QCMake::properties() const } QCMakeProperty prop; - prop.Key = i.GetName(); - prop.Help = i.GetProperty("HELPSTRING"); - prop.Value = i.GetValue(); + prop.Key = QString::fromLocal8Bit(i.GetName()); + prop.Help = QString::fromLocal8Bit(i.GetProperty("HELPSTRING")); + prop.Value = QString::fromLocal8Bit(i.GetValue()); prop.Advanced = i.GetPropertyAsBool("ADVANCED"); if(i.GetType() == cmCacheManager::BOOL) @@ -330,7 +330,7 @@ QCMakePropertyList QCMake::properties() const prop.Type = QCMakeProperty::STRING; if (i.PropertyExists("STRINGS")) { - prop.Strings = QString(i.GetProperty("STRINGS")).split(";"); + prop.Strings = QString::fromLocal8Bit(i.GetProperty("STRINGS")).split(";"); } } @@ -356,11 +356,11 @@ void QCMake::progressCallback(const char* msg, float percent, void* cd) QCMake* self = reinterpret_cast(cd); if(percent >= 0) { - emit self->progressChanged(msg, percent); + emit self->progressChanged(QString::fromLocal8Bit(msg), percent); } else { - emit self->outputMessage(msg); + emit self->outputMessage(QString::fromLocal8Bit(msg)); } QCoreApplication::processEvents(); } @@ -369,7 +369,7 @@ void QCMake::errorCallback(const char* msg, const char* /*title*/, bool& /*stop*/, void* cd) { QCMake* self = reinterpret_cast(cd); - emit self->errorMessage(msg); + emit self->errorMessage(QString::fromLocal8Bit(msg)); QCoreApplication::processEvents(); } @@ -396,9 +396,9 @@ QStringList QCMake::availableGenerators() const void QCMake::deleteCache() { // delete cache - this->CMakeInstance->GetCacheManager()->DeleteCache(this->BinaryDirectory.toAscii().data()); + this->CMakeInstance->GetCacheManager()->DeleteCache(this->BinaryDirectory.toLocal8Bit().data()); // reload to make our cache empty - this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toAscii().data()); + this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toLocal8Bit().data()); // emit no generator and no properties this->setGenerator(QString()); QCMakePropertyList props = this->properties(); @@ -411,7 +411,7 @@ void QCMake::reloadCache() QCMakePropertyList props; emit this->propertiesChanged(props); // reload - this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toAscii().data()); + this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toLocal8Bit().data()); // emit new cache properties props = this->properties(); emit this->propertiesChanged(props); diff --git a/Source/QtDialog/QMacInstallDialog.cxx b/Source/QtDialog/QMacInstallDialog.cxx index 3aa509d94..6eb053b21 100644 --- a/Source/QtDialog/QMacInstallDialog.cxx +++ b/Source/QtDialog/QMacInstallDialog.cxx @@ -34,12 +34,11 @@ void QMacInstallDialog::DoInstall() { QDir installDir(this->Internals->InstallPrefix->text()); QString installTo = installDir.path(); - if(!cmSystemTools::FileExists(installTo.toAscii().data())) + if(!cmSystemTools::FileExists(installTo.toLocal8Bit().data())) { QString message = tr("Build install does not exist, " - "should I create it?") - + "\n\n" - + tr("Directory: "); + "should I create it?\n\n" + "Directory: "); message += installDir.path(); QString title = tr("Create Directory"); QMessageBox::StandardButton btn; @@ -47,7 +46,7 @@ void QMacInstallDialog::DoInstall() QMessageBox::Yes | QMessageBox::No); if(btn == QMessageBox::Yes) { - cmSystemTools::MakeDirectory(installTo.toAscii().data()); + cmSystemTools::MakeDirectory(installTo.toLocal8Bit().data()); } } QDir cmExecDir(QApplication::applicationDirPath()); @@ -66,14 +65,14 @@ void QMacInstallDialog::DoInstall() newName += "/"; newName += filename; // Remove the old files - if(cmSystemTools::FileExists(newName.toAscii().data())) + if(cmSystemTools::FileExists(newName.toLocal8Bit().data())) { - std::cout << "rm [" << newName.toAscii().data() << "]\n"; - if(!cmSystemTools::RemoveFile(newName.toAscii().data())) + std::cout << "rm [" << newName.toLocal8Bit().data() << "]\n"; + if(!cmSystemTools::RemoveFile(newName.toLocal8Bit().data())) { QString message = tr("Failed to remove file " "installation may be incomplete: "); - message += newName.toAscii().data(); + message += newName; QString title = tr("Error Removing file"); QMessageBox::StandardButton btn = QMessageBox::critical(this, title, message, @@ -84,14 +83,14 @@ void QMacInstallDialog::DoInstall() } } } - std::cout << "ln -s [" << file.toAscii().data() << "] ["; - std::cout << newName.toAscii().data() << "]\n"; - if(!cmSystemTools::CreateSymlink(file.toAscii().data(), - newName.toAscii().data())) + std::cout << "ln -s [" << file.toLocal8Bit().data() << "] ["; + std::cout << newName.toLocal8Bit().data() << "]\n"; + if(!cmSystemTools::CreateSymlink(file.toLocal8Bit().data(), + newName.toLocal8Bit().data())) { QString message = tr("Failed create symlink " "installation may be incomplete: "); - message += newName.toAscii().data(); + message += newName; QString title = tr("Error Creating Symlink"); QMessageBox::StandardButton btn = QMessageBox::critical(this, title, message, diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 4aff64bd8..b5687e39a 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -1944,35 +1944,33 @@ bool cmCTest::AddTestsForDashboardType(std::string &targ) } else { - cmCTestLog(this, ERROR_MESSAGE, - "CTest -D called with incorrect option: " - << targ << std::endl); - cmCTestLog(this, ERROR_MESSAGE, "Available options are:" << std::endl - << " " << "ctest" << " -D Continuous" << std::endl - << " " << "ctest" - << " -D Continuous(Start|Update|Configure|Build)" << std::endl - << " " << "ctest" - << " -D Continuous(Test|Coverage|MemCheck|Submit)" - << std::endl - << " " << "ctest" << " -D Experimental" << std::endl - << " " << "ctest" - << " -D Experimental(Start|Update|Configure|Build)" - << std::endl - << " " << "ctest" - << " -D Experimental(Test|Coverage|MemCheck|Submit)" - << std::endl - << " " << "ctest" << " -D Nightly" << std::endl - << " " << "ctest" - << " -D Nightly(Start|Update|Configure|Build)" << std::endl - << " " << "ctest" - << " -D Nightly(Test|Coverage|MemCheck|Submit)" << std::endl - << " " << "ctest" << " -D NightlyMemoryCheck" << std::endl); return false; } return true; } +//---------------------------------------------------------------------- +void cmCTest::ErrorMessageUnknownDashDValue(std::string &val) +{ + cmCTestLog(this, ERROR_MESSAGE, + "CTest -D called with incorrect option: " << val << std::endl); + + cmCTestLog(this, ERROR_MESSAGE, + "Available options are:" << std::endl + << " ctest -D Continuous" << std::endl + << " ctest -D Continuous(Start|Update|Configure|Build)" << std::endl + << " ctest -D Continuous(Test|Coverage|MemCheck|Submit)" << std::endl + << " ctest -D Experimental" << std::endl + << " ctest -D Experimental(Start|Update|Configure|Build)" << std::endl + << " ctest -D Experimental(Test|Coverage|MemCheck|Submit)" << std::endl + << " ctest -D Nightly" << std::endl + << " ctest -D Nightly(Start|Update|Configure|Build)" << std::endl + << " ctest -D Nightly(Test|Coverage|MemCheck|Submit)" << std::endl + << " ctest -D NightlyMemoryCheck" << std::endl); +} + + //---------------------------------------------------------------------- bool cmCTest::CheckArgument(const std::string& arg, const char* varg1, const char* varg2) @@ -2231,6 +2229,22 @@ void cmCTest::HandleScriptArguments(size_t &i, } } +//---------------------------------------------------------------------- +bool cmCTest::AddVariableDefinition(const std::string &arg) +{ + std::string name; + std::string value; + cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED; + + if (cmCacheManager::ParseEntry(arg.c_str(), name, value, type)) + { + this->Definitions[name] = value; + return true; + } + + return false; +} + //---------------------------------------------------------------------- // the main entry point of ctest, called from main int cmCTest::Run(std::vector &args, std::string* output) @@ -2238,7 +2252,7 @@ int cmCTest::Run(std::vector &args, std::string* output) this->FindRunningCMake(); const char* ctestExec = "ctest"; bool cmakeAndTest = false; - bool performSomeTest = true; + bool executeTests = true; bool SRArgumentSpecified = false; // copy the command line @@ -2263,14 +2277,29 @@ int cmCTest::Run(std::vector &args, std::string* output) this->ProduceXML = true; i++; std::string targ = args[i]; - // AddTestsForDashboard parses the dashborad type and converts it + // AddTestsForDashboard parses the dashboard type and converts it // into the separate stages if (!this->AddTestsForDashboardType(targ)) { - performSomeTest = false; + if (!this->AddVariableDefinition(targ)) + { + this->ErrorMessageUnknownDashDValue(targ); + executeTests = false; + } } } + // If it's not exactly -D, but it starts with -D, then try to parse out + // a variable definition from it, same as CMake does. Unsuccessful + // attempts are simply ignored since previous ctest versions ignore + // this too. (As well as many other unknown command line args.) + // + if(arg != "-D" && cmSystemTools::StringStartsWith(arg.c_str(), "-D")) + { + std::string input = arg.substr(2); + this->AddVariableDefinition(input); + } + if(this->CheckArgument(arg, "-T", "--test-action") && (i < args.size() -1) ) { @@ -2278,7 +2307,7 @@ int cmCTest::Run(std::vector &args, std::string* output) i++; if ( !this->SetTest(args[i].c_str(), false) ) { - performSomeTest = false; + executeTests = false; cmCTestLog(this, ERROR_MESSAGE, "CTest -T called with incorrect option: " << args[i].c_str() << std::endl); @@ -2316,7 +2345,7 @@ int cmCTest::Run(std::vector &args, std::string* output) } else { - performSomeTest = false; + executeTests = false; cmCTestLog(this, ERROR_MESSAGE, "CTest -M called with incorrect option: " << str.c_str() << std::endl); @@ -2387,8 +2416,7 @@ int cmCTest::Run(std::vector &args, std::string* output) return retv; } - // if some tests must be run - if(performSomeTest) + if(executeTests) { int res; // call process directory diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 7c71b00ea..beffe9e7a 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -417,6 +417,12 @@ public: bool GetLabelSummary() { return this->LabelSummary;} std::string GetCostDataFile(); + + const std::map &GetDefinitions() + { + return this->Definitions; + } + private: std::string ConfigType; std::string ScheduleType; @@ -516,6 +522,12 @@ private: //! parse the option after -D and convert it into the appropriate steps bool AddTestsForDashboardType(std::string &targ); + //! read as "emit an error message for an unknown -D value" + void ErrorMessageUnknownDashDValue(std::string &val); + + //! add a variable definition from a command line -D value + bool AddVariableDefinition(const std::string &arg); + //! parse and process most common command line arguments void HandleCommandLineArguments(size_t &i, std::vector &args); @@ -558,6 +570,8 @@ private: int OutputLogFileLastTag; bool OutputTestOutputOnTestFailure; + + std::map Definitions; }; class cmCTestLogWrite diff --git a/Source/cmCommandArgumentsHelper.cxx b/Source/cmCommandArgumentsHelper.cxx index 1c906a65c..d92013788 100644 --- a/Source/cmCommandArgumentsHelper.cxx +++ b/Source/cmCommandArgumentsHelper.cxx @@ -178,7 +178,7 @@ bool cmCAString::DoConsume(const std::string& arg, unsigned int index) void cmCAString::DoReset() { - this->String = this->DefaultString; + this->String = ""; } cmCAEnabler::cmCAEnabler(cmCommandArgumentsHelper* args, diff --git a/Source/cmCommandArgumentsHelper.h b/Source/cmCommandArgumentsHelper.h index cb33ccd4b..3b0b058fd 100644 --- a/Source/cmCommandArgumentsHelper.h +++ b/Source/cmCommandArgumentsHelper.h @@ -125,11 +125,8 @@ class cmCAString : public cmCommandArgument /// Return the string const std::string& GetString() const {return this->String;} const char* GetCString() const {return this->String.c_str();} - void SetDefaultString(const char* text) - {this->DefaultString = (text ? text : "");} private: std::string String; - std::string DefaultString; unsigned int DataStart; virtual bool DoConsume(const std::string& arg, unsigned int index); virtual void DoReset(); diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 592d93164..77aaffcba 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -218,7 +218,7 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Full path to ctest command installed with cmake.", "This is the full path to the CTest executable ctest " "which is useful from custom commands that want " - " to use the cmake -E option for portable system " + "to use the cmake -E option for portable system " "commands.",false, "Variables that Provide Information"); @@ -355,7 +355,7 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "If this is set to TRUE, then the rpath information " "is not added to compiled executables. The default " "is to add rpath information if the platform supports it. " - "This allows for easy running from the build tree. To omit RPATH" + "This allows for easy running from the build tree. To omit RPATH " "in the install step, but not the build step, use " "CMAKE_SKIP_INSTALL_RPATH instead.",false, "Variables that Provide Information"); diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index 904a157b6..1b042ae6f 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -221,7 +221,7 @@ DOCUMENT_INTRO(CompatCommands, "cmakecompat", cmDocumentation::cmDocumentation() :CurrentFormatter(0) { - this->SetForm(TextForm); + this->SetForm(TextForm, 0); this->addCommonStandardDocSections(); this->ShowGenerators = true; } @@ -594,7 +594,7 @@ bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os) i != this->RequestedHelpItems.end(); ++i) { - this->SetForm(i->HelpForm); + this->SetForm(i->HelpForm, i->ManSection); this->CurrentArgument = i->Argument; // If a file name was given, use it. Otherwise, default to the // given stream. @@ -642,7 +642,8 @@ bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os) cmDocumentation::Form cmDocumentation::GetFormFromFilename( - const std::string& filename) + const std::string& filename, + int* manSection) { std::string ext = cmSystemTools::GetFilenameLastExtension(filename); ext = cmSystemTools::UpperCase(ext); @@ -659,6 +660,10 @@ cmDocumentation::Form cmDocumentation::GetFormFromFilename( // ".1" to ".9" should be manpages if ((ext.length()==2) && (ext[1] >='1') && (ext[1]<='9')) { + if (manSection) + { + *manSection = ext[1] - '0'; + } return cmDocumentation::ManForm; } @@ -1128,49 +1133,57 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, { help.HelpType = cmDocumentation::Properties; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-policies") == 0) { help.HelpType = cmDocumentation::Policies; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-variables") == 0) { help.HelpType = cmDocumentation::Variables; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-modules") == 0) { help.HelpType = cmDocumentation::Modules; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-custom-modules") == 0) { help.HelpType = cmDocumentation::CustomModules; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-commands") == 0) { help.HelpType = cmDocumentation::Commands; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-compatcommands") == 0) { help.HelpType = cmDocumentation::CompatCommands; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-full") == 0) { help.HelpType = cmDocumentation::Full; GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-html") == 0) { @@ -1183,6 +1196,7 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, help.HelpType = cmDocumentation::Full; GET_OPT_ARGUMENT(help.Filename); help.HelpForm = cmDocumentation::ManForm; + help.ManSection = 1; } else if(strcmp(argv[i], "--help-command") == 0) { @@ -1190,35 +1204,40 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); help.Argument = cmSystemTools::LowerCase(help.Argument); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-module") == 0) { help.HelpType = cmDocumentation::SingleModule; GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-property") == 0) { help.HelpType = cmDocumentation::SingleProperty; GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-policy") == 0) { help.HelpType = cmDocumentation::SinglePolicy; GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-variable") == 0) { help.HelpType = cmDocumentation::SingleVariable; GET_OPT_ARGUMENT(help.Argument); GET_OPT_ARGUMENT(help.Filename); - help.HelpForm = this->GetFormFromFilename(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename, + &help.ManSection); } else if(strcmp(argv[i], "--help-command-list") == 0) { @@ -1269,9 +1288,9 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv, } //---------------------------------------------------------------------------- -void cmDocumentation::Print(Form f, std::ostream& os) +void cmDocumentation::Print(Form f, int manSection, std::ostream& os) { - this->SetForm(f); + this->SetForm(f, manSection); this->Print(os); } @@ -1879,7 +1898,7 @@ void cmDocumentation::CreateFullDocumentation() } //---------------------------------------------------------------------------- -void cmDocumentation::SetForm(Form f) +void cmDocumentation::SetForm(Form f, int manSection) { switch(f) { @@ -1890,6 +1909,7 @@ void cmDocumentation::SetForm(Form f) this->CurrentFormatter = &this->DocbookFormatter; break; case ManForm: + this->ManFormatter.SetManSection(manSection); this->CurrentFormatter = &this->ManFormatter; break; case TextForm: diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h index 11bef1677..e180f60f5 100644 --- a/Source/cmDocumentation.h +++ b/Source/cmDocumentation.h @@ -33,7 +33,7 @@ class cmDocumentation: public cmDocumentationEnums { public: cmDocumentation(); - + ~cmDocumentation(); /** @@ -51,18 +51,18 @@ public: typedef std::list documentedModulesList_t; // High-level interface for standard documents: - + /** * Check command line arguments for documentation options. Returns * true if documentation options are found, and false otherwise. * When true is returned, PrintRequestedDocumentation should be - * called. exitOpt can be used for things like cmake -E, so that + * called. exitOpt can be used for things like cmake -E, so that * all arguments after the -E are ignored and not searched for * help arguments. */ - bool CheckOptions(int argc, const char* const* argv, + bool CheckOptions(int argc, const char* const* argv, const char* exitOpt =0); - + /** * Print help requested on the command line. Call after * CheckOptions returns true. Returns true on success, and false @@ -70,12 +70,12 @@ public: * command line cannot be written. */ bool PrintRequestedDocumentation(std::ostream& os); - + /** Print help of the given type. */ bool PrintDocumentation(Type ht, std::ostream& os, const char* docname=0); void SetShowGenerators(bool showGen) { this->ShowGenerators = showGen; } - + /** Set the program name for standard document generation. */ void SetName(const char* name); @@ -108,8 +108,8 @@ public: * Print documentation in the given form. All previously added * sections will be generated. */ - void Print(Form f, std::ostream& os); - + void Print(Form f, int manSection, std::ostream& os); + /** * Print documentation in the current form. All previously added * sections will be generated. @@ -125,15 +125,16 @@ public: void SetSeeAlsoList(const char *data[][3]); /** Clear all previously added sections of help. */ - void ClearSections(); - + void ClearSections(); + /** Set cmake root so we can find installed files */ void SetCMakeRoot(const char* root) { this->CMakeRoot = root;} /** Set CMAKE_MODULE_PATH so we can find additional cmake modules */ void SetCMakeModulePath(const char* path) { this->CMakeModulePath = path;} - - static Form GetFormFromFilename(const std::string& filename); + + static Form GetFormFromFilename(const std::string& filename, + int* ManSection); /** Add common (to all tools) documentation section(s) */ void addCommonStandardDocSections(); @@ -190,13 +191,13 @@ public: std::vector& commands, cmake* cm); private: - void SetForm(Form f); + void SetForm(Form f, int manSection); void SetDocName(const char* docname); - bool CreateSingleModule(const char* fname, + bool CreateSingleModule(const char* fname, const char* moduleName, cmDocumentationSection &sec); - void CreateModuleDocsForDir(cmsys::Directory& dir, + void CreateModuleDocsForDir(cmsys::Directory& dir, cmDocumentationSection &moduleSection); bool CreateModulesSection(); bool CreateCustomModulesSection(); @@ -236,7 +237,7 @@ private: std::string NameString; std::string DocName; std::map AllSections; - + std::string SeeAlsoString; std::string CMakeRoot; std::string CMakeModulePath; @@ -247,11 +248,12 @@ private: struct RequestedHelpItem { - RequestedHelpItem():HelpForm(TextForm), HelpType(None) {} + RequestedHelpItem():HelpForm(TextForm), HelpType(None), ManSection(1) {} cmDocumentationEnums::Form HelpForm; cmDocumentationEnums::Type HelpType; std::string Filename; std::string Argument; + int ManSection; }; std::vector RequestedHelpItems; diff --git a/Source/cmDocumentationFormatterMan.cxx b/Source/cmDocumentationFormatterMan.cxx index 79a3b25e6..4123c85cb 100644 --- a/Source/cmDocumentationFormatterMan.cxx +++ b/Source/cmDocumentationFormatterMan.cxx @@ -19,9 +19,15 @@ cmDocumentationFormatterMan::cmDocumentationFormatterMan() :cmDocumentationFormatter() +,ManSection(1) { } +void cmDocumentationFormatterMan::SetManSection(int manSection) +{ + this->ManSection = manSection; +} + void cmDocumentationFormatterMan ::PrintSection(std::ostream& os, const cmDocumentationSection §ion, @@ -32,9 +38,9 @@ void cmDocumentationFormatterMan os << ".SH " << name << "\n"; } - const std::vector &entries = + const std::vector &entries = section.GetEntries(); - for(std::vector::const_iterator op = entries.begin(); + for(std::vector::const_iterator op = entries.begin(); op != entries.end(); ++op) { if(op->Name.size()) @@ -58,7 +64,7 @@ void cmDocumentationFormatterMan::EscapeText(std::string& man_text) cmSystemTools::ReplaceString(man_text, "-", "\\-"); } -void cmDocumentationFormatterMan::PrintPreformatted(std::ostream& os, +void cmDocumentationFormatterMan::PrintPreformatted(std::ostream& os, const char* text) { std::string man_text = text; @@ -69,7 +75,7 @@ void cmDocumentationFormatterMan::PrintPreformatted(std::ostream& os, os << ".fi\n\n"; } -void cmDocumentationFormatterMan::PrintParagraph(std::ostream& os, +void cmDocumentationFormatterMan::PrintParagraph(std::ostream& os, const char* text) { std::string man_text = text; @@ -87,7 +93,7 @@ void cmDocumentationFormatterMan::PrintHeader(const char* docname, this->EscapeText(s_docname); this->EscapeText(s_appname); - os << ".TH " << s_docname << " 1 \"" + os << ".TH " << s_docname << " " << this->ManSection << " \"" << cmSystemTools::GetCurrentDateTime("%B %d, %Y").c_str() << "\" \"" << s_appname << " " << cmVersion::GetCMakeVersion() diff --git a/Source/cmDocumentationFormatterMan.h b/Source/cmDocumentationFormatterMan.h index 11b5acbb3..b3d069c36 100644 --- a/Source/cmDocumentationFormatterMan.h +++ b/Source/cmDocumentationFormatterMan.h @@ -22,6 +22,8 @@ class cmDocumentationFormatterMan : public cmDocumentationFormatter public: cmDocumentationFormatterMan(); + void SetManSection(int manSection); + virtual cmDocumentationEnums::Form GetForm() const { return cmDocumentationEnums::ManForm;} @@ -35,6 +37,7 @@ public: private: void EscapeText(std::string& man_text); + int ManSection; }; #endif diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 5df8627d0..ad4ab76ee 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -60,9 +60,7 @@ cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator() // disable until somebody actually tests it: // this->SupportedGlobalGenerators.push_back("MSYS Makefiles"); #endif -#ifdef CMAKE_USE_NINJA this->SupportedGlobalGenerators.push_back("Ninja"); -#endif this->SupportedGlobalGenerators.push_back("Unix Makefiles"); } diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index ab113075d..78a87047a 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -34,9 +34,7 @@ cmExtraEclipseCDT4Generator this->SupportedGlobalGenerators.push_back("MinGW Makefiles"); // this->SupportedGlobalGenerators.push_back("MSYS Makefiles"); #endif -#ifdef CMAKE_USE_NINJA this->SupportedGlobalGenerators.push_back("Ninja"); -#endif this->SupportedGlobalGenerators.push_back("Unix Makefiles"); this->SupportsVirtualFolders = true; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index c3989c046..3f3cfbbb1 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -160,34 +160,35 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, arguments << "\n"; - - cmOStringStream builds; + cmOStringStream build; // Write outputs files. - builds << "build"; + build << "build"; for(cmNinjaDeps::const_iterator i = outputs.begin(); - i != outputs.end(); - ++i) - builds << " " << EncodeIdent(EncodePath(*i), os); - builds << ":"; - + i != outputs.end(); ++i) + build << " " << EncodeIdent(EncodePath(*i), os); + build << ":"; // Write the rule. - builds << " " << rule; + build << " " << rule; + + // Write the variables bound to this build statement. + cmOStringStream variable_assignments; + for(cmNinjaVars::const_iterator i = variables.begin(); + i != variables.end(); ++i) + cmGlobalNinjaGenerator::WriteVariable(variable_assignments, + i->first, i->second, "", 1); // check if a response file rule should be used + std::string buildstr = build.str(); + const std::string assignments = variable_assignments.str(); const std::string args = arguments.str(); - if (cmdLineLimit > 0 && - (args.size() + + builds.str().size()) > (size_t)cmdLineLimit) - builds << "_RSPFILE"; - - os << builds.str() << args; + if (cmdLineLimit > 0 + && args.size() + buildstr.size() + assignments.size() + > (size_t) cmdLineLimit) + buildstr += "_RSPFILE"; - // Write the variables bound to this build statement. - for(cmNinjaVars::const_iterator i = variables.begin(); - i != variables.end(); - ++i) - cmGlobalNinjaGenerator::WriteVariable(os, i->first, i->second, "", 1); + os << buildstr << args << assignments; } void cmGlobalNinjaGenerator::WritePhonyBuild(std::ostream& os, @@ -216,6 +217,7 @@ void cmGlobalNinjaGenerator::AddCustomCommandRule() "Rule for running custom commands.", /*depfile*/ "", /*rspfile*/ "", + /*rspcontent*/ "", /*restat*/ true); } @@ -250,6 +252,48 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, vars); } +void +cmGlobalNinjaGenerator::AddMacOSXContentRule() +{ + cmLocalGenerator *lg = this->LocalGenerators[0]; + cmMakefile* mfRoot = lg->GetMakefile(); + + cmOStringStream cmd; + cmd << lg->ConvertToOutputFormat( + mfRoot->GetRequiredDefinition("CMAKE_COMMAND"), + cmLocalGenerator::SHELL) + << " -E copy $in $out"; + + this->AddRule("COPY_OSX_CONTENT", + cmd.str(), + "Copying OS X Content $out", + "Rule for copying OS X bundle content file." + /*depfile*/ "", + /*rspfile*/ ""); +} + +void +cmGlobalNinjaGenerator::WriteMacOSXContentBuild(const std::string& input, + const std::string& output) +{ + this->AddMacOSXContentRule(); + + cmNinjaDeps outputs; + outputs.push_back(output); + cmNinjaDeps deps; + deps.push_back(input); + cmNinjaVars vars; + + cmGlobalNinjaGenerator::WriteBuild(*this->BuildFileStream, + "", + "COPY_OSX_CONTENT", + outputs, + deps, + cmNinjaDeps(), + cmNinjaDeps(), + cmNinjaVars()); +} + void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, const std::string& name, const std::string& command, @@ -257,6 +301,7 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, const std::string& comment, const std::string& depfile, const std::string& rspfile, + const std::string& rspcontent, bool restat, bool generator) { @@ -303,10 +348,15 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, if(!rspfile.empty()) { - cmGlobalNinjaGenerator::Indent(os, 1); - os << "rspfile = " << rspfile << "\n"; - cmGlobalNinjaGenerator::Indent(os, 1); - os << "rspfile_content = $in" << "\n"; + if (rspcontent.empty()) + { + cmSystemTools::Error("No rspfile_content given!", comment.c_str()); + return; + } + cmGlobalNinjaGenerator::Indent(os, 1); + os << "rspfile = " << rspfile << "\n"; + cmGlobalNinjaGenerator::Indent(os, 1); + os << "rspfile_content = " << rspcontent << "\n"; } if(restat) @@ -466,10 +516,33 @@ void cmGlobalNinjaGenerator if(mf->IsOn("CMAKE_COMPILER_IS_MINGW")) { UsingMinGW = true; - std::string rc = cmSystemTools::FindProgram("windres"); - if(rc.empty()) - rc = "windres.exe";; - mf->AddDefinition("CMAKE_RC_COMPILER", rc.c_str()); + if(!mf->GetDefinition("CMAKE_RC_COMPILER")) + { + std::string windres = cmSystemTools::FindProgram("windres"); + if(windres.empty()) + { + std::string compiler_path; + std::string::size_type prefix = std::string::npos; + if (mf->GetDefinition("CMAKE_C_COMPILER")) + { + compiler_path = mf->GetDefinition("CMAKE_C_COMPILER"); + prefix = compiler_path.rfind("gcc"); + } + else if (mf->GetDefinition("CMAKE_CXX_COMPILER")) + { + compiler_path = mf->GetDefinition("CMAKE_CXX_COMPILER"); + prefix = compiler_path.rfind("++"); + prefix--; + } + if (prefix != std::string::npos) + { + windres = compiler_path.substr(0, prefix) + "windres"; + windres = cmSystemTools::FindProgram(windres.c_str()); + } + } + if(!windres.empty()) + mf->AddDefinition("CMAKE_RC_COMPILER", windres.c_str()); + } } } this->cmGlobalGenerator::EnableLanguage(language, mf, optional); @@ -537,6 +610,7 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name, const std::string& comment, const std::string& depfile, const std::string& rspfile, + const std::string& rspcontent, bool restat, bool generator) { @@ -554,8 +628,11 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name, comment, depfile, rspfile, + rspcontent, restat, generator); + + this->RuleCmdLength[name] = (int) command.size(); } bool cmGlobalNinjaGenerator::HasRule(const std::string &name) @@ -701,13 +778,22 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand( *this->CompileCommandsStream << "," << std::endl; } + std::string sourceFileName = sourceFile; + if (!cmSystemTools::FileIsFullPath(sourceFileName.c_str())) + { + sourceFileName = cmSystemTools::CollapseFullPath( + sourceFileName.c_str(), + this->GetCMakeInstance()->GetHomeOutputDirectory()); + } + + *this->CompileCommandsStream << "\n{\n" << " \"directory\": \"" << cmGlobalGenerator::EscapeJSON(buildFileDir) << "\",\n" << " \"command\": \"" << cmGlobalGenerator::EscapeJSON(commandLine) << "\",\n" << " \"file\": \"" - << cmGlobalGenerator::EscapeJSON(sourceFile) << "\"\n" + << cmGlobalGenerator::EscapeJSON(sourceFileName) << "\"\n" << "}"; } @@ -737,6 +823,11 @@ void cmGlobalNinjaGenerator::AddDependencyToAll(cmTarget* target) this->AppendTargetOutputs(target, this->AllDependencies); } +void cmGlobalNinjaGenerator::AddDependencyToAll(const std::string& input) +{ + this->AllDependencies.push_back(input); +} + void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() { for (std::map >::iterator @@ -899,6 +990,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) "Rule for re-running cmake.", /*depfile=*/ "", /*rspfile=*/ "", + /*rspcontent*/ "", /*restat=*/ false, /*generator=*/ true); @@ -948,6 +1040,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) "Rule for cleaning all built files.", /*depfile=*/ "", /*rspfile=*/ "", + /*rspcontent*/ "", /*restat=*/ false, /*generator=*/ false); WriteBuild(os, @@ -964,11 +1057,12 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) { WriteRule(*this->RulesFileStream, "HELP", - (ninjaCmd() + " -t tagets").c_str(), + (ninjaCmd() + " -t targets").c_str(), "All primary targets available:", "Rule for printing all primary targets available.", /*depfile=*/ "", /*rspfile=*/ "", + /*rspcontent*/ "", /*restat=*/ false, /*generator=*/ false); WriteBuild(os, diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index e939f6149..b2fe24327 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -103,6 +103,8 @@ public: const cmNinjaDeps& outputs, const cmNinjaDeps& deps = cmNinjaDeps(), const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps()); + void WriteMacOSXContentBuild(const std::string& input, + const std::string& output); /** * Write a rule statement named @a name to @a os with the @a comment, @@ -114,11 +116,12 @@ public: const std::string& name, const std::string& command, const std::string& description, - const std::string& comment = "", - const std::string& depfile = "", - const std::string& rspfile = "" , - bool restat = false, - bool generator = false); + const std::string& comment, + const std::string& depfile, + const std::string& rspfile, + const std::string& rspcontent, + bool restat, + bool generator); /** * Write a variable named @a name to @a os with value @a value and an @@ -150,6 +153,7 @@ public: static bool IsMinGW() { return UsingMinGW; } + public: /// Default constructor. cmGlobalNinjaGenerator(); @@ -213,12 +217,12 @@ public: } virtual const char* GetCleanTargetName() const { return "clean"; } -public: - cmGeneratedFileStream* GetBuildFileStream() const - { return this->BuildFileStream; } - cmGeneratedFileStream* GetRulesFileStream() const - { return this->RulesFileStream; } + cmGeneratedFileStream* GetBuildFileStream() const { + return this->BuildFileStream; } + + cmGeneratedFileStream* GetRulesFileStream() const { + return this->RulesFileStream; } void AddCXXCompileCommand(const std::string &commandLine, const std::string &sourceFile); @@ -231,15 +235,62 @@ public: void AddRule(const std::string& name, const std::string& command, const std::string& description, - const std::string& comment = "", + const std::string& comment, const std::string& depfile = "", const std::string& rspfile = "", + const std::string& rspcontent = "", bool restat = false, bool generator = false); bool HasRule(const std::string& name); void AddCustomCommandRule(); + void AddMacOSXContentRule(); + + bool HasCustomCommandOutput(const std::string &output) { + return this->CustomCommandOutputs.find(output) != + this->CustomCommandOutputs.end(); + } + + /// Called when we have seen the given custom command. Returns true + /// if we has seen it before. + bool SeenCustomCommand(cmCustomCommand const *cc) { + return !this->CustomCommands.insert(cc).second; + } + + /// Called when we have seen the given custom command output. + void SeenCustomCommandOutput(const std::string &output) { + this->CustomCommandOutputs.insert(output); + // We don't need the assumed dependencies anymore, because we have + // an output. + this->AssumedSourceDependencies.erase(output); + } + + void AddAssumedSourceDependencies(const std::string &source, + const cmNinjaDeps &deps) { + std::set &ASD = this->AssumedSourceDependencies[source]; + // Because we may see the same source file multiple times (same source + // specified in multiple targets), compute the union of any assumed + // dependencies. + ASD.insert(deps.begin(), deps.end()); + } + + void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs); + void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs); + void AddDependencyToAll(cmTarget* target); + void AddDependencyToAll(const std::string& input); + + const std::vector& GetLocalGenerators() const { + return LocalGenerators; } + + bool IsExcluded(cmLocalGenerator* root, cmTarget& target) { + return cmGlobalGenerator::IsExcluded(root, target); } + + int GetRuleCmdLength(const std::string& name) { + return RuleCmdLength[name]; } + + void AddTargetAlias(const std::string& alias, cmTarget* target); + protected: @@ -247,21 +298,12 @@ protected: /// @see cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { return true; } + private: /// @see cmGlobalGenerator::ComputeTargetObjects virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const; -private: - // In order to access the AddDependencyToAll() functions and co. - friend class cmLocalNinjaGenerator; - - // In order to access the SeenCustomCommand() function. - friend class cmNinjaTargetGenerator; - friend class cmNinjaNormalTargetGenerator; - friend class cmNinjaUtilityTargetGenerator; - -private: void OpenBuildFileStream(); void CloseBuildFileStream(); @@ -273,14 +315,8 @@ private: /// Write the common disclaimer text at the top of each build file. void WriteDisclaimer(std::ostream& os); - void AddDependencyToAll(cmTarget* target); - void WriteAssumedSourceDependencies(); - void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs); - void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs); - - void AddTargetAlias(const std::string& alias, cmTarget* target); void WriteTargetAliases(std::ostream& os); void WriteBuiltinTargets(std::ostream& os); @@ -289,37 +325,9 @@ private: void WriteTargetClean(std::ostream& os); void WriteTargetHelp(std::ostream& os); - /// Called when we have seen the given custom command. Returns true - /// if we has seen it before. - bool SeenCustomCommand(cmCustomCommand const *cc) { - return !this->CustomCommands.insert(cc).second; - } - - /// Called when we have seen the given custom command output. - void SeenCustomCommandOutput(const std::string &output) { - this->CustomCommandOutputs.insert(output); - // We don't need the assumed dependencies anymore, because we have - // an output. - this->AssumedSourceDependencies.erase(output); - } - - bool HasCustomCommandOutput(const std::string &output) { - return this->CustomCommandOutputs.find(output) != - this->CustomCommandOutputs.end(); - } - - void AddAssumedSourceDependencies(const std::string &source, - const cmNinjaDeps &deps) { - std::set &ASD = this->AssumedSourceDependencies[source]; - // Because we may see the same source file multiple times (same source - // specified in multiple targets), compute the union of any assumed - // dependencies. - ASD.insert(deps.begin(), deps.end()); - } - std::string ninjaCmd() const; -private: + /// The file containing the build statement. (the relation ship of the /// compilation DAG). cmGeneratedFileStream* BuildFileStream; @@ -335,6 +343,9 @@ private: /// The set of rules added to the generated build system. RulesSetType Rules; + /// Length of rule command, used by rsp file evaluation + std::map RuleCmdLength; + /// The set of dependencies to add to the "all" target. cmNinjaDeps AllDependencies; diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h index 83ea8a474..94e4d998a 100644 --- a/Source/cmIfCommand.h +++ b/Source/cmIfCommand.h @@ -123,6 +123,7 @@ public: " if()\n" "True if the variable is defined to a value that is not a false " "constant. False otherwise. " + "(Note macro arguments are not variables.)" "\n" " if(NOT )\n" "True if the expression is not true." diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx index 0ac6df46a..0d5f67b78 100644 --- a/Source/cmIncludeCommand.cxx +++ b/Source/cmIncludeCommand.cxx @@ -70,6 +70,13 @@ bool cmIncludeCommand } } + if(fname.empty()) + { + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, + "include() given empty file name (ignored)."); + return true; + } + if(!cmSystemTools::FileIsFullPath(fname.c_str())) { // Not a path. Maybe module. diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h index bf9fd9ed3..76e622e81 100644 --- a/Source/cmInstallCommand.h +++ b/Source/cmInstallCommand.h @@ -85,7 +85,10 @@ public: "with which the install rule is associated, such as \"runtime\" or " "\"development\". During component-specific installation only " "install rules associated with the given component name will be " - "executed. During a full installation all components are installed.\n" + "executed. During a full installation all components are installed." + " If COMPONENT is not provided a default component \"Unspecified\" is" + " created. The default component name may be controlled with the " + "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME variable.\n" "The RENAME argument specifies a name for an installed file that " "may be different from the original file. Renaming is allowed only " "when a single file is installed by the command.\n" diff --git a/Source/cmInstallCommandArguments.cxx b/Source/cmInstallCommandArguments.cxx index 0ba21c7ad..8e48f08e6 100644 --- a/Source/cmInstallCommandArguments.cxx +++ b/Source/cmInstallCommandArguments.cxx @@ -36,8 +36,8 @@ cmInstallCommandArguments::cmInstallCommandArguments( ,NamelinkOnly (&Parser, "NAMELINK_ONLY" , &ArgumentGroup) ,NamelinkSkip (&Parser, "NAMELINK_SKIP" , &ArgumentGroup) ,GenericArguments(0) +,DefaultComponentName(defaultComponent) { - this->Component.SetDefaultString(defaultComponent.c_str()); } const std::string& cmInstallCommandArguments::GetDestination() const @@ -63,7 +63,10 @@ const std::string& cmInstallCommandArguments::GetComponent() const { return this->GenericArguments->GetComponent(); } - + if (!this->DefaultComponentName.empty()) + { + return this->DefaultComponentName; + } static std::string unspecifiedComponent = "Unspecified"; return unspecifiedComponent; } diff --git a/Source/cmInstallCommandArguments.h b/Source/cmInstallCommandArguments.h index 321454a59..01f7d5679 100644 --- a/Source/cmInstallCommandArguments.h +++ b/Source/cmInstallCommandArguments.h @@ -61,6 +61,7 @@ class cmInstallCommandArguments cmInstallCommandArguments* GenericArguments; static const char* PermissionsTable[]; static const std::string EmptyString; + std::string DefaultComponentName; bool CheckPermissions(); }; diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 9a496f294..d902f4ef7 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -61,7 +61,7 @@ void cmLocalNinjaGenerator::Generate() tg->Generate(); // Add the target to "all" if required. if (!this->GetGlobalNinjaGenerator()->IsExcluded( - this->GetGlobalNinjaGenerator()->LocalGenerators[0], + this->GetGlobalNinjaGenerator()->GetLocalGenerators()[0], t->second)) this->GetGlobalNinjaGenerator()->AddDependencyToAll(&t->second); delete tg; @@ -272,7 +272,7 @@ std::string cmLocalNinjaGenerator::BuildCommandLine( // don't use POST_BUILD. if (cmdLines.empty()) #ifdef _WIN32 - return "cd."; + return "cd ."; #else return ":"; #endif diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index ea44b2fe2..c450841af 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -45,7 +45,6 @@ public: /// Overloaded methods. @see cmLocalGenerator::GetTargetDirectory() virtual std::string GetTargetDirectory(cmTarget const& target) const; -public: const cmGlobalNinjaGenerator* GetGlobalNinjaGenerator() const; cmGlobalNinjaGenerator* GetGlobalNinjaGenerator(); @@ -67,33 +66,8 @@ public: std::string GetHomeRelativeOutputPath() const { return this->HomeRelativeOutputPath; } -protected: - virtual std::string ConvertToLinkReference(std::string const& lib); - virtual std::string ConvertToIncludeReference(std::string const& path); - -private: - friend class cmGlobalNinjaGenerator; - - // In order to access to protected member of the local generator. - friend class cmNinjaTargetGenerator; - friend class cmNinjaNormalTargetGenerator; - friend class cmNinjaUtilityTargetGenerator; - -private: - cmGeneratedFileStream& GetBuildFileStream() const; - cmGeneratedFileStream& GetRulesFileStream() const; - - void WriteBuildFileTop(); - void WriteProjectHeader(std::ostream& os); - void WriteNinjaFilesInclusion(std::ostream& os); - void WriteProcessedMakefile(std::ostream& os); - - void SetConfigName(); - std::string ConvertToNinjaPath(const char *path); - struct map_to_ninja_path; - friend struct map_to_ninja_path; struct map_to_ninja_path { cmLocalNinjaGenerator *LocalGenerator; map_to_ninja_path(cmLocalNinjaGenerator *LocalGen) @@ -102,26 +76,52 @@ private: return LocalGenerator->ConvertToNinjaPath(path.c_str()); } }; + map_to_ninja_path MapToNinjaPath() { return map_to_ninja_path(this); } + void ExpandRuleVariables(std::string& string, + const RuleVariables& replaceValues) { + cmLocalGenerator::ExpandRuleVariables(string, replaceValues); + } + + std::string BuildCommandLine(const std::vector &cmdLines); + void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs); void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs); - void AppendCustomCommandDeps(const cmCustomCommand *cc, - cmNinjaDeps &ninjaDeps); - std::string BuildCommandLine(const std::vector &cmdLines); + void AddCustomCommandTarget(cmCustomCommand const* cc, cmTarget* target); void AppendCustomCommandLines(const cmCustomCommand *cc, std::vector &cmdLines); + void AppendCustomCommandDeps(const cmCustomCommand *cc, + cmNinjaDeps &ninjaDeps); + + virtual std::string ConvertToLinkReference(std::string const& lib); + + +protected: + virtual std::string ConvertToIncludeReference(std::string const& path); + + +private: + cmGeneratedFileStream& GetBuildFileStream() const; + cmGeneratedFileStream& GetRulesFileStream() const; + + void WriteBuildFileTop(); + void WriteProjectHeader(std::ostream& os); + void WriteNinjaFilesInclusion(std::ostream& os); + void WriteProcessedMakefile(std::ostream& os); + + void SetConfigName(); + void WriteCustomCommandRule(); void WriteCustomCommandBuildStatement(cmCustomCommand const *cc, const cmNinjaDeps& orderOnlyDeps); - void AddCustomCommandTarget(cmCustomCommand const* cc, cmTarget* target); void WriteCustomCommandBuildStatements(); -private: + std::string ConfigName; std::string HomeRelativeOutputPath; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 78278cbbf..ab5150a36 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -29,13 +29,19 @@ cmMakefileExecutableTargetGenerator this->TargetNameOut, this->TargetNameReal, this->TargetNameImport, this->TargetNamePDB, this->ConfigName); - if(this->Target->IsAppBundleOnApple()) - { - this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += ".app/Contents/"; - } + this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target, + this->TargetNameOut, + this->ConfigName); + this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + this->MacContentDirectory = + this->OSXBundleGenerator->GetMacContentDirectory(); +} + +//---------------------------------------------------------------------------- +cmMakefileExecutableTargetGenerator +::~cmMakefileExecutableTargetGenerator() +{ + delete this->OSXBundleGenerator; } //---------------------------------------------------------------------------- @@ -100,7 +106,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) outpath += "/"; if(this->Target->IsAppBundleOnApple()) { - this->CreateAppBundle(targetName, outpath); + this->OSXBundleGenerator->CreateAppBundle(targetName, outpath); } std::string outpathImp; if(relink) @@ -129,7 +135,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) std::string targetFullPathReal = outpath + targetNameReal; std::string targetFullPathPDB = outpath + targetNamePDB; std::string targetFullPathImport = outpathImp + targetNameImport; - std::string targetOutPathPDB = + std::string targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(), cmLocalGenerator::NONE, cmLocalGenerator::SHELL); @@ -440,24 +446,3 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) exeCleanFiles.begin(), exeCleanFiles.end()); } - -//---------------------------------------------------------------------------- -void -cmMakefileExecutableTargetGenerator::CreateAppBundle(std::string& targetName, - std::string& outpath) -{ - // Compute bundle directory names. - outpath = this->MacContentDirectory; - outpath += "MacOS"; - cmSystemTools::MakeDirectory(outpath.c_str()); - this->Makefile->AddCMakeOutputFile(outpath.c_str()); - outpath += "/"; - - // Configure the Info.plist file. Note that it needs the executable name - // to be set. - std::string plist = this->MacContentDirectory + "Info.plist"; - this->LocalGenerator->GenerateAppleInfoPList(this->Target, - targetName.c_str(), - plist.c_str()); - this->Makefile->AddCMakeOutputFile(plist.c_str()); -} diff --git a/Source/cmMakefileExecutableTargetGenerator.h b/Source/cmMakefileExecutableTargetGenerator.h index 985f207e7..3b18166ff 100644 --- a/Source/cmMakefileExecutableTargetGenerator.h +++ b/Source/cmMakefileExecutableTargetGenerator.h @@ -18,14 +18,14 @@ class cmMakefileExecutableTargetGenerator: public cmMakefileTargetGenerator { public: cmMakefileExecutableTargetGenerator(cmTarget* target); + virtual ~cmMakefileExecutableTargetGenerator(); /* the main entry point for this class. Writes the Makefiles associated with this target */ virtual void WriteRuleFiles(); - + protected: virtual void WriteExecutableRule(bool relink); - void CreateAppBundle(std::string& targetName, std::string& outpath); }; #endif diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index db59ffdd6..577e5fd07 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -26,41 +26,26 @@ cmMakefileLibraryTargetGenerator ::cmMakefileLibraryTargetGenerator(cmTarget* target): cmMakefileTargetGenerator(target) { - if(this->Target->IsCFBundleOnApple()) - { - target->SetProperty("PREFIX", ""); - target->SetProperty("SUFFIX", ""); - } + cmOSXBundleGenerator::PrepareTargetProperties(this->Target); this->CustomCommandDriver = OnDepends; this->Target->GetLibraryNames( this->TargetNameOut, this->TargetNameSO, this->TargetNameReal, this->TargetNameImport, this->TargetNamePDB, this->ConfigName); - if(this->Target->IsFrameworkOnApple()) - { - this->FrameworkVersion = this->Target->GetFrameworkVersion(); - this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += ".framework/Versions/"; - this->MacContentDirectory += this->FrameworkVersion; - this->MacContentDirectory += "/"; - } - else if(this->Target->IsCFBundleOnApple()) - { - this->MacContentDirectory = this->Target->GetDirectory(this->ConfigName); - this->MacContentDirectory += "/"; - this->MacContentDirectory += this->TargetNameOut; - this->MacContentDirectory += "."; - const char *ext = this->Target->GetProperty("BUNDLE_EXTENSION"); - if (!ext) - { - ext = "bundle"; - } - this->MacContentDirectory += ext; - this->MacContentDirectory += "/Contents/"; - } + this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target, + this->TargetNameOut, + this->ConfigName); + this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + this->MacContentDirectory = + this->OSXBundleGenerator->GetMacContentDirectory(); +} + +//---------------------------------------------------------------------------- +cmMakefileLibraryTargetGenerator +::~cmMakefileLibraryTargetGenerator() +{ + delete this->OSXBundleGenerator; } //---------------------------------------------------------------------------- @@ -199,7 +184,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink) linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName); this->LocalGenerator->AppendFlags (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str())); - + this->LocalGenerator->AddConfigVariableFlags (extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName); this->AddModuleDefinitionFlag(extraFlags); @@ -220,7 +205,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink) linkRuleVar += "_CREATE_SHARED_MODULE"; std::string extraFlags; - this->LocalGenerator->AppendFlags(extraFlags, + this->LocalGenerator->AppendFlags(extraFlags, this->Target->GetProperty("LINK_FLAGS")); std::string linkFlagsConfig = "LINK_FLAGS_"; linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName); @@ -246,7 +231,7 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink) linkRuleVar += "_CREATE_MACOSX_FRAMEWORK"; std::string extraFlags; - this->LocalGenerator->AppendFlags(extraFlags, + this->LocalGenerator->AppendFlags(extraFlags, this->Target->GetProperty("LINK_FLAGS")); std::string linkFlagsConfig = "LINK_FLAGS_"; linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName); @@ -258,115 +243,6 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink) this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink); } -//---------------------------------------------------------------------------- -void -cmMakefileLibraryTargetGenerator -::CreateFramework(std::string const& targetName) -{ - // Configure the Info.plist file into the Resources directory. - this->MacContentFolders.insert("Resources"); - std::string plist = this->MacContentDirectory + "Resources/Info.plist"; - this->LocalGenerator->GenerateFrameworkInfoPList(this->Target, - targetName.c_str(), - plist.c_str()); - - // TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to - // drive rules to create these files at build time. - std::string oldName; - std::string newName; - - // Compute the location of the top-level foo.framework directory. - std::string top = this->Target->GetDirectory(this->ConfigName); - top += "/"; - top += this->TargetNameOut; - top += ".framework/"; - - // Make foo.framework/Versions - std::string versions = top; - versions += "Versions"; - cmSystemTools::MakeDirectory(versions.c_str()); - - // Make foo.framework/Versions/version - std::string version = versions; - version += "/"; - version += this->FrameworkVersion; - cmSystemTools::MakeDirectory(version.c_str()); - - // Current -> version - oldName = this->FrameworkVersion; - newName = versions; - newName += "/Current"; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); - - // foo -> Versions/Current/foo - oldName = "Versions/Current/"; - oldName += this->TargetNameOut; - newName = top; - newName += this->TargetNameOut; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); - - // Resources -> Versions/Current/Resources - if(this->MacContentFolders.find("Resources") != - this->MacContentFolders.end()) - { - oldName = "Versions/Current/Resources"; - newName = top; - newName += "Resources"; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); - } - - // Headers -> Versions/Current/Headers - if(this->MacContentFolders.find("Headers") != - this->MacContentFolders.end()) - { - oldName = "Versions/Current/Headers"; - newName = top; - newName += "Headers"; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); - } - - // PrivateHeaders -> Versions/Current/PrivateHeaders - if(this->MacContentFolders.find("PrivateHeaders") != - this->MacContentFolders.end()) - { - oldName = "Versions/Current/PrivateHeaders"; - newName = top; - newName += "PrivateHeaders"; - cmSystemTools::RemoveFile(newName.c_str()); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); - } -} - -//---------------------------------------------------------------------------- -void -cmMakefileLibraryTargetGenerator::CreateCFBundle(std::string& targetName, - std::string& outpath) -{ - // Compute bundle directory names. - outpath = this->MacContentDirectory; - outpath += "MacOS"; - cmSystemTools::MakeDirectory(outpath.c_str()); - this->Makefile->AddCMakeOutputFile(outpath.c_str()); - outpath += "/"; - - // Configure the Info.plist file. Note that it needs the executable name - // to be set. - std::string plist = this->MacContentDirectory + "Info.plist"; - this->LocalGenerator->GenerateAppleInfoPList(this->Target, - targetName.c_str(), - plist.c_str()); - this->Makefile->AddCMakeOutputFile(plist.c_str()); -} - //---------------------------------------------------------------------------- void cmMakefileLibraryTargetGenerator::WriteLibraryRules (const char* linkRuleVar, const char* extraFlags, bool relink) @@ -419,13 +295,13 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules if(this->Target->IsFrameworkOnApple()) { outpath = this->MacContentDirectory; - this->CreateFramework(targetName); + this->OSXBundleGenerator->CreateFramework(targetName); } else if(this->Target->IsCFBundleOnApple()) { outpath = this->Target->GetDirectory(this->ConfigName); outpath += "/"; - this->CreateCFBundle(targetName, outpath); + this->OSXBundleGenerator->CreateCFBundle(targetName, outpath); } else if(relink) { @@ -460,16 +336,16 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules // Construct the output path version of the names for use in command // arguments. - std::string targetOutPathPDB = + std::string targetOutPathPDB = this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE, cmLocalGenerator::SHELL); - std::string targetOutPath = + std::string targetOutPath = this->Convert(targetFullPath.c_str(),cmLocalGenerator::START_OUTPUT, cmLocalGenerator::SHELL); - std::string targetOutPathSO = + std::string targetOutPathSO = this->Convert(targetFullPathSO.c_str(),cmLocalGenerator::START_OUTPUT, cmLocalGenerator::SHELL); - std::string targetOutPathReal = + std::string targetOutPathReal = this->Convert(targetFullPathReal.c_str(),cmLocalGenerator::START_OUTPUT, cmLocalGenerator::SHELL); std::string targetOutPathImport = @@ -569,7 +445,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules std::vector commands1; // Add a command to remove any existing files for this library. - // for static libs only + // for static libs only if(this->Target->GetType() == cmTarget::STATIC_LIBRARY) { this->LocalGenerator->AppendCleanCommand(commands1, libCleanFiles, diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h index e6a5867ea..07f828b7d 100644 --- a/Source/cmMakefileLibraryTargetGenerator.h +++ b/Source/cmMakefileLibraryTargetGenerator.h @@ -14,16 +14,17 @@ #include "cmMakefileTargetGenerator.h" -class cmMakefileLibraryTargetGenerator: +class cmMakefileLibraryTargetGenerator: public cmMakefileTargetGenerator { public: cmMakefileLibraryTargetGenerator(cmTarget* target); + virtual ~cmMakefileLibraryTargetGenerator(); /* the main entry point for this class. Writes the Makefiles associated with this target */ - virtual void WriteRuleFiles(); - + virtual void WriteRuleFiles(); + protected: void WriteObjectLibraryRules(); void WriteStaticLibraryRules(); @@ -33,8 +34,6 @@ protected: bool relink); // MacOSX Framework support methods void WriteFrameworkRules(bool relink); - void CreateFramework(std::string const& targetName); - void CreateCFBundle(std::string& targetName, std::string& outpath); // Store the computd framework version for OS X Frameworks. std::string FrameworkVersion; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 16e3e026c..0de182ede 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -28,6 +28,8 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target) + : OSXBundleGenerator(0) + , MacOSXContentGenerator(0) { this->BuildFileStream = 0; this->InfoFileStream = 0; @@ -50,6 +52,12 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target) { this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus); } + MacOSXContentGenerator = new MacOSXContentGeneratorType(this); +} + +cmMakefileTargetGenerator::~cmMakefileTargetGenerator() +{ + delete MacOSXContentGenerator; } cmMakefileTargetGenerator * @@ -153,8 +161,12 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() } } } - this->WriteMacOSXContentRules(this->GeneratorTarget->HeaderSources); - this->WriteMacOSXContentRules(this->GeneratorTarget->ExtraSources); + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + this->GeneratorTarget->HeaderSources, + this->MacOSXContentGenerator); + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + this->GeneratorTarget->ExtraSources, + this->MacOSXContentGenerator); for(std::vector::const_iterator si = this->GeneratorTarget->ExternalObjects.begin(); si != this->GeneratorTarget->ExternalObjects.end(); ++si) @@ -173,7 +185,6 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects); } - //---------------------------------------------------------------------------- void cmMakefileTargetGenerator::WriteCommonCodeRules() { @@ -343,44 +354,20 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags() } } -//---------------------------------------------------------------------------- -void cmMakefileTargetGenerator::WriteMacOSXContentRules( - std::vector const& sources) -{ - for(std::vector::const_iterator - si = sources.begin(); si != sources.end(); ++si) - { - cmTarget::SourceFileFlags tsFlags = - this->Target->GetTargetSourceFileFlags(*si); - if(tsFlags.Type != cmTarget::SourceFileTypeNormal) - { - this->WriteMacOSXContentRules(**si, tsFlags.MacFolder); - } - } -} //---------------------------------------------------------------------------- -void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source, - const char* pkgloc) +void +cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator() + (cmSourceFile& source, const char* pkgloc) { // Skip OS X content when not building a Framework or Bundle. - if(this->MacContentDirectory.empty()) + if(this->Generator->MacContentDirectory.empty()) { return; } - // Construct the full path to the content subdirectory. - std::string macdir = this->MacContentDirectory; - macdir += pkgloc; - cmSystemTools::MakeDirectory(macdir.c_str()); - - // Record use of this content location. Only the first level - // directory is needed. - { - std::string loc = pkgloc; - loc = loc.substr(0, loc.find('/')); - this->MacContentFolders.insert(loc); - } + std::string macdir = + this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc); // Get the input file location. std::string input = source.GetFullPath(); @@ -389,9 +376,11 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source, std::string output = macdir; output += "/"; output += cmSystemTools::GetFilenameName(input); - this->CleanFiles.push_back(this->Convert(output.c_str(), - cmLocalGenerator::START_OUTPUT)); - output = this->Convert(output.c_str(), cmLocalGenerator::HOME_OUTPUT); + this->Generator->CleanFiles.push_back( + this->Generator->Convert(output.c_str(), + cmLocalGenerator::START_OUTPUT)); + output = this->Generator->Convert(output.c_str(), + cmLocalGenerator::HOME_OUTPUT); // Create a rule to copy the content into the bundle. std::vector depends; @@ -399,21 +388,23 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source, depends.push_back(input); std::string copyEcho = "Copying OS X content "; copyEcho += output; - this->LocalGenerator->AppendEcho(commands, copyEcho.c_str(), - cmLocalUnixMakefileGenerator3::EchoBuild); + this->Generator->LocalGenerator->AppendEcho( + commands, copyEcho.c_str(), + cmLocalUnixMakefileGenerator3::EchoBuild); std::string copyCommand = "$(CMAKE_COMMAND) -E copy "; - copyCommand += this->Convert(input.c_str(), - cmLocalGenerator::NONE, - cmLocalGenerator::SHELL); + copyCommand += this->Generator->Convert(input.c_str(), + cmLocalGenerator::NONE, + cmLocalGenerator::SHELL); copyCommand += " "; - copyCommand += this->Convert(output.c_str(), - cmLocalGenerator::NONE, - cmLocalGenerator::SHELL); + copyCommand += this->Generator->Convert(output.c_str(), + cmLocalGenerator::NONE, + cmLocalGenerator::SHELL); commands.push_back(copyCommand); - this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0, - output.c_str(), - depends, commands, false); - this->ExtraFiles.insert(output); + this->Generator->LocalGenerator->WriteMakeRule( + *this->Generator->BuildFileStream, 0, + output.c_str(), + depends, commands, false); + this->Generator->ExtraFiles.insert(output); } //---------------------------------------------------------------------------- diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 36a1f6861..2798e5462 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -13,6 +13,7 @@ #define cmMakefileTargetGenerator_h #include "cmLocalUnixMakefileGenerator3.h" +#include "cmOSXBundleGenerator.h" class cmCustomCommand; class cmDependInformation; @@ -34,7 +35,7 @@ class cmMakefileTargetGenerator public: // constructor to set the ivars cmMakefileTargetGenerator(cmTarget* target); - virtual ~cmMakefileTargetGenerator() {}; + virtual ~cmMakefileTargetGenerator(); // construct using this factory call static cmMakefileTargetGenerator *New(cmTarget *tgt); @@ -50,6 +51,7 @@ public: { return this->ProgressFileNameFull; } cmTarget* GetTarget() { return this->Target;} + protected: // create the file and directory etc @@ -73,8 +75,18 @@ protected: void WriteTargetDependRules(); // write rules for Mac OS X Application Bundle content. - void WriteMacOSXContentRules(std::vector const& sources); - void WriteMacOSXContentRules(cmSourceFile& source, const char* pkgloc); + struct MacOSXContentGeneratorType : + cmOSXBundleGenerator::MacOSXContentGeneratorType + { + MacOSXContentGeneratorType(cmMakefileTargetGenerator* gen) : + Generator(gen) {} + + void operator()(cmSourceFile& source, const char* pkgloc); + + private: + cmMakefileTargetGenerator* Generator; + }; + friend struct MacOSXContentGeneratorType; // write the rules for an object void WriteObjectRuleFiles(cmSourceFile& source); @@ -223,6 +235,8 @@ protected: // Mac OS X content info. std::string MacContentDirectory; std::set MacContentFolders; + cmOSXBundleGenerator* OSXBundleGenerator; + MacOSXContentGeneratorType* MacOSXContentGenerator; typedef std::map ByLanguageMap; std::string GetFlags(const std::string &l); diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx index a82c50349..4456aa794 100644 --- a/Source/cmMakefileUtilityTargetGenerator.cxx +++ b/Source/cmMakefileUtilityTargetGenerator.cxx @@ -24,6 +24,19 @@ cmMakefileUtilityTargetGenerator cmMakefileTargetGenerator(target) { this->CustomCommandDriver = OnUtility; + this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target, + this->TargetNameOut, + this->ConfigName); + this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + this->MacContentDirectory = + this->OSXBundleGenerator->GetMacContentDirectory(); +} + +//---------------------------------------------------------------------------- +cmMakefileUtilityTargetGenerator +::~cmMakefileUtilityTargetGenerator() +{ + delete this->OSXBundleGenerator; } //---------------------------------------------------------------------------- diff --git a/Source/cmMakefileUtilityTargetGenerator.h b/Source/cmMakefileUtilityTargetGenerator.h index 99c16fcee..fc47b3891 100644 --- a/Source/cmMakefileUtilityTargetGenerator.h +++ b/Source/cmMakefileUtilityTargetGenerator.h @@ -14,16 +14,17 @@ #include "cmMakefileTargetGenerator.h" -class cmMakefileUtilityTargetGenerator: +class cmMakefileUtilityTargetGenerator: public cmMakefileTargetGenerator { public: cmMakefileUtilityTargetGenerator(cmTarget* target); + virtual ~cmMakefileUtilityTargetGenerator(); /* the main entry point for this class. Writes the Makefiles associated with this target */ - virtual void WriteRuleFiles(); - + virtual void WriteRuleFiles(); + protected: }; diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 01e8e737a..a923d6068 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -16,8 +16,15 @@ #include "cmSourceFile.h" #include "cmGeneratedFileStream.h" #include "cmMakefile.h" +#include "cmOSXBundleGenerator.h" #include +#include + +#ifndef _WIN32 +#include +#endif + cmNinjaNormalTargetGenerator:: cmNinjaNormalTargetGenerator(cmTarget* target) @@ -27,7 +34,10 @@ cmNinjaNormalTargetGenerator(cmTarget* target) , TargetNameReal() , TargetNameImport() , TargetNamePDB() + , TargetLinkLanguage(0) { + cmOSXBundleGenerator::PrepareTargetProperties(target); + this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName()); if (target->GetType() == cmTarget::EXECUTABLE) target->GetExecutableNames(this->TargetNameOut, @@ -49,10 +59,16 @@ cmNinjaNormalTargetGenerator(cmTarget* target) // ensure the directory exists (OutDir test) EnsureDirectoryExists(target->GetDirectory(this->GetConfigName())); } + + this->OSXBundleGenerator = new cmOSXBundleGenerator(target, + this->TargetNameOut, + this->GetConfigName()); + this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); } cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() { + delete this->OSXBundleGenerator; } void cmNinjaNormalTargetGenerator::Generate() @@ -75,10 +91,8 @@ void cmNinjaNormalTargetGenerator::Generate() } else { - this->WriteLinkRule(false); -#ifdef _WIN32 // TODO response file support only Linux - this->WriteLinkRule(true); -#endif + this->WriteLinkRule(false); // write rule without rspfile support + this->WriteLinkRule(true); // write rule with rspfile support this->WriteLinkStatement(); } } @@ -111,7 +125,10 @@ const char *cmNinjaNormalTargetGenerator::GetVisibleTypeName() const case cmTarget::SHARED_LIBRARY: return "shared library"; case cmTarget::MODULE_LIBRARY: - return "shared module"; + if (this->GetTarget()->IsCFBundleOnApple()) + return "CFBundle shared module"; + else + return "shared module"; case cmTarget::EXECUTABLE: return "executable"; default: @@ -140,6 +157,7 @@ cmNinjaNormalTargetGenerator // Select whether to use a response file for objects. std::string rspfile; + std::string rspcontent; if (!this->GetGlobalGenerator()->HasRule(ruleName)) { cmLocalGenerator::RuleVariables vars; @@ -150,6 +168,7 @@ cmNinjaNormalTargetGenerator std::string responseFlag; if (!useResponseFile) { vars.Objects = "$in"; + vars.LinkLibraries = "$LINK_LIBRARIES"; } else { // handle response file std::string cmakeLinkVar = std::string("CMAKE_") + @@ -162,11 +181,20 @@ cmNinjaNormalTargetGenerator } rspfile = "$out.rsp"; responseFlag += rspfile; + rspcontent = "$in $LINK_LIBRARIES"; vars.Objects = responseFlag.c_str(); + vars.LinkLibraries = ""; } vars.ObjectDir = "$OBJECT_DIR"; + + // TODO: + // Makefile generator expands to the plain target name + // with suffix. $out expands to a relative path. This difference + // could make trouble when switching to Ninja generator. Maybe + // using TARGET_NAME and RuleVariables::TargetName is a fix. vars.Target = "$out"; + vars.SONameFlag = "$SONAME_FLAG"; vars.TargetSOName = "$SONAME"; vars.TargetInstallNameDir = "$INSTALLNAME_DIR"; @@ -189,7 +217,6 @@ cmNinjaNormalTargetGenerator vars.TargetVersionMajor = targetVersionMajor.c_str(); vars.TargetVersionMinor = targetVersionMinor.c_str(); - vars.LinkLibraries = "$LINK_LIBRARIES"; vars.Flags = "$FLAGS"; vars.LinkFlags = "$LINK_FLAGS"; @@ -227,7 +254,8 @@ cmNinjaNormalTargetGenerator description.str(), comment.str(), /*depfile*/ "", - rspfile); + rspfile, + rspcontent); } if (this->TargetNameOut != this->TargetNameReal) { @@ -333,6 +361,40 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() { cmTarget::TargetType targetType = this->GetTarget()->GetType(); + std::string targetOutput = ConvertToNinjaPath( + this->GetTarget()->GetFullPath(this->GetConfigName()).c_str()); + std::string targetOutputReal = ConvertToNinjaPath( + this->GetTarget()->GetFullPath(this->GetConfigName(), + /*implib=*/false, + /*realpath=*/true).c_str()); + std::string targetOutputImplib = ConvertToNinjaPath( + this->GetTarget()->GetFullPath(this->GetConfigName(), + /*implib=*/true).c_str()); + + if (this->GetTarget()->IsAppBundleOnApple()) + { + // Create the app bundle + std::string outpath; + this->OSXBundleGenerator->CreateAppBundle(this->TargetNameOut, outpath); + + // Calculate the output path + targetOutput = outpath + this->TargetNameOut; + targetOutput = this->ConvertToNinjaPath(targetOutput.c_str()); + targetOutputReal = outpath + this->TargetNameReal; + targetOutputReal = this->ConvertToNinjaPath(targetOutputReal.c_str()); + } + else if (this->GetTarget()->IsFrameworkOnApple()) + { + // Create the library framework. + this->OSXBundleGenerator->CreateFramework(this->TargetNameOut); + } + else if(this->GetTarget()->IsCFBundleOnApple()) + { + // Create the core foundation bundle. + std::string outpath; + this->OSXBundleGenerator->CreateCFBundle(this->TargetNameOut, outpath); + } + // Write comments. cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream()); this->GetBuildFileStream() @@ -345,16 +407,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() cmNinjaDeps emptyDeps; cmNinjaVars vars; - std::string targetOutput = ConvertToNinjaPath( - this->GetTarget()->GetFullPath(this->GetConfigName()).c_str()); - std::string targetOutputReal = ConvertToNinjaPath( - this->GetTarget()->GetFullPath(this->GetConfigName(), - /*implib=*/false, - /*realpath=*/true).c_str()); - std::string targetOutputImplib = ConvertToNinjaPath( - this->GetTarget()->GetFullPath(this->GetConfigName(), - /*implib=*/true).c_str()); - // Compute the comment. cmOStringStream comment; comment << "Link the " << this->GetVisibleTypeName() << " " @@ -365,8 +417,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() outputs.push_back(targetOutputReal); // Compute specific libraries to link with. - cmNinjaDeps explicitDeps = this->GetObjects(), - implicitDeps = this->ComputeLinkDeps(); + cmNinjaDeps explicitDeps = this->GetObjects(); + cmNinjaDeps implicitDeps = this->ComputeLinkDeps(); this->GetLocalGenerator()->GetTargetFlags(vars["LINK_LIBRARIES"], vars["FLAGS"], @@ -415,7 +467,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() EnsureParentDirectoryExists(path); } - // TODO move to GetTargetPDB cmMakefile* mf = this->GetMakefile(); if (mf->GetDefinition("MSVC_C_ARCHITECTURE_ID") || mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID")) @@ -426,12 +477,29 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() cmLocalGenerator::SHELL); EnsureParentDirectoryExists(path); } + else + { + // It is common to place debug symbols at a specific place, + // so we need a plain target name in the rule available. + std::string prefix; + std::string base; + std::string suffix; + this->GetTarget()->GetFullNameComponents(prefix, base, suffix); + std::string dbg_suffix = ".dbg"; + // TODO: Where to document? + if (mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX")) + dbg_suffix = mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX"); + vars["TARGET_PDB"] = base + suffix + dbg_suffix; + } if (mf->IsOn("CMAKE_COMPILER_IS_MINGW")) { path = GetTarget()->GetSupportDirectory(); vars["OBJECT_DIR"] = ConvertToNinjaPath(path.c_str()); EnsureDirectoryExists(path); + // ar.exe can't handle backslashes in rsp files (implictly used by gcc) + std::string& linkLibraries = vars["LINK_LIBRARIES"]; + std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/'); } std::vector *cmdLists[3] = { @@ -478,11 +546,16 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() symlinkVars["POST_BUILD"] = postBuildCmdLine; } - int cmdLineLimit; + int linkRuleLength = this->GetGlobalGenerator()-> + GetRuleCmdLength(this->LanguageLinkerRule()); #ifdef _WIN32 - cmdLineLimit = 8000; + int commandLineLengthLimit = 8000 - linkRuleLength; +#elif defined(__linux) || defined(__APPLE__) + // for instance ARG_MAX is 2096152 on Ubuntu or 262144 on Mac + int commandLineLengthLimit = ((int)sysconf(_SC_ARG_MAX)) + - linkRuleLength - 1000; #else - cmdLineLimit = -1; // TODO + int commandLineLengthLimit = -1; #endif // Write the build statement for this target. @@ -494,7 +567,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() implicitDeps, emptyDeps, vars, - cmdLineLimit); + commandLineLengthLimit); if (targetOutput != targetOutputReal) { if (targetType == cmTarget::EXECUTABLE) { @@ -507,11 +580,20 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() emptyDeps, symlinkVars); } else { - symlinkVars["SONAME"] = this->GetTargetFilePath(this->TargetNameSO); + cmNinjaDeps symlinks; + const std::string soName = this->GetTargetFilePath(this->TargetNameSO); + // If one link has to be created. + if (targetOutputReal == soName || targetOutput == soName) { + symlinkVars["SONAME"] = soName; + } else { + symlinkVars["SONAME"] = ""; + symlinks.push_back(soName); + } + symlinks.push_back(targetOutput); cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(), "Create library symlink " + targetOutput, "CMAKE_SYMLINK_LIBRARY", - cmNinjaDeps(1, targetOutput), + symlinks, cmNinjaDeps(1, targetOutputReal), emptyDeps, emptyDeps, diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h index 1ef95675b..284804b08 100644 --- a/Source/cmNinjaNormalTargetGenerator.h +++ b/Source/cmNinjaNormalTargetGenerator.h @@ -15,8 +15,12 @@ # include "cmNinjaTargetGenerator.h" # include "cmNinjaTypes.h" +# include "cmStandardIncludes.h" + +# include class cmSourceFile; +class cmOSXBundleGenerator; class cmNinjaNormalTargetGenerator : public cmNinjaTargetGenerator { diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 615793117..3532c8ba4 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -56,7 +56,11 @@ cmNinjaTargetGenerator::New(cmTarget* target) } cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target) - : Target(target), + : + MacOSXContentGenerator(0), + OSXBundleGenerator(0), + MacContentFolders(), + Target(target), Makefile(target->GetMakefile()), LocalGenerator( static_cast(Makefile->GetLocalGenerator())), @@ -64,10 +68,12 @@ cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target) { this->GeneratorTarget = this->GetGlobalGenerator()->GetGeneratorTarget(target); + MacOSXContentGenerator = new MacOSXContentGeneratorType(this); } cmNinjaTargetGenerator::~cmNinjaTargetGenerator() { + delete this->MacOSXContentGenerator; } cmGeneratedFileStream& cmNinjaTargetGenerator::GetBuildFileStream() const @@ -87,7 +93,7 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const const char* cmNinjaTargetGenerator::GetConfigName() const { - return this->LocalGenerator->ConfigName.c_str(); + return this->LocalGenerator->GetConfigName(); } // TODO: Picked up from cmMakefileTargetGenerator. Refactor it. @@ -143,16 +149,18 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, this->LocalGenerator->AddCMP0018Flags(flags, this->Target, language.c_str()); - // TODO: Handle response file. // Add include directory flags. { std::vector includes; this->LocalGenerator->GetIncludeDirectories(includes, this->Target, language.c_str()); std::string includeFlags = - this->LocalGenerator->GetIncludeFlags(includes, language.c_str(), false); + this->LocalGenerator->GetIncludeFlags(includes, language.c_str(), + language == "RC" ? true : false); // full include paths for RC + // needed by cmcldeps if(cmGlobalNinjaGenerator::IsMinGW()) cmSystemTools::ReplaceString(includeFlags, "\\", "/"); + this->LocalGenerator->AppendFlags(flags, includeFlags.c_str()); } @@ -428,6 +436,12 @@ cmNinjaTargetGenerator cmCustomCommand const* cc = (*si)->GetCustomCommand(); this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget()); } + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + this->GeneratorTarget->HeaderSources, + this->MacOSXContentGenerator); + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + this->GeneratorTarget->ExtraSources, + this->MacOSXContentGenerator); for(std::vector::const_iterator si = this->GeneratorTarget->ExternalObjects.begin(); si != this->GeneratorTarget->ExternalObjects.end(); ++si) @@ -467,7 +481,7 @@ cmNinjaTargetGenerator cmNinjaDeps emptyDeps; std::string comment; - const char* language = source->GetLanguage(); + const std::string language = source->GetLanguage(); std::string rule = this->LanguageCompilerRule(language); cmNinjaDeps outputs; @@ -477,7 +491,11 @@ cmNinjaTargetGenerator this->Objects.push_back(objectFileName); cmNinjaDeps explicitDeps; - std::string sourceFileName = this->GetSourceFilePath(source); + std::string sourceFileName; + if (language == "RC") + sourceFileName = source->GetFullPath(); + else + sourceFileName = this->GetSourceFilePath(source); explicitDeps.push_back(sourceFileName); // Ensure that the target dependencies are built before any source file in @@ -534,9 +552,21 @@ cmNinjaTargetGenerator cmLocalGenerator::RuleVariables compileObjectVars; std::string lang = language; compileObjectVars.Language = lang.c_str(); - std::string escapedSourceFileName = + + std::string escapedSourceFileName = sourceFileName; + + if (!cmSystemTools::FileIsFullPath(sourceFileName.c_str())) + { + escapedSourceFileName = cmSystemTools::CollapseFullPath( + escapedSourceFileName.c_str(), + this->GetGlobalGenerator()->GetCMakeInstance()-> + GetHomeOutputDirectory()); + } + + escapedSourceFileName = this->LocalGenerator->ConvertToOutputFormat( - sourceFileName.c_str(), cmLocalGenerator::SHELL); + escapedSourceFileName.c_str(), cmLocalGenerator::SHELL); + compileObjectVars.Source = escapedSourceFileName.c_str(); compileObjectVars.Object = objectFileName.c_str(); compileObjectVars.Flags = vars["FLAGS"].c_str(); @@ -622,3 +652,38 @@ cmNinjaTargetGenerator { EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path.c_str())); } + + +//---------------------------------------------------------------------------- +void +cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()( + cmSourceFile& source, const char* pkgloc) +{ + // Skip OS X content when not building a Framework or Bundle. + if(this->Generator->OSXBundleGenerator->GetMacContentDirectory().empty()) + { + return; + } + + std::string macdir = + this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc); + + // Get the input file location. + std::string input = source.GetFullPath(); + input = + this->Generator->GetLocalGenerator()->ConvertToNinjaPath(input.c_str()); + + // Get the output file location. + std::string output = macdir; + output += "/"; + output += cmSystemTools::GetFilenameName(input); + output = + this->Generator->GetLocalGenerator()->ConvertToNinjaPath(output.c_str()); + + // Write a build statement to copy the content into the bundle. + this->Generator->GetGlobalGenerator()->WriteMacOSXContentBuild(input, + output); + + // Add as a dependency of all target so that it gets called. + this->Generator->GetGlobalGenerator()->AddDependencyToAll(output); +} diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index af43a8b38..84573cec2 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -16,6 +16,7 @@ #include "cmStandardIncludes.h" #include "cmNinjaTypes.h" #include "cmLocalNinjaGenerator.h" +#include "cmOSXBundleGenerator.h" class cmTarget; class cmGlobalNinjaGenerator; @@ -114,6 +115,27 @@ protected: void EnsureDirectoryExists(const std::string& dir); void EnsureParentDirectoryExists(const std::string& path); + // write rules for Mac OS X Application Bundle content. + struct MacOSXContentGeneratorType : + cmOSXBundleGenerator::MacOSXContentGeneratorType + { + MacOSXContentGeneratorType(cmNinjaTargetGenerator* g) : + Generator(g) {} + + void operator()(cmSourceFile& source, const char* pkgloc); + + private: + cmNinjaTargetGenerator* Generator; + }; + friend struct MacOSXContentGeneratorType; + +protected: + MacOSXContentGeneratorType* MacOSXContentGenerator; + // Properly initialized by sub-classes. + cmOSXBundleGenerator* OSXBundleGenerator; + std::set MacContentFolders; + + private: cmTarget* Target; cmGeneratorTarget* GeneratorTarget; diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx new file mode 100644 index 000000000..42fad0742 --- /dev/null +++ b/Source/cmOSXBundleGenerator.cxx @@ -0,0 +1,236 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Nicolas Despres + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmOSXBundleGenerator.h" +#include "cmMakefile.h" +#include "cmTarget.h" +#include "cmLocalGenerator.h" + +#include + +void cmOSXBundleGenerator::PrepareTargetProperties(cmTarget* target) +{ + if(target->IsCFBundleOnApple()) + { + target->SetProperty("PREFIX", ""); + target->SetProperty("SUFFIX", ""); + } +} + +//---------------------------------------------------------------------------- +cmOSXBundleGenerator:: +cmOSXBundleGenerator(cmTarget* target, + std::string targetNameOut, + const char* configName) + : Target(target) + , Makefile(target->GetMakefile()) + , LocalGenerator(Makefile->GetLocalGenerator()) + , TargetNameOut(targetNameOut) + , ConfigName(configName) + , MacContentDirectory() + , FrameworkVersion() + , MacContentFolders(0) +{ + if (this->MustSkip()) + return; + + this->MacContentDirectory = + this->Target->GetMacContentDirectory(this->ConfigName, + /*implib*/ false, + /*includeMacOS*/ false); + if(this->Target->IsFrameworkOnApple()) + this->FrameworkVersion = this->Target->GetFrameworkVersion(); +} + +//---------------------------------------------------------------------------- +bool cmOSXBundleGenerator::MustSkip() +{ + return !this->Target->HaveWellDefinedOutputFiles(); +} + +//---------------------------------------------------------------------------- +void cmOSXBundleGenerator::CreateAppBundle(std::string& targetName, + std::string& outpath) +{ + if (this->MustSkip()) + return; + + // Compute bundle directory names. + outpath = this->MacContentDirectory; + outpath += "MacOS"; + cmSystemTools::MakeDirectory(outpath.c_str()); + outpath += "/"; + this->Makefile->AddCMakeOutputFile(outpath.c_str()); + + // Configure the Info.plist file. Note that it needs the executable name + // to be set. + std::string plist = this->MacContentDirectory + "Info.plist"; + this->LocalGenerator->GenerateAppleInfoPList(this->Target, + targetName.c_str(), + plist.c_str()); + this->Makefile->AddCMakeOutputFile(plist.c_str()); +} + +//---------------------------------------------------------------------------- +void cmOSXBundleGenerator::CreateFramework(std::string const& targetName) +{ + if (this->MustSkip()) + return; + + assert(this->MacContentFolders); + + // Configure the Info.plist file into the Resources directory. + this->MacContentFolders->insert("Resources"); + std::string plist = this->MacContentDirectory + "Resources/Info.plist"; + this->LocalGenerator->GenerateFrameworkInfoPList(this->Target, + targetName.c_str(), + plist.c_str()); + + // TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to + // drive rules to create these files at build time. + std::string oldName; + std::string newName; + + // Compute the location of the top-level foo.framework directory. + std::string top = this->Target->GetDirectory(this->ConfigName); + top += "/"; + top += this->TargetNameOut; + top += ".framework/"; + + // Make foo.framework/Versions + std::string versions = top; + versions += "Versions"; + cmSystemTools::MakeDirectory(versions.c_str()); + + // Make foo.framework/Versions/version + std::string version = versions; + version += "/"; + version += this->FrameworkVersion; + cmSystemTools::MakeDirectory(version.c_str()); + + // Current -> version + oldName = this->FrameworkVersion; + newName = versions; + newName += "/Current"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + + // foo -> Versions/Current/foo + oldName = "Versions/Current/"; + oldName += this->TargetNameOut; + newName = top; + newName += this->TargetNameOut; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + + // Resources -> Versions/Current/Resources + if(this->MacContentFolders->find("Resources") != + this->MacContentFolders->end()) + { + oldName = "Versions/Current/Resources"; + newName = top; + newName += "Resources"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + } + + // Headers -> Versions/Current/Headers + if(this->MacContentFolders->find("Headers") != + this->MacContentFolders->end()) + { + oldName = "Versions/Current/Headers"; + newName = top; + newName += "Headers"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + } + + // PrivateHeaders -> Versions/Current/PrivateHeaders + if(this->MacContentFolders->find("PrivateHeaders") != + this->MacContentFolders->end()) + { + oldName = "Versions/Current/PrivateHeaders"; + newName = top; + newName += "PrivateHeaders"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + } +} + +//---------------------------------------------------------------------------- +void cmOSXBundleGenerator::CreateCFBundle(std::string& targetName, + std::string& outpath) +{ + if (this->MustSkip()) + return; + + // Compute bundle directory names. + outpath = this->MacContentDirectory; + outpath += "MacOS"; + cmSystemTools::MakeDirectory(outpath.c_str()); + outpath += "/"; + this->Makefile->AddCMakeOutputFile(outpath.c_str()); + + // Configure the Info.plist file. Note that it needs the executable name + // to be set. + std::string plist = this->MacContentDirectory; + plist += "Info.plist"; + this->LocalGenerator->GenerateAppleInfoPList(this->Target, + targetName.c_str(), + plist.c_str()); + this->Makefile->AddCMakeOutputFile(plist.c_str()); +} + +//---------------------------------------------------------------------------- +void +cmOSXBundleGenerator:: +GenerateMacOSXContentStatements(std::vector const& sources, + MacOSXContentGeneratorType* generator) +{ + if (this->MustSkip()) + return; + + for(std::vector::const_iterator + si = sources.begin(); si != sources.end(); ++si) + { + cmTarget::SourceFileFlags tsFlags = + this->Target->GetTargetSourceFileFlags(*si); + if(tsFlags.Type != cmTarget::SourceFileTypeNormal) + { + (*generator)(**si, tsFlags.MacFolder); + } + } +} + +//---------------------------------------------------------------------------- +std::string +cmOSXBundleGenerator::InitMacOSXContentDirectory(const char* pkgloc) +{ + // Construct the full path to the content subdirectory. + std::string macdir = this->MacContentDirectory; + macdir += pkgloc; + cmSystemTools::MakeDirectory(macdir.c_str()); + + // Record use of this content location. Only the first level + // directory is needed. + { + std::string loc = pkgloc; + loc = loc.substr(0, loc.find('/')); + this->MacContentFolders->insert(loc); + } + + return macdir; +} diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h new file mode 100644 index 000000000..01e3cbeb4 --- /dev/null +++ b/Source/cmOSXBundleGenerator.h @@ -0,0 +1,71 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Nicolas Despres + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmOSXBundleGenerator_h +#define cmOSXBundleGenerator_h + +#include "cmStandardIncludes.h" +#include "cmSourceFile.h" + +#include +#include + +class cmTarget; +class cmMakefile; +class cmLocalGenerator; + +class cmOSXBundleGenerator +{ +public: + static void PrepareTargetProperties(cmTarget* target); + + cmOSXBundleGenerator(cmTarget* target, + std::string targetNameOut, + const char* configName); + + void CreateAppBundle(std::string& targetName, std::string& outpath); + void CreateFramework(std::string const& targetName); + void CreateCFBundle(std::string& targetName, std::string& outpath); + + struct MacOSXContentGeneratorType + { + virtual ~MacOSXContentGeneratorType() {} + virtual void operator()(cmSourceFile& source, const char* pkgloc) = 0; + }; + + void GenerateMacOSXContentStatements( + std::vector const& sources, + MacOSXContentGeneratorType* generator); + std::string InitMacOSXContentDirectory(const char* pkgloc); + + std::string GetMacContentDirectory() const + { return this->MacContentDirectory; } + std::string GetFrameworkVersion() const + { return this->FrameworkVersion; } + void SetMacContentFolders(std::set* macContentFolders) + { this->MacContentFolders = macContentFolders; } + +private: + bool MustSkip(); + +private: + cmTarget* Target; + cmMakefile* Makefile; + cmLocalGenerator* LocalGenerator; + std::string TargetNameOut; + const char* ConfigName; + std::string MacContentDirectory; + std::string FrameworkVersion; + std::set* MacContentFolders; +}; + + +#endif diff --git a/Source/cmProjectCommand.h b/Source/cmProjectCommand.h index 4b051afee..88a1944b4 100644 --- a/Source/cmProjectCommand.h +++ b/Source/cmProjectCommand.h @@ -69,7 +69,7 @@ public: "C++ compiler, you can disable the check for it by explicitly listing " "the languages you want to support, e.g. C. By using the special " "language \"NONE\" all checks for any language can be disabled. " - "If a variable exists called CMAKE_PROJECT__INCLUDE_FILE, " + "If a variable exists called CMAKE_PROJECT__INCLUDE, " "the file pointed to by that variable will be included as the last step " "of the project command."; } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 4f3f2c572..775662cc3 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2482,6 +2482,16 @@ void cmTarget::MarkAsImported() this->IsImportedTarget = true; } +//---------------------------------------------------------------------------- +bool cmTarget::HaveWellDefinedOutputFiles() +{ + return + this->GetType() == cmTarget::STATIC_LIBRARY || + this->GetType() == cmTarget::SHARED_LIBRARY || + this->GetType() == cmTarget::MODULE_LIBRARY || + this->GetType() == cmTarget::EXECUTABLE; +} + //---------------------------------------------------------------------------- cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) { @@ -2492,10 +2502,7 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(const char* config) } // Only libraries and executables have well-defined output files. - if(this->GetType() != cmTarget::STATIC_LIBRARY && - this->GetType() != cmTarget::SHARED_LIBRARY && - this->GetType() != cmTarget::MODULE_LIBRARY && - this->GetType() != cmTarget::EXECUTABLE) + if(!this->HaveWellDefinedOutputFiles()) { std::string msg = "cmTarget::GetOutputInfo called for "; msg += this->GetName(); @@ -2586,18 +2593,7 @@ const char* cmTarget::NormalGetLocation(const char* config) this->Location += cfgid; this->Location += "/"; } - if(this->IsAppBundleOnApple()) - { - this->Location += this->GetFullName(config, false); - this->Location += ".app/Contents/MacOS/"; - } - if(this->IsFrameworkOnApple()) - { - this->Location += this->GetFullName(config, false); - this->Location += ".framework/Versions/"; - this->Location += this->GetFrameworkVersion(); - this->Location += "/"; - } + this->Location = this->BuildMacContentDirectory(this->Location, config); this->Location += this->GetFullName(config, false); return this->Location.c_str(); } @@ -3169,22 +3165,7 @@ std::string cmTarget::GetFullPath(const char* config, bool implib, std::string cmTarget::NormalGetFullPath(const char* config, bool implib, bool realname) { - // Start with the output directory for the target. - std::string fpath = this->GetDirectory(config, implib); - fpath += "/"; - - if(this->IsAppBundleOnApple()) - { - fpath += this->GetFullName(config, false); - fpath += ".app/Contents/MacOS/"; - } - if(this->IsFrameworkOnApple()) - { - fpath += this->GetFullName(config, false); - fpath += ".framework/Versions/"; - fpath += this->GetFrameworkVersion(); - fpath += "/"; - } + std::string fpath = this->GetMacContentDirectory(config, implib); // Add the full name of the target. if(implib) @@ -3707,10 +3688,7 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config, dir += "/"; if(this->IsFrameworkOnApple() && !for_xcode) { - dir += this->GetFullName(config, false); - dir += ".framework/Versions/"; - dir += this->GetFrameworkVersion(); - dir += "/"; + dir += this->GetFrameworkDirectory(config); } return dir; } @@ -3741,10 +3719,7 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char* config, if(this->IsFrameworkOnApple() && !for_xcode) { - dir += this->GetFullName(config, false); - dir += ".framework/Versions/"; - dir += this->GetFrameworkVersion(); - dir += "/"; + dir += this->GetFrameworkDirectory(config); } return dir; @@ -4733,6 +4708,63 @@ std::vector cmTarget::GetIncludeDirectories() return orderedAndUniqueIncludes; } +//---------------------------------------------------------------------------- +std::string cmTarget::GetFrameworkDirectory(const char* config) +{ + std::string fpath; + fpath += this->GetFullName(config, false); + fpath += ".framework/Versions/"; + fpath += this->GetFrameworkVersion(); + fpath += "/"; + return fpath; +} + +//---------------------------------------------------------------------------- +std::string cmTarget::BuildMacContentDirectory(const std::string& base, + const char* config, + bool includeMacOS) +{ + std::string fpath = base; + if(this->IsAppBundleOnApple()) + { + fpath += this->GetFullName(config, false); + fpath += ".app/Contents/"; + if(includeMacOS) + fpath += "MacOS/"; + } + if(this->IsFrameworkOnApple()) + { + fpath += this->GetFrameworkDirectory(config); + } + if(this->IsCFBundleOnApple()) + { + fpath += this->GetFullName(config, false); + fpath += "."; + const char *ext = this->GetProperty("BUNDLE_EXTENSION"); + if (!ext) + { + ext = "bundle"; + } + fpath += ext; + fpath += "/Contents/"; + if(includeMacOS) + fpath += "MacOS/"; + } + return fpath; +} + +//---------------------------------------------------------------------------- +std::string cmTarget::GetMacContentDirectory(const char* config, + bool implib, + bool includeMacOS) +{ + // Start with the output directory for the target. + std::string fpath = this->GetDirectory(config, implib); + fpath += "/"; + fpath = this->BuildMacContentDirectory(fpath, config, includeMacOS); + return fpath; +} + //---------------------------------------------------------------------------- cmTargetLinkInformationMap ::cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r): derived() diff --git a/Source/cmTarget.h b/Source/cmTarget.h index d70cacdff..a89c5d91b 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -465,6 +465,22 @@ public: /** Get the include directories for this target. */ std::vector GetIncludeDirectories(); + /** Append to @a base the mac content directory and return it. */ + std::string BuildMacContentDirectory(const std::string& base, + const char* config = 0, + bool includeMacOS = true); + + /** @return the mac content directory for this target. */ + std::string GetMacContentDirectory(const char* config = 0, + bool implib = false, + bool includeMacOS = true); + + /** @return whether this target have a well defined output file name. */ + bool HaveWellDefinedOutputFiles(); + + /** @return the Mac framework directory without the base. */ + std::string GetFrameworkDirectory(const char* config = 0); + private: /** * A list of direct dependencies. Use in conjunction with DependencyMap. diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 451aec8fa..fdc42fa2b 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -84,10 +84,8 @@ #else #endif #include "cmGlobalUnixMakefileGenerator3.h" +#include "cmGlobalNinjaGenerator.h" -#ifdef CMAKE_USE_NINJA -# include "cmGlobalNinjaGenerator.h" -#endif #if defined(CMAKE_HAVE_VS_GENERATORS) #include "cmCallVisualStudioMacro.h" @@ -2600,10 +2598,8 @@ void cmake::AddDefaultGenerators() #endif this->Generators[cmGlobalUnixMakefileGenerator3::GetActualName()] = &cmGlobalUnixMakefileGenerator3::New; -#ifdef CMAKE_USE_NINJA this->Generators[cmGlobalNinjaGenerator::GetActualName()] = &cmGlobalNinjaGenerator::New; -#endif #ifdef CMAKE_USE_XCODE this->Generators[cmGlobalXCodeGenerator::GetActualName()] = &cmGlobalXCodeGenerator::New; diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index c3de8ca8d..11a426753 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -// include these first, otherwise there will be problems on Windows -// with GetCurrentDirectory() being redefined +// include these first, otherwise there will be problems on Windows +// with GetCurrentDirectory() being redefined #ifdef CMAKE_BUILD_WITH_CMAKE #include "cmDynamicLoader.h" #include "cmDocumentation.h" @@ -183,7 +183,7 @@ static const char * cmDocumentationOptions[][3] = "If a file is specified, the documentation is written into and the output " "format is determined depending on the filename suffix. Supported are man " "page, HTML, DocBook and plain text."}, - {"--help-policy cmp [file]", + {"--help-policy cmp [file]", "Print help for a single policy and exit.", "Full documentation specific to the given policy is displayed." "If a file is specified, the documentation is written into and the output " @@ -194,7 +194,7 @@ static const char * cmDocumentationOptions[][3] = "If a file is specified, the documentation is written into and the output " "format is determined depending on the filename suffix. Supported are man " "page, HTML, DocBook and plain text."}, - {"--help-property prop [file]", + {"--help-property prop [file]", "Print help for a single property and exit.", "Full documentation specific to the given property is displayed." "If a file is specified, the documentation is written into and the output " @@ -212,7 +212,7 @@ static const char * cmDocumentationOptions[][3] = "If a file is specified, the documentation is written into and the output " "format is determined depending on the filename suffix. Supported are man " "page, HTML, DocBook and plain text."}, - {"--help-variable var [file]", + {"--help-variable var [file]", "Print help for a single variable and exit.", "Full documentation specific to the given variable is displayed." "If a file is specified, the documentation is written into and the output " @@ -296,13 +296,13 @@ static std::string cmakemainGetStack(void *clientdata) return msg; } -static void cmakemainErrorCallback(const char* m, const char*, bool&, +static void cmakemainErrorCallback(const char* m, const char*, bool&, void *clientdata) { std::cerr << m << cmakemainGetStack(clientdata) << std::endl << std::flush; } -static void cmakemainProgressCallback(const char *m, float prog, +static void cmakemainProgressCallback(const char *m, float prog, void* clientdata) { cmMakefile* mf = cmakemainGetMakefile(clientdata); @@ -348,7 +348,7 @@ int do_cmake(int ac, char** av) if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 ) { - std::cerr << "Current working directory cannot be established." + std::cerr << "Current working directory cannot be established." << std::endl; nocwd = 1; } @@ -357,13 +357,13 @@ int do_cmake(int ac, char** av) cmDocumentation doc; doc.addCMakeStandardDocSections(); if(doc.CheckOptions(ac, av, "-E") || nocwd) - { + { // Construct and print requested documentation. cmake hcm; hcm.AddCMakePaths(); doc.SetCMakeRoot(hcm.GetCacheDefinition("CMAKE_ROOT")); - // the command line args are processed here so that you can do + // the command line args are processed here so that you can do // -DCMAKE_MODULE_PATH=/some/path and have this value accessible here std::vector args; for(int i =0; i < ac; ++i) @@ -401,7 +401,7 @@ int do_cmake(int ac, char** av) doc.SetSections(propDocs); cmDocumentationEntry e; - e.Brief = + e.Brief = "variables defined by cmake, that give information about the project, " "and cmake"; doc.PrependSection("Variables that Provide Information",e); @@ -418,7 +418,7 @@ int do_cmake(int ac, char** av) { doc.ClearSections(); doc.SetSection("NOTE", cmDocumentationNOTE); - doc.Print(cmDocumentation::UsageForm, std::cerr); + doc.Print(cmDocumentation::UsageForm, 0, std::cerr); return 1; } return result; @@ -426,13 +426,13 @@ int do_cmake(int ac, char** av) #else if ( nocwd || ac == 1 ) { - std::cout << + std::cout << "Bootstrap CMake should not be used outside CMake build process." << std::endl; return 0; } #endif - + bool wiz = false; bool sysinfo = false; bool command = false; @@ -453,7 +453,7 @@ int do_cmake(int ac, char** av) sysinfo = true; } // if command has already been set, then - // do not eat the -E + // do not eat the -E else if (!command && strcmp(av[i], "-E") == 0) { command = true; @@ -500,7 +500,7 @@ int do_cmake(int ac, char** av) workingMode = cmake::FIND_PACKAGE_MODE; args.push_back(av[i]); } - else + else { args.push_back(av[i]); } @@ -513,15 +513,15 @@ int do_cmake(int ac, char** av) if (wiz) { cmakewizard wizard; - return wizard.RunWizard(args); + return wizard.RunWizard(args); } if (sysinfo) { cmake cm; int ret = cm.GetSystemInformation(args); - return ret; + return ret; } - cmake cm; + cmake cm; cmSystemTools::SetErrorCallback(cmakemainErrorCallback, (void *)&cm); cm.SetProgressCallback(cmakemainProgressCallback, (void *)&cm); cm.SetWorkingMode(workingMode); @@ -529,7 +529,7 @@ int do_cmake(int ac, char** av) int res = cm.Run(args, view_only); if ( list_cached || list_all_cached ) { - cmCacheManager::CacheIterator it = + cmCacheManager::CacheIterator it = cm.GetCacheManager()->GetCacheIterator(); std::cout << "-- Cache values" << std::endl; for ( it.Begin(); !it.IsAtEnd(); it.Next() ) @@ -545,8 +545,8 @@ int do_cmake(int ac, char** av) { std::cout << "// " << it.GetProperty("HELPSTRING") << std::endl; } - std::cout << it.GetName() << ":" << - cmCacheManager::TypeToString(it.GetType()) + std::cout << it.GetName() << ":" << + cmCacheManager::TypeToString(it.GetType()) << "=" << it.GetValue() << std::endl; if ( list_help ) { diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx index 7d3c4bd65..69df88d2a 100644 --- a/Source/cmcldeps.cxx +++ b/Source/cmcldeps.cxx @@ -1,8 +1,4 @@ -/* - ninja's subprocess.h -*/ - -// Copyright 2012 Google Inc. All Rights Reserved. +// Copyright 2011 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,114 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef NINJA_SUBPROCESS_H_ -#define NINJA_SUBPROCESS_H_ -#include -#include -#include -#include -#include +// Wrapper around cl that adds /showIncludes to command line, and uses that to +// generate .d files that match the style from gcc -MD. +// +// /showIncludes is equivalent to -MD, not -MMD, that is, system headers are +// included. -#ifdef _WIN32 #include -#else -#include -#endif - - -#if defined(_WIN64) -typedef unsigned __int64 cmULONG_PTR; -#else -typedef unsigned long cmULONG_PTR; -#endif - -//#include "exit_status.h" -enum ExitStatus { - ExitSuccess, - ExitFailure, - ExitInterrupted -}; - -/// Subprocess wraps a single async subprocess. It is entirely -/// passive: it expects the caller to notify it when its fds are ready -/// for reading, as well as call Finish() to reap the child once done() -/// is true. -struct Subprocess { - ~Subprocess(); - - /// Returns ExitSuccess on successful process exit, ExitInterrupted if - /// the process was interrupted, ExitFailure if it otherwise failed. - ExitStatus Finish(); - - bool Done() const; - - const std::string& GetOutput() const; - - int ExitCode() const { return exit_code_; } - - private: - Subprocess(); - bool Start(struct SubprocessSet* set, const std::string& command, - const std::string& dir); - void OnPipeReady(); - - std::string buf_; - -#ifdef _WIN32 - /// Set up pipe_ as the parent-side pipe of the subprocess; return the - /// other end of the pipe, usable in the child process. - HANDLE SetupPipe(HANDLE ioport); - - PROCESS_INFORMATION child_; - HANDLE pipe_; - OVERLAPPED overlapped_; - char overlapped_buf_[4 << 10]; - bool is_reading_; - int exit_code_; -#else - int fd_; - pid_t pid_; -#endif - - friend struct SubprocessSet; -}; - -/// SubprocessSet runs a ppoll/pselect() loop around a set of Subprocesses. -/// DoWork() waits for any state change in subprocesses; finished_ -/// is a queue of subprocesses as they finish. -struct SubprocessSet { - SubprocessSet(); - ~SubprocessSet(); - - Subprocess* Add(const std::string& command, const std::string& dir); - bool DoWork(); - Subprocess* NextFinished(); - void Clear(); - - std::vector running_; - std::queue finished_; - -#ifdef _WIN32 - static BOOL WINAPI NotifyInterrupted(DWORD dwCtrlType); - static HANDLE ioport_; -#else - static void SetInterruptedFlag(int signum); - static bool interrupted_; - - struct sigaction old_act_; - sigset_t old_mask_; -#endif -}; - -#endif // NINJA_SUBPROCESS_H_ - - -/* - ninja's util functions -*/ +#include +#include +// We don't want any wildcard expansion. +// See http://msdn.microsoft.com/en-us/library/zay8tzh6(v=vs.85).aspx +void _setargv() {} static void Fatal(const char* msg, ...) { va_list ap; @@ -132,370 +35,13 @@ static void Fatal(const char* msg, ...) { vfprintf(stderr, msg, ap); va_end(ap); fprintf(stderr, "\n"); -#ifdef _WIN32 // On Windows, some tools may inject extra threads. // exit() may block on locks held by those threads, so forcibly exit. fflush(stderr); fflush(stdout); ExitProcess(1); -#else - exit(1); -#endif -} - - -#ifdef _WIN32 -std::string GetLastErrorString() { - DWORD err = GetLastError(); - - char* msg_buf; - FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (char*)&msg_buf, - 0, - NULL); - std::string msg = msg_buf; - LocalFree(msg_buf); - return msg; -} -#endif - -#define snprintf _snprintf - - -/* - ninja's subprocess-win32.cc -*/ - -// Copyright 2012 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//#include "subprocess.h" - -#include - -#include - -//#include "util.h" - -namespace { - -void Win32Fatal(const char* function) { - Fatal("%s: %s", function, GetLastErrorString().c_str()); -} - -} // anonymous namespace - -Subprocess::Subprocess() : overlapped_(), is_reading_(false), - exit_code_(1) { - child_.hProcess = NULL; -} - -Subprocess::~Subprocess() { - if (pipe_) { - if (!CloseHandle(pipe_)) - Win32Fatal("CloseHandle"); - } - // Reap child if forgotten. - if (child_.hProcess) - Finish(); -} - -HANDLE Subprocess::SetupPipe(HANDLE ioport) { - char pipe_name[100]; - snprintf(pipe_name, sizeof(pipe_name), - "\\\\.\\pipe\\ninja_pid%u_sp%p", GetCurrentProcessId(), this); - - pipe_ = ::CreateNamedPipeA(pipe_name, - PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_BYTE, - PIPE_UNLIMITED_INSTANCES, - 0, 0, INFINITE, NULL); - if (pipe_ == INVALID_HANDLE_VALUE) - Win32Fatal("CreateNamedPipe"); - - if (!CreateIoCompletionPort(pipe_, ioport, (cmULONG_PTR)this, 0)) - Win32Fatal("CreateIoCompletionPort"); - - memset(&overlapped_, 0, sizeof(overlapped_)); - if (!ConnectNamedPipe(pipe_, &overlapped_) && - GetLastError() != ERROR_IO_PENDING) { - Win32Fatal("ConnectNamedPipe"); - } - - // Get the write end of the pipe as a handle inheritable across processes. - HANDLE output_write_handle = CreateFile(pipe_name, GENERIC_WRITE, 0, - NULL, OPEN_EXISTING, 0, NULL); - HANDLE output_write_child; - if (!DuplicateHandle(GetCurrentProcess(), output_write_handle, - GetCurrentProcess(), &output_write_child, - 0, TRUE, DUPLICATE_SAME_ACCESS)) { - Win32Fatal("DuplicateHandle"); - } - CloseHandle(output_write_handle); - - return output_write_child; -} - -bool Subprocess::Start(SubprocessSet* set, const std::string& command, - const std::string& dir) { - HANDLE child_pipe = SetupPipe(set->ioport_); - - SECURITY_ATTRIBUTES security_attributes; - memset(&security_attributes, 0, sizeof(SECURITY_ATTRIBUTES)); - security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES); - security_attributes.bInheritHandle = TRUE; - // Must be inheritable so subprocesses can dup to children. - HANDLE nul = CreateFile("NUL", GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - &security_attributes, OPEN_EXISTING, 0, NULL); - if (nul == INVALID_HANDLE_VALUE) - Fatal("couldn't open nul"); - - STARTUPINFOA startup_info; - memset(&startup_info, 0, sizeof(startup_info)); - startup_info.cb = sizeof(STARTUPINFO); - startup_info.dwFlags = STARTF_USESTDHANDLES; - startup_info.hStdInput = nul; - startup_info.hStdOutput = child_pipe; - startup_info.hStdError = child_pipe; - - PROCESS_INFORMATION process_info; - memset(&process_info, 0, sizeof(process_info)); - - // Do not prepend 'cmd /c' on Windows, this breaks command - // lines greater than 8,191 chars. - if (!CreateProcessA(NULL, (char*)command.c_str(), NULL, NULL, - /* inherit handles */ TRUE, CREATE_NEW_PROCESS_GROUP, - NULL, (dir.empty() ? NULL : dir.c_str()), - &startup_info, &process_info)) { - DWORD error = GetLastError(); - if (error == ERROR_FILE_NOT_FOUND) { - // file (program) not found error is treated - // as a normal build action failure - if (child_pipe) - CloseHandle(child_pipe); - CloseHandle(pipe_); - CloseHandle(nul); - pipe_ = NULL; - // child_ is already NULL; - buf_ = - "CreateProcess failed: The system cannot find the file specified.\n"; - return true; - } else { - Win32Fatal("CreateProcess"); // pass all other errors to Win32Fatal - } - } - - // Close pipe channel only used by the child. - if (child_pipe) - CloseHandle(child_pipe); - CloseHandle(nul); - - CloseHandle(process_info.hThread); - child_ = process_info; - - return true; -} - -void Subprocess::OnPipeReady() { - DWORD bytes; - if (!GetOverlappedResult(pipe_, &overlapped_, &bytes, TRUE)) { - if (GetLastError() == ERROR_BROKEN_PIPE) { - CloseHandle(pipe_); - pipe_ = NULL; - return; - } - Win32Fatal("GetOverlappedResult"); - } - - if (is_reading_ && bytes) - buf_.append(overlapped_buf_, bytes); - - memset(&overlapped_, 0, sizeof(overlapped_)); - is_reading_ = true; - if (!::ReadFile(pipe_, overlapped_buf_, sizeof(overlapped_buf_), - &bytes, &overlapped_)) { - if (GetLastError() == ERROR_BROKEN_PIPE) { - CloseHandle(pipe_); - pipe_ = NULL; - return; - } - if (GetLastError() != ERROR_IO_PENDING) - Win32Fatal("ReadFile"); - } - - // Even if we read any bytes in the readfile call, we'll enter this - // function again later and get them at that point. -} - -ExitStatus Subprocess::Finish() { - if (!child_.hProcess) - return ExitFailure; - - // TODO: add error handling for all of these. - WaitForSingleObject(child_.hProcess, INFINITE); - - DWORD exit_code = 0; - GetExitCodeProcess(child_.hProcess, &exit_code); - - CloseHandle(child_.hProcess); - child_.hProcess = NULL; - exit_code_ = exit_code; - return exit_code == 0 ? ExitSuccess : - exit_code == CONTROL_C_EXIT ? ExitInterrupted : - ExitFailure; -} - -bool Subprocess::Done() const { - return pipe_ == NULL; } -const std::string& Subprocess::GetOutput() const { - return buf_; -} - -HANDLE SubprocessSet::ioport_; - -SubprocessSet::SubprocessSet() { - ioport_ = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); - if (!ioport_) - Win32Fatal("CreateIoCompletionPort"); - if (!SetConsoleCtrlHandler(NotifyInterrupted, TRUE)) - Win32Fatal("SetConsoleCtrlHandler"); -} - -SubprocessSet::~SubprocessSet() { - Clear(); - - SetConsoleCtrlHandler(NotifyInterrupted, FALSE); - CloseHandle(ioport_); -} - -BOOL WINAPI SubprocessSet::NotifyInterrupted(DWORD dwCtrlType) { - if (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_BREAK_EVENT) { - if (!PostQueuedCompletionStatus(ioport_, 0, 0, NULL)) - Win32Fatal("PostQueuedCompletionStatus"); - return TRUE; - } - - return FALSE; -} - -Subprocess *SubprocessSet::Add(const std::string& command, - const std::string& dir) { - Subprocess *subprocess = new Subprocess; - if (!subprocess->Start(this, command, dir)) { - delete subprocess; - return 0; - } - if (subprocess->child_.hProcess) - running_.push_back(subprocess); - else - finished_.push(subprocess); - return subprocess; -} - -bool SubprocessSet::DoWork() { - DWORD bytes_read; - Subprocess* subproc; - OVERLAPPED* overlapped; - - if (!GetQueuedCompletionStatus(ioport_, &bytes_read, (cmULONG_PTR*)&subproc, - &overlapped, INFINITE)) { - if (GetLastError() != ERROR_BROKEN_PIPE) - Win32Fatal("GetQueuedCompletionStatus"); - } - - if (!subproc) // A NULL subproc indicates that we were interrupted and is - // delivered by NotifyInterrupted above. - return true; - - subproc->OnPipeReady(); - - if (subproc->Done()) { - std::vector::iterator end = - std::remove(running_.begin(), running_.end(), subproc); - if (running_.end() != end) { - finished_.push(subproc); - running_.resize(end - running_.begin()); - } - } - - return false; -} - -Subprocess* SubprocessSet::NextFinished() { - if (finished_.empty()) - return NULL; - Subprocess* subproc = finished_.front(); - finished_.pop(); - return subproc; -} - -void SubprocessSet::Clear() { - std::vector::iterator it = running_.begin(); - for (; it != running_.end(); ++it) { - if ((*it)->child_.hProcess) { - if (!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, - (*it)->child_.dwProcessId)) - Win32Fatal("GenerateConsoleCtrlEvent"); - } - } - it = running_.begin(); - for (; it != running_.end(); ++it) - delete *it; - running_.clear(); -} - - -// Copyright 2011 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -// Wrapper around cl that adds /showIncludes to command line, and uses that to -// generate .d files that match the style from gcc -MD. -// -// /showIncludes is equivalent to -MD, not -MMD, that is, system headers are -// included. - - -#include -#include -//#include "subprocess.h" -//#include "util.h" - -// We don't want any wildcard expansion. -// See http://msdn.microsoft.com/en-us/library/zay8tzh6(v=vs.85).aspx -void _setargv() {} - static void usage(const char* msg) { Fatal("%s\n\nusage:\n " "cmcldeps " @@ -629,23 +175,23 @@ static int process( const std::string& srcfilename, const std::string& prefix, const std::string& cmd, const std::string& dir = "", - bool quiet = false) { - - SubprocessSet subprocs; - Subprocess* subproc = subprocs.Add(cmd, dir); - - if(!subproc) - return 2; - - while ((subproc = subprocs.NextFinished()) == NULL) { - subprocs.DoWork(); - } - - bool success = subproc->Finish() == ExitSuccess; - int exit_code = subproc->ExitCode(); - - std::string output = subproc->GetOutput(); - delete subproc; + bool quiet = false) +{ + std::string output; + // break up command line into a vector + std::vector args; + cmSystemTools::ParseWindowsCommandLine(cmd.c_str(), args); + // convert to correct vector type for RunSingleCommand + std::vector command; + for(std::vector::iterator i = args.begin(); + i != args.end(); ++i) + { + command.push_back(i->c_str()); + } + // run the command + int exit_code = 0; + bool run = cmSystemTools::RunSingleCommand(command, &output, &exit_code, + dir.c_str(), cmSystemTools::OUTPUT_NONE); // process the include directives and output everything else std::stringstream ss(output); @@ -660,7 +206,7 @@ static int process( const std::string& srcfilename, includes.push_back(inc); } else { if (!isFirstLine || !startsWith(line, srcfilename)) { - if (!quiet) { + if (!quiet || exit_code != 0) { fprintf(stdout, "%s\n", line.c_str()); } } else { @@ -669,14 +215,11 @@ static int process( const std::string& srcfilename, } } - if (!success) { - return exit_code; - } - // don't update .d until/unless we succeed compilation - outputDepFile(dfile, objfile, includes); + if (run && exit_code == 0) + outputDepFile(dfile, objfile, includes); - return 0; + return exit_code; } @@ -711,7 +254,10 @@ int main() { // rc: /fo x.dir\x.rc.res -> cl: /out:x.dir\x.rc.res.dep.obj clrest = replace(clrest, "/fo", "/out:"); clrest = replace(clrest, objfile, objfile + ".dep.obj "); + // rc: src\x\x.rc -> cl: /Tc src\x\x.rc + if (srcfile.find(" ") != std::string::npos) + srcfile = "\"" + srcfile + "\""; clrest = replace(clrest, srcfile, "/Tc " + srcfile); cl = "\"" + cl + "\" /P /DRC_INVOKED "; @@ -724,8 +270,11 @@ int main() { } // extract dependencies with cl.exe - process(srcfilename, dfile, objfile, - prefix, cl + nol + show + clrest, objdir, true); + int exit_code = process(srcfilename, dfile, objfile, + prefix, cl + nol + show + clrest, objdir, true); + + if (exit_code != 0) + return exit_code; // compile rc file with rc.exe return process(srcfilename, "" , objfile, prefix, binpath + " " + rest); diff --git a/Source/ctest.cxx b/Source/ctest.cxx index d41627e26..d65077748 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -103,6 +103,12 @@ static const char * cmDocumentationOptions[][3] = "a dashboard test. All tests are , where Mode can be " "Experimental, Nightly, and Continuous, and Test can be Start, Update, " "Configure, Build, Test, Coverage, and Submit."}, + {"-D :=", "Define a variable for script mode", + "Pass in variable values on the command line. Use in " + "conjunction with -S to pass variable values to a dashboard script. " + "Parsing -D arguments as variable values is only attempted if " + "the value following -D does not match any of the known dashboard " + "types."}, {"-M , --test-model ", "Sets the model for a dashboard", "This option tells ctest to act as a Dart client " "where the TestModel can be Experimental, " diff --git a/Tests/BuildDepends/Project/CMakeLists.txt b/Tests/BuildDepends/Project/CMakeLists.txt index a977884c9..ed8b8bf5d 100644 --- a/Tests/BuildDepends/Project/CMakeLists.txt +++ b/Tests/BuildDepends/Project/CMakeLists.txt @@ -17,7 +17,8 @@ endfunction() if(APPLE) # only use multi-arch if the sysroot exists on this machine - if(EXISTS "${CMAKE_OSX_SYSROOT}") + # Ninja needs -M which could not be used with multiple -arch flags + if(EXISTS "${CMAKE_OSX_SYSROOT}" AND NOT "${CMAKE_GENERATOR}" MATCHES "Ninja") set(CMAKE_OSX_ARCHITECTURES "ppc;i386") test_for_xcode4(is_xcode4) if(is_xcode4) @@ -25,7 +26,7 @@ if(APPLE) # Arch 'ppc' no longer works: tools no longer available starting with Xcode 4 set(CMAKE_OSX_ARCHITECTURES i386 x86_64) endif() - endif(EXISTS "${CMAKE_OSX_SYSROOT}") + endif() endif(APPLE) add_library(foo STATIC ${testRebuild_BINARY_DIR}/foo.cxx) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 9deb8acb2..27ae3a072 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -717,31 +717,21 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ENDIF(CTEST_RUN_CPackComponents) IF(CTEST_RUN_CPackComponentsForAll) - # Analyze 'cpack --help' output for list of available generators: - execute_process(COMMAND ${CMAKE_CPACK_COMMAND} --help - RESULT_VARIABLE result - OUTPUT_VARIABLE stdout - ERROR_VARIABLE stderr) - - string(REPLACE ";" "\\;" stdout "${stdout}") - string(REPLACE "\n" "E;" stdout "${stdout}") - - set(collecting 0) - set(ACTIVE_CPACK_GENERATORS) - foreach(eline ${stdout}) - string(REGEX REPLACE "^(.*)E$" "\\1" line "${eline}") - if(collecting AND NOT line STREQUAL "") - string(REGEX REPLACE "^ ([^ ]+) += (.*)$" "\\1" gen "${line}") - string(REGEX REPLACE "^ ([^ ]+) += (.*)$" "\\2" doc "${line}") - list(APPEND ACTIVE_CPACK_GENERATORS ${gen}) - endif() - if(line STREQUAL "Generators") - set(collecting 1) - endif() - endforeach() + # Check whether if rpmbuild command is found + # before adding RPM tests + find_program(RPMBUILD_EXECUTABLE NAMES rpmbuild) + if(RPMBUILD_EXECUTABLE) + list(APPEND ACTIVE_CPACK_GENERATORS RPM) + endif(RPMBUILD_EXECUTABLE) + # Check whether if dpkg command is found + # before adding DEB tests + find_program(DPKG_EXECUTABLE NAMES dpkg) + if(DPKG_EXECUTABLE) + list(APPEND ACTIVE_CPACK_GENERATORS DEB) + endif(DPKG_EXECUTABLE) + # ACTIVE_CPACK_GENERATORS variable # now contains the list of 'active generators' - set(CPackComponentsForAll_EXTRA_OPTIONS) set(CPackRun_CPackCommand "-DCPackCommand=${CMAKE_CPACK_COMMAND}") # set up list of CPack generators @@ -1418,42 +1408,44 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSMidl") ENDIF(${CMAKE_TEST_GENERATOR} MATCHES "Visual Studio") - IF (APPLE AND CMAKE_COMPILER_IS_GNUCXX) - SET(BundleTestInstallDir - "${CMake_BINARY_DIR}/Tests/BundleTest/InstallDirectory") - ADD_TEST(BundleTest ${CMAKE_CTEST_COMMAND} - --build-and-test - "${CMake_SOURCE_DIR}/Tests/BundleTest" - "${CMake_BINARY_DIR}/Tests/BundleTest" - --build-two-config - --build-generator ${CMAKE_TEST_GENERATOR} - --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} - --build-project BundleTest - --build-target install -# --build-target package - --build-options "-DCMAKE_INSTALL_PREFIX:PATH=${BundleTestInstallDir}" - "-DCMake_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}" - --test-command - ${BundleTestInstallDir}/Applications/SecondBundleExe.app/Contents/MacOS/SecondBundleExe) - LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleTest") - - ADD_TEST(CFBundleTest ${CMAKE_CTEST_COMMAND} - --build-and-test - "${CMake_SOURCE_DIR}/Tests/CFBundleTest" - "${CMake_BINARY_DIR}/Tests/CFBundleTest" - --build-two-config - --build-generator ${CMAKE_TEST_GENERATOR} - --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} - --build-project CFBundleTest - --test-command - ${CMAKE_CMAKE_COMMAND} -DCTEST_CONFIGURATION_TYPE=\${CTEST_CONFIGURATION_TYPE} + IF (APPLE) + if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + SET(BundleTestInstallDir + "${CMake_BINARY_DIR}/Tests/BundleTest/InstallDirectory") + ADD_TEST(BundleTest ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/BundleTest" + "${CMake_BINARY_DIR}/Tests/BundleTest" + --build-two-config + --build-generator ${CMAKE_TEST_GENERATOR} + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-project BundleTest + --build-target install +# --build-target package + --build-options "-DCMAKE_INSTALL_PREFIX:PATH=${BundleTestInstallDir}" + "-DCMake_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}" + --test-command + ${BundleTestInstallDir}/Applications/SecondBundleExe.app/Contents/MacOS/SecondBundleExe) + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleTest") + + ADD_TEST(CFBundleTest ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/CFBundleTest" + "${CMake_BINARY_DIR}/Tests/CFBundleTest" + --build-two-config + --build-generator ${CMAKE_TEST_GENERATOR} + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-project CFBundleTest + --test-command + ${CMAKE_CMAKE_COMMAND} -DCTEST_CONFIGURATION_TYPE=\${CTEST_CONFIGURATION_TYPE} -Ddir=${CMake_BINARY_DIR}/Tests/CFBundleTest -Dgen=${CMAKE_TEST_GENERATOR} -P ${CMake_SOURCE_DIR}/Tests/CFBundleTest/VerifyResult.cmake) - LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CFBundleTest") + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CFBundleTest") - ADD_TEST_MACRO(ObjC++ ObjC++) - ENDIF (APPLE AND CMAKE_COMPILER_IS_GNUCXX) + ADD_TEST_MACRO(ObjC++ ObjC++) + ENDIF (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + ENDIF (APPLE) IF(APPLE AND CTEST_TEST_CPACK) ADD_TEST(BundleGeneratorTest ${CMAKE_CTEST_COMMAND} @@ -1822,6 +1814,19 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ add_config_tests(Release) add_config_tests(RelWithDebInfo) + # Test -S script with some -D variable definition args to ctest: + add_test(CTestConfig.ScriptWithArgs ${CMAKE_CTEST_COMMAND} + -C "Release" + -D arg1=this + -D arg2=that + -D "arg3=the other" + "-Darg4=this is the fourth" + -Darg5=the_fifth + -Darg6:STRING=value-with-type + -S "${CMake_SOURCE_DIR}/Tests/CTestConfig/ScriptWithArgs.cmake" -VV + --output-log "${CMake_BINARY_DIR}/Tests/CTestConfig/ScriptWithArgs.log" + ) + ADD_TEST_MACRO(CMakeCommands.target_link_libraries target_link_libraries) CONFIGURE_FILE( diff --git a/Tests/CTestConfig/ScriptWithArgs.cmake b/Tests/CTestConfig/ScriptWithArgs.cmake new file mode 100644 index 000000000..79896a7fc --- /dev/null +++ b/Tests/CTestConfig/ScriptWithArgs.cmake @@ -0,0 +1,16 @@ +set(CTEST_RUN_CURRENT_SCRIPT 0) + +macro(check_arg name expected_value) + message("${name}='${${name}}'") + if(NOT "${${name}}" STREQUAL "${expected_value}") + message(FATAL_ERROR "unexpected ${name} value '${${name}}', expected '${expected_value}'") + endif() +endmacro() + +check_arg(arg1 "this") +check_arg(arg2 "that") +check_arg(arg3 "the other") +check_arg(arg4 "this is the fourth") +check_arg(arg5 "the_fifth") +check_arg(arg6 "value-with-type") +check_arg(arg7 "") diff --git a/Tests/CTestUpdateSVN.cmake.in b/Tests/CTestUpdateSVN.cmake.in index edafb4ef2..15b833b10 100644 --- a/Tests/CTestUpdateSVN.cmake.in +++ b/Tests/CTestUpdateSVN.cmake.in @@ -41,7 +41,6 @@ init_testing() #----------------------------------------------------------------------------- # Create the repository. message("Creating repository...") -file(MAKE_DIRECTORY ${TOP}/repo) run_child( COMMAND ${SVNADMIN} create --config-dir ${TOP}/config ${TOP}/repo ) diff --git a/Tests/CustomCommand/GeneratedHeader/main.cpp b/Tests/CustomCommand/GeneratedHeader/main.cpp index 1b3e85ffe..0b43ffe83 100644 --- a/Tests/CustomCommand/GeneratedHeader/main.cpp +++ b/Tests/CustomCommand/GeneratedHeader/main.cpp @@ -1,5 +1,5 @@ #include "generated.h" -int main() +int mainGeneratedHeader() { return 0; } diff --git a/Tests/LibName/CMakeLists.txt b/Tests/LibName/CMakeLists.txt index 3dca0b003..07499a14d 100644 --- a/Tests/LibName/CMakeLists.txt +++ b/Tests/LibName/CMakeLists.txt @@ -3,11 +3,24 @@ project(LibName) # LIBRARY_OUTPUT_PATH and EXECUTABLE_OUTPUT_PATH work set(LIBRARY_OUTPUT_PATH lib) set(EXECUTABLE_OUTPUT_PATH lib) + add_library(bar SHARED bar.c) + add_library(foo SHARED foo.c) target_link_libraries(foo bar) + add_executable(foobar foobar.c) target_link_libraries(foobar foo) IF(UNIX) target_link_libraries(foobar -L/usr/local/lib) ENDIF(UNIX) + + +# check with lib version + +add_library(verFoo SHARED foo.c) +target_link_libraries(verFoo bar) +set_target_properties(verFoo PROPERTIES VERSION 3.1.4 SOVERSION 3) + +add_executable(verFoobar foobar.c) +target_link_libraries(verFoobar verFoo) diff --git a/Tests/ObjC++/objc++.mm b/Tests/ObjC++/objc++.mm index b7ec4b5f5..f0be25682 100644 --- a/Tests/ObjC++/objc++.mm +++ b/Tests/ObjC++/objc++.mm @@ -1,5 +1,6 @@ -#import #import +#import +using namespace std; int main() { diff --git a/Tests/PositionIndependentTargets/pic_test.h b/Tests/PositionIndependentTargets/pic_test.h index 3f64557e9..13cf8f79f 100644 --- a/Tests/PositionIndependentTargets/pic_test.h +++ b/Tests/PositionIndependentTargets/pic_test.h @@ -1,7 +1,7 @@ #if defined(__ELF__) -# if !defined(__PIC__) -# error "The POSITION_INDEPENDENT_CODE property should cause __PIC__ to be defined on ELF platforms." +# if !defined(__PIC__) && !defined(__PIE__) +# error "The POSITION_INDEPENDENT_CODE property should cause __PIC__ or __PIE__ to be defined on ELF platforms." # endif #endif diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 23fc086d8..eca96f907 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -50,6 +50,7 @@ add_RunCMake_test(ObjectLibrary) add_RunCMake_test(build_command) add_RunCMake_test(find_package) +add_RunCMake_test(include) add_RunCMake_test(list) if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]") diff --git a/Tests/RunCMake/include/CMakeLists.txt b/Tests/RunCMake/include/CMakeLists.txt new file mode 100644 index 000000000..e8db6b05b --- /dev/null +++ b/Tests/RunCMake/include/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/include/EmptyString-stderr.txt b/Tests/RunCMake/include/EmptyString-stderr.txt new file mode 100644 index 000000000..006c647c6 --- /dev/null +++ b/Tests/RunCMake/include/EmptyString-stderr.txt @@ -0,0 +1,5 @@ +CMake Warning \(dev\) at EmptyString.cmake:1 \(include\): + include\(\) given empty file name \(ignored\). +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/include/EmptyString.cmake b/Tests/RunCMake/include/EmptyString.cmake new file mode 100644 index 000000000..4285cb3d5 --- /dev/null +++ b/Tests/RunCMake/include/EmptyString.cmake @@ -0,0 +1 @@ +include("") diff --git a/Tests/RunCMake/include/EmptyStringOptional-stderr.txt b/Tests/RunCMake/include/EmptyStringOptional-stderr.txt new file mode 100644 index 000000000..b61c67912 --- /dev/null +++ b/Tests/RunCMake/include/EmptyStringOptional-stderr.txt @@ -0,0 +1,5 @@ +CMake Warning \(dev\) at EmptyStringOptional.cmake:1 \(include\): + include\(\) given empty file name \(ignored\). +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/include/EmptyStringOptional.cmake b/Tests/RunCMake/include/EmptyStringOptional.cmake new file mode 100644 index 000000000..549d46b3d --- /dev/null +++ b/Tests/RunCMake/include/EmptyStringOptional.cmake @@ -0,0 +1 @@ +include("" OPTIONAL) diff --git a/Tests/RunCMake/include/RunCMakeTest.cmake b/Tests/RunCMake/include/RunCMakeTest.cmake new file mode 100644 index 000000000..59b87ca75 --- /dev/null +++ b/Tests/RunCMake/include/RunCMakeTest.cmake @@ -0,0 +1,4 @@ +include(RunCMake) + +run_cmake(EmptyString) +run_cmake(EmptyStringOptional) diff --git a/Tests/X11/HelloWorldX11.cxx b/Tests/X11/HelloWorldX11.cxx index 5bbc19a4a..e3c9dd9cf 100644 --- a/Tests/X11/HelloWorldX11.cxx +++ b/Tests/X11/HelloWorldX11.cxx @@ -15,6 +15,7 @@ #define MAIN_H 1 #include +#include /* include the X library headers */ #include diff --git a/Utilities/Git/pre-commit b/Utilities/Git/pre-commit index 110e9ee35..d308a81b5 100755 --- a/Utilities/Git/pre-commit +++ b/Utilities/Git/pre-commit @@ -19,6 +19,26 @@ die() { exit 1 } +#------------------------------------------------------------------------------- +line_too_long=80 +bad=$(regex=".{$line_too_long}" && +git diff-index --cached HEAD --name-only --diff-filter=AM \ + --pickaxe-regex -S"$regex" -- 'Source/*.h' 'Source/*.cxx' | +while read file; do + lines_too_long=$(git diff-index -p --cached HEAD \ + --pickaxe-regex -S"$regex" -- "$file") + if echo "$lines_too_long" | egrep -q '^\+'"$regex"; then + echo "$lines_too_long" + fi +done) +test -z "$bad" || +die 'The following changes add lines too long for our C++ style: + +'"$bad"' + +Use lines strictly less than '"$line_too_long"' characters in C++ code.' + +#------------------------------------------------------------------------------- if test -z "$HOOKS_ALLOW_KWSYS"; then # Disallow changes to KWSys files=$(git diff-index --name-only --cached HEAD -- Source/kwsys) && diff --git a/Utilities/KWIML/ABI.h.in b/Utilities/KWIML/ABI.h.in index e85a1c588..060a520db 100644 --- a/Utilities/KWIML/ABI.h.in +++ b/Utilities/KWIML/ABI.h.in @@ -156,6 +156,8 @@ suppression macro @KWIML@_ABI_NO_VERIFY was defined. # define @KWIML@_ABI_CHAR_IS_UNSIGNED 1 # elif defined(__BORLANDC__) /* Borland default */ # define @KWIML@_ABI_CHAR_IS_SIGNED 1 +# elif defined(__hpux) /* Old HP: no __HP_cc/__HP_aCC/__GNUC__ above */ +# define @KWIML@_ABI_CHAR_IS_SIGNED 1 /* (unless +uc) */ # endif #endif #if !defined(@KWIML@_ABI_CHAR_IS_UNSIGNED) && !defined(@KWIML@_ABI_CHAR_IS_SIGNED) \ @@ -251,6 +253,8 @@ suppression macro @KWIML@_ABI_NO_VERIFY was defined. # else # define @KWIML@_ABI_SIZEOF_LONG_LONG 0 # endif +# elif defined(__hpux) && !defined(__GNUC__) /* Old HP: no __HP_cc/__HP_aCC above */ +# define @KWIML@_ABI_SIZEOF_LONG_LONG 8 # endif #endif #if !defined(@KWIML@_ABI_SIZEOF_LONG_LONG) && !defined(@KWIML@_ABI_NO_ERROR_LONG_LONG) diff --git a/Utilities/KWIML/INT.h.in b/Utilities/KWIML/INT.h.in index d40edcde4..d2eda6387 100644 --- a/Utilities/KWIML/INT.h.in +++ b/Utilities/KWIML/INT.h.in @@ -91,10 +91,11 @@ An includer may test the following macros after inclusion: Some compilers define integer format macros incorrectly for their own formatted print/scan implementations. - @KWIML@_INT_BROKEN_INT64_C = macro INT64_C is incorrect if defined - @KWIML@_INT_BROKEN_UINT64_C = macro UINT64_C is incorrect if defined + @KWIML@_INT_BROKEN_INT#_C = macro INT#_C is incorrect if defined + @KWIML@_INT_BROKEN_UINT#_C = macro UINT#_C is incorrect if defined Some compilers define integer constant macros incorrectly and - cannot handle literals as large as the integer type. + cannot handle literals as large as the integer type or even + produce bad preprocessor syntax. @KWIML@_INT_BROKEN_INT8_T = type 'int8_t' is available but incorrect Some compilers have a flag to make 'char' (un)signed but do not account @@ -259,8 +260,6 @@ An includer may test the following macros after inclusion: # endif #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) # define @KWIML@_INT__NO_SCN8 -#elif defined(__HP_cc) || defined(__HP_aCC) -# define @KWIML@_INT__NO_SCN8 #elif defined(__BORLANDC__) # define @KWIML@_INT__NO_SCN8 # define @KWIML@_INT__NO_SCN64 @@ -268,6 +267,8 @@ An includer may test the following macros after inclusion: # define @KWIML@_INT__NO_SCN8 #elif defined(__WATCOMC__) # define @KWIML@_INT__NO_SCN8 +# elif defined(__hpux) /* HP runtime lacks support (any compiler) */ +# define @KWIML@_INT__NO_SCN8 #endif /* 8-bit d, i */ @@ -341,12 +342,12 @@ An includer may test the following macros after inclusion: #endif /* 8-bit constants */ -#if defined(INT8_C) +#if defined(INT8_C) && !defined(@KWIML@_INT_BROKEN_INT8_C) # define @KWIML@_INT_INT8_C(c) INT8_C(c) #else # define @KWIML@_INT_INT8_C(c) c #endif -#if defined(UINT8_C) +#if defined(UINT8_C) && !defined(@KWIML@_INT_BROKEN_UINT8_C) # define @KWIML@_INT_UINT8_C(c) UINT8_C(c) #else # define @KWIML@_INT_UINT8_C(c) c ## u @@ -435,12 +436,12 @@ An includer may test the following macros after inclusion: #endif /* 16-bit constants */ -#if defined(INT16_C) +#if defined(INT16_C) && !defined(@KWIML@_INT_BROKEN_INT16_C) # define @KWIML@_INT_INT16_C(c) INT16_C(c) #else # define @KWIML@_INT_INT16_C(c) c #endif -#if defined(UINT16_C) +#if defined(UINT16_C) && !defined(@KWIML@_INT_BROKEN_UINT16_C) # define @KWIML@_INT_UINT16_C(c) UINT16_C(c) #else # define @KWIML@_INT_UINT16_C(c) c ## u @@ -528,13 +529,19 @@ An includer may test the following macros after inclusion: # define @KWIML@_INT_PRIX32 "X" #endif +#if defined(__hpux) && defined(__GNUC__) && !defined(__LP64__) \ + && defined(__CONCAT__) && defined(__CONCAT_U__) + /* Some HPs define UINT32_C incorrectly and break GNU. */ +# define @KWIML@_INT_BROKEN_UINT32_C +#endif + /* 32-bit constants */ -#if defined(INT32_C) +#if defined(INT32_C) && !defined(@KWIML@_INT_BROKEN_INT32_C) # define @KWIML@_INT_INT32_C(c) INT32_C(c) #else # define @KWIML@_INT_INT32_C(c) c #endif -#if defined(UINT32_C) +#if defined(UINT32_C) && !defined(@KWIML@_INT_BROKEN_UINT32_C) # define @KWIML@_INT_UINT32_C(c) UINT32_C(c) #else # define @KWIML@_INT_UINT32_C(c) c ## u diff --git a/bootstrap b/bootstrap index 9d98f4713..801882d7a 100755 --- a/bootstrap +++ b/bootstrap @@ -72,14 +72,14 @@ else cmake_system_darwin=false fi -# Determine whether this is BeOS +# Determine whether this is BeOS if echo "${cmake_system}" | grep BeOS >/dev/null 2>&1; then cmake_system_beos=true else cmake_system_beos=false fi -# Determine whether this is Haiku +# Determine whether this is Haiku if echo "${cmake_system}" | grep Haiku >/dev/null 2>&1; then cmake_system_haiku=true else @@ -220,6 +220,7 @@ CMAKE_CXX_SOURCES="\ cmMakefileLibraryTargetGenerator \ cmMakefileTargetGenerator \ cmMakefileUtilityTargetGenerator \ + cmOSXBundleGenerator \ cmNewLineStyle \ cmBootstrapCommands \ cmCommands \ @@ -238,6 +239,11 @@ CMAKE_CXX_SOURCES="\ cmExprLexer \ cmExprParser \ cmExprParserHelper \ + cmGlobalNinjaGenerator \ + cmLocalNinjaGenerator \ + cmNinjaTargetGenerator \ + cmNinjaNormalTargetGenerator \ + cmNinjaUtilityTargetGenerator \ " if ${cmake_system_mingw}; then @@ -351,7 +357,7 @@ cmake_error() res=$1 shift 1 echo "---------------------------------------------" - echo "Error when bootstrapping CMake:" + echo "Error when bootstrapping CMake:" echo "$*" echo "---------------------------------------------" if [ -f cmake_bootstrap.log ]; then @@ -370,7 +376,7 @@ cmake_replace_string () SEARCHFOR="$3" REPLACEWITH="$4" if [ -f "${INFILE}" ] || ${cmake_system_openvms}; then - cat "${INFILE}" | + cat "${INFILE}" | sed "s/\@${SEARCHFOR}\@/${REPLACEWITH}/g" > "${OUTFILE}${_tmp}" if [ -f "${OUTFILE}${_tmp}" ]; then if "${_diff}" "${OUTFILE}" "${OUTFILE}${_tmp}" > /dev/null 2> /dev/null ; then @@ -393,7 +399,7 @@ cmake_kwsys_config_replace_string () APPEND="$*" if [ -f "${INFILE}" ] || ${cmake_system_openvms}; then echo "${APPEND}" > "${OUTFILE}${_tmp}" - cat "${INFILE}" | + cat "${INFILE}" | sed "/./ {s/\@KWSYS_NAMESPACE\@/cmsys/g; s/@KWSYS_BUILD_SHARED@/${KWSYS_BUILD_SHARED}/g; s/@KWSYS_LFS_AVAILABLE@/${KWSYS_LFS_AVAILABLE}/g; @@ -797,7 +803,7 @@ echo ' # include #endif -class NeedCXX +class NeedCXX { public: NeedCXX() { this->Foo = 1; } @@ -1387,12 +1393,12 @@ cmake_kwsys_config_replace_string \ "${cmake_bootstrap_dir}/cmsys/Configure.h" \ "${cmake_compiler_settings_comment}" -for a in ${KWSYS_FILES}; do +for a in ${KWSYS_FILES}; do cmake_replace_string "${cmake_source_dir}/Source/kwsys/${a}.in" \ "${cmake_bootstrap_dir}/cmsys/${a}" KWSYS_NAMESPACE cmsys done -for a in ${KWSYS_IOS_FILES}; do +for a in ${KWSYS_IOS_FILES}; do cmake_replace_string "${cmake_source_dir}/Source/kwsys/kwsys_ios_${a}.h.in" \ "${cmake_bootstrap_dir}/cmsys/ios/${a}" KWSYS_NAMESPACE cmsys done