diff options
author | Bill Hoffman <bill.hoffman@kitware.com> | 2008-03-31 17:57:41 -0400 |
---|---|---|
committer | Bill Hoffman <bill.hoffman@kitware.com> | 2008-03-31 17:57:41 -0400 |
commit | 0210ed41681dced2ed752efd0e1706c4a4726077 (patch) | |
tree | 2a2568c2fb0e4f7d963ed8ef6ca4f33586bd0cb1 | |
parent | bf5f91f058155c136443e922a3bec6811729a0f3 (diff) | |
download | cmake-0210ed41681dced2ed752efd0e1706c4a4726077.tar.gz |
ENH: merge changes from head to 26 branch
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | ChangeLog.manual | 6 | ||||
-rw-r--r-- | Modules/FindMPI.cmake | 228 | ||||
-rw-r--r-- | Source/cmComputeLinkDepends.cxx | 37 | ||||
-rw-r--r-- | Source/cmComputeLinkDepends.h | 9 | ||||
-rw-r--r-- | Source/cmComputeLinkInformation.cxx | 20 | ||||
-rw-r--r-- | Source/cmExportFileGenerator.cxx | 12 | ||||
-rw-r--r-- | Source/cmListFileCache.cxx | 30 | ||||
-rw-r--r-- | Source/cmLocalVisualStudio7Generator.cxx | 41 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 67 | ||||
-rw-r--r-- | Source/cmMakefile.h | 8 | ||||
-rw-r--r-- | Source/cmPolicies.cxx | 10 |
12 files changed, 324 insertions, 146 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 63ed5645c3..392829dc4a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -354,7 +354,7 @@ ENDMACRO (CMAKE_BUILD_UTILITIES) SET(CMake_VERSION_MAJOR 2) SET(CMake_VERSION_MINOR 6) SET(CMake_VERSION_PATCH 0) -SET(CMake_VERSION_RC 51) +SET(CMake_VERSION_RC 52) # CVS versions are odd, if this is an odd minor version # then set the CMake_VERSION_DATE variable IF("${CMake_VERSION_MINOR}" MATCHES "[13579]$") diff --git a/ChangeLog.manual b/ChangeLog.manual index 9d7295ccb6..b68ade35ea 100644 --- a/ChangeLog.manual +++ b/ChangeLog.manual @@ -15,6 +15,12 @@ Changes in CMake 2.6.0 RC 6 - Fix some missing flags for vs IDE flag map - Fix MacOSX install symlink crash problem - Fix turning of Dev warnings with gui's +- Fix backwards compatibility issue with FindMPI.cmake +- Fix for bug 6605, add -L path for optimized in debug sometimes for + backwards compatibility +- Allow for CMP0000 to be set before any warnings happen +- Do not use FAT32 hack in VS 2005 and 2008 unless on a FAT32 disk, + causes try-compiles to be 3 times slower if FAT hack is present. Changes in CMake 2.6.0 diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake index 627effce14..5e218e7074 100644 --- a/Modules/FindMPI.cmake +++ b/Modules/FindMPI.cmake @@ -1,95 +1,132 @@ -# This module looks for the Message Passing Interface (MPI). +# - Message Passing Interface (MPI) module. +# +# The Message Passing Interface (MPI) is a library used to write +# high-performance parallel applications that use message passing, and +# is typically deployed on a cluster. MPI is a standard interface +# (defined by the MPI forum) for which many implementations are +# available. All of these implementations have somewhat different +# compilation approaches (different include paths, libraries to link +# against, etc.), and this module tries to smooth out those differences. # # This module will set the following variables: # MPI_FOUND TRUE if we have found MPI # MPI_COMPILE_FLAGS Compilation flags for MPI programs -# MPI_INCLUDE_PATH Include path for MPI header +# MPI_INCLUDE_PATH Include path(s) for MPI header # MPI_LINK_FLAGS Linking flags for MPI programs -# MPI_LIBRARIES Libraries to link MPI programs against -# MPI_LIBRARY Deprecated; first MPI library to link against -# MPI_EXTRA_LIBRARY Deprecated; second MPI library to link against +# MPI_LIBRARY First MPI library to link against (cached) +# MPI_EXTRA_LIBRARY Extra MPI libraries to link against (cached) +# MPI_LIBRARIES All libraries to link MPI programs against # MPIEXEC Executable for running MPI programs +# MPIEXEC_NUMPROC_FLAG Flag to pass to MPIEXEC before giving it the +# number of processors to run on +# MPIEXEC_PREFLAGS Flags to pass to MPIEXEC directly before the +# executable to run. +# MPIEXEC_POSTFLAGS Flags to pass to MPIEXEC after all other flags. # # This module will attempt to auto-detect these settings, first by -# looking for a C++ MPI driver (e.g., mpic++, mpiCC, or mpicxx; set by -# MPICXX) and later by checking common MPI paths and library names. +# looking for a MPI compiler, which many MPI implementations provide +# as a pass-through to the native compiler to simplify the compilation +# of MPI programs. The MPI compiler is stored in the cache variable +# MPI_COMPILER, and will attempt to look for commonly-named drivers +# mpic++, mpicxx, mpiCC, or mpicc. If the compiler driver is found and +# recognized, it will be used to set all of the module variables. To +# skip this auto-detection, set MPI_LIBRARY and MPI_INCLUDE_PATH in +# the CMake cache. +# +# If no compiler driver is found or the compiler driver is not +# recognized, this module will then search for common include paths +# and library names to try to detect MPI. +# +# If CMake initially finds a different MPI than was intended, and you +# want to use the MPI compiler auto-detection for a different MPI +# implementation, set MPI_COMPILER to the MPI compiler driver you want +# to use (e.g., mpicxx) and then set MPI_LIBRARY to the string +# MPI_LIBRARY-NOTFOUND. When you re-configure, auto-detection of MPI +# will run again with the newly-specified MPI_COMPILER. +# +# When using MPIEXEC to execute MPI applications, you should typically +# use all of the MPIEXEC flags as follows: +# ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} PROCS ${MPIEXEC_PREFLAGS} EXECUTABLE +# ${MPIEXEC_POSTFLAGS} ARGS +# where PROCS is the number of processors on which to execute the program, +# EXECUTABLE is the MPI program, and ARGS are the arguments to pass to the +# MPI program. # Try to find the MPI driver program -find_program(MPICXX - NAMES mpic++ mpicxx mpiCC - DOC "MPI C++ compiler. Used only to detect MPI compilation flags.") -mark_as_advanced(MPICXX) +find_program(MPI_COMPILER + NAMES mpic++ mpicxx mpiCC mpicc + DOC "MPI compiler. Used only to detect MPI compilation flags.") +mark_as_advanced(MPI_COMPILER) find_program(MPIEXEC - NAMES mpiexec mpirun + NAMES mpiexec mpirun lamexec DOC "Executable for running MPI programs.") -mark_as_advanced(MPIEXEC) -if (NOT OLD_MPICXX STREQUAL MPICXX) - set(MPI_FORCE_RECONFIGURE TRUE) - set(OLD_MPICXX ${MPICXX} CACHE INTERNAL "Previous value of MPICXX" FORCE) -endif (NOT OLD_MPICXX STREQUAL MPICXX) - -if (NOT MPICXX) - # If there is no MPI C++ compiler, we force ourselves to configure - # MPI the old way. - set(MPI_FORCE_RECONFIGURE TRUE) -endif (NOT MPICXX) +set(MPIEXEC_NUMPROC_FLAG "-np" CACHE STRING "Flag used by MPI to specify the number of processes for MPIEXEC; the next option will be the number of processes.") +set(MPIEXEC_PREFLAGS "" CACHE STRING "These flags will be directly before the executable that is being run by MPIEXEC.") +set(MPIEXEC_POSTFLAGS "" CACHE STRING "These flags will come after all flags given to MPIEXEC.") +set(MPIEXEC_MAX_NUMPROCS "2" CACHE STRING "Maximum number of processors available to run MPI applications.") +mark_as_advanced(MPIEXEC MPIEXEC_NUMPROC_FLAG MPIEXEC_PREFLAGS + MPIEXEC_POSTFLAGS MPIEXEC_MAX_NUMPROCS) -if (MPICXX) +if (MPI_INCLUDE_PATH AND MPI_LIBRARY) + # Do nothing: we already have MPI_INCLUDE_PATH and MPI_LIBRARY in + # the cache, and we don't want to override those settings. +elseif (MPI_COMPILER) # Check whether the -showme:compile option works. This indicates # that we have either Open MPI or a newer version of LAM-MPI, and # implies that -showme:link will also work. - exec_program(${MPICXX} + exec_program(${MPI_COMPILER} ARGS -showme:compile OUTPUT_VARIABLE MPI_COMPILE_CMDLINE - RETURN_VALUE MPICXX_RETURN) + RETURN_VALUE MPI_COMPILER_RETURN) - if (MPICXX_RETURN EQUAL 0) + if (MPI_COMPILER_RETURN EQUAL 0) # If we appear to have -showme:compile, then we should also have # -showme:link. Try it. - exec_program(${MPICXX} + exec_program(${MPI_COMPILER} ARGS -showme:link OUTPUT_VARIABLE MPI_LINK_CMDLINE - RETURN_VALUE MPICXX_RETURN) - endif (MPICXX_RETURN EQUAL 0) + RETURN_VALUE MPI_COMPILER_RETURN) + endif (MPI_COMPILER_RETURN EQUAL 0) - if (MPICXX_RETURN EQUAL 0) + if (MPI_COMPILER_RETURN EQUAL 0) # Do nothing: we have our command lines now - else (MPICXX_RETURN EQUAL 0) + else (MPI_COMPILER_RETURN EQUAL 0) # Older versions of LAM-MPI have "-showme". Try it. - exec_program(${MPICXX} + exec_program(${MPI_COMPILER} ARGS -showme OUTPUT_VARIABLE MPI_COMPILE_CMDLINE - RETURN_VALUE MPICXX_RETURN) - endif (MPICXX_RETURN EQUAL 0) + RETURN_VALUE MPI_COMPILER_RETURN) + endif (MPI_COMPILER_RETURN EQUAL 0) - if (MPICXX_RETURN EQUAL 0) + if (MPI_COMPILER_RETURN EQUAL 0) # Do nothing: we have our command lines now - else (MPICXX_RETURN EQUAL 0) + else (MPI_COMPILER_RETURN EQUAL 0) # MPICH uses "-show". Try it. - exec_program(${MPICXX} + exec_program(${MPI_COMPILER} ARGS -show OUTPUT_VARIABLE MPI_COMPILE_CMDLINE - RETURN_VALUE MPICXX_RETURN) - endif (MPICXX_RETURN EQUAL 0) + RETURN_VALUE MPI_COMPILER_RETURN) + endif (MPI_COMPILER_RETURN EQUAL 0) - if (MPICXX_RETURN EQUAL 0) + if (MPI_COMPILER_RETURN EQUAL 0) # We have our command lines, but we might need to copy # MPI_COMPILE_CMDLINE into MPI_LINK_CMDLINE, if the underlying if (NOT MPI_LINK_CMDLINE) SET(MPI_LINK_CMDLINE ${MPI_COMPILE_CMDLINE}) endif (NOT MPI_LINK_CMDLINE) - else (MPICXX_RETURN EQUAL 0) - message(STATUS "Unable to determine MPI from MPI driver ${MPICXX}") - endif (MPICXX_RETURN EQUAL 0) -endif (MPICXX) + else (MPI_COMPILER_RETURN EQUAL 0) + message(STATUS "Unable to determine MPI from MPI driver ${MPI_COMPILER}") + endif (MPI_COMPILER_RETURN EQUAL 0) +endif (MPI_INCLUDE_PATH AND MPI_LIBRARY) -if (NOT MPI_FORCE_RECONFIGURE) - # We don't actually have to reconfigure anything +if (MPI_INCLUDE_PATH AND MPI_LIBRARY) + # Do nothing: we already have MPI_INCLUDE_PATH and MPI_LIBRARY in + # the cache, and we don't want to override those settings. elseif (MPI_COMPILE_CMDLINE) # Extract compile flags from the compile command line. - string(REGEX MATCHALL "-D([^\" ]+|\"[^\"]+\")" MPI_ALL_COMPILE_FLAGS ${MPI_COMPILE_CMDLINE}) + string(REGEX MATCHALL "-D([^\" ]+|\"[^\"]+\")" MPI_ALL_COMPILE_FLAGS "${MPI_COMPILE_CMDLINE}") set(MPI_COMPILE_FLAGS_WORK) foreach(FLAG ${MPI_ALL_COMPILE_FLAGS}) if (MPI_COMPILE_FLAGS_WORK) @@ -100,17 +137,25 @@ elseif (MPI_COMPILE_CMDLINE) endforeach(FLAG) # Extract include paths from compile command line - string(REGEX MATCH "-I([^\" ]+|\"[^\"]+\")" MPI_INCLUDE_PATH ${MPI_COMPILE_CMDLINE}) - string(REGEX REPLACE "^-I" "" MPI_INCLUDE_PATH ${MPI_INCLUDE_PATH}) - string(REGEX REPLACE "//" "/" MPI_INCLUDE_PATH ${MPI_INCLUDE_PATH}) - + string(REGEX MATCHALL "-I([^\" ]+|\"[^\"]+\")" MPI_ALL_INCLUDE_PATHS "${MPI_COMPILE_CMDLINE}") + set(MPI_INCLUDE_PATH_WORK) + foreach(IPATH ${MPI_ALL_INCLUDE_PATHS}) + string(REGEX REPLACE "^-I" "" IPATH ${IPATH}) + string(REGEX REPLACE "//" "/" IPATH ${IPATH}) + list(APPEND MPI_INCLUDE_PATH_WORK ${IPATH}) + endforeach(IPATH) + # Extract linker paths from the link command line - string(REGEX MATCH "-L([^\" ]+|\"[^\"]+\")" MPI_LINK_PATH ${MPI_LINK_CMDLINE}) - string(REGEX REPLACE "^-L" "" MPI_LINK_PATH ${MPI_LINK_PATH}) - string(REGEX REPLACE "//" "/" MPI_LINK_PATH ${MPI_LINK_PATH}) + string(REGEX MATCHALL "-L([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_PATHS "${MPI_LINK_CMDLINE}") + set(MPI_LINK_PATH) + foreach(LPATH ${MPI_ALL_LINK_PATHS}) + string(REGEX REPLACE "^-L" "" LPATH ${LPATH}) + string(REGEX REPLACE "//" "/" LPATH ${LPATH}) + list(APPEND MPI_LINK_PATH ${LPATH}) + endforeach(LPATH) # Extract linker flags from the link command line - string(REGEX MATCHALL "-Wl,([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS ${MPI_LINK_CMDLINE}) + string(REGEX MATCHALL "-Wl,([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE}") set(MPI_LINK_FLAGS_WORK) foreach(FLAG ${MPI_ALL_LINK_FLAGS}) if (MPI_LINK_FLAGS_WORK) @@ -122,7 +167,7 @@ elseif (MPI_COMPILE_CMDLINE) # Extract the set of libraries to link against from the link command # line - string(REGEX MATCHALL "-l([^\" ]+|\"[^\"]+\")" MPI_LIBNAMES ${MPI_LINK_CMDLINE}) + string(REGEX MATCHALL "-l([^\" ]+|\"[^\"]+\")" MPI_LIBNAMES "${MPI_LINK_CMDLINE}") # Determine full path names for all of the libraries that one needs # to link against in an MPI program @@ -143,31 +188,23 @@ elseif (MPI_COMPILE_CMDLINE) # MPI_EXTRA_LIBRARY. list(LENGTH MPI_LIBRARIES MPI_NUMLIBS) if (MPI_NUMLIBS GREATER 0) - list(GET MPI_LIBRARIES 0 MPI_LIBRARY) + list(GET MPI_LIBRARIES 0 MPI_LIBRARY_WORK) + set(MPI_LIBRARY ${MPI_LIBRARY_WORK} CACHE FILEPATH "MPI library to link against" FORCE) else (MPI_NUMLIBS GREATER 0) - set(MPI_LIBRARY "MPI_LIBRARY-NOTFOUND") + set(MPI_LIBRARY "MPI_LIBRARY-NOTFOUND" CACHE STRING "MPI library to link against" FORCE) endif (MPI_NUMLIBS GREATER 0) if (MPI_NUMLIBS GREATER 1) - set(MPI_EXTRA_LIBRARY ${MPI_LIBRARIES}) - list(REMOVE_AT MPI_EXTRA_LIBRARY 0) + set(MPI_EXTRA_LIBRARY_WORK ${MPI_LIBRARIES}) + list(REMOVE_AT MPI_EXTRA_LIBRARY_WORK 0) + set(MPI_EXTRA_LIBRARY ${MPI_EXTRA_LIBRARY_WORK} CACHE STRING "Extra MPI libraries to link against" FORCE) else (MPI_NUMLIBS GREATER 1) - set(MPI_EXTRA_LIBRARY "MPI_EXTRA_LIBRARY-NOTFOUND") + set(MPI_EXTRA_LIBRARY "MPI_EXTRA_LIBRARY-NOTFOUND" CACHE STRING "Extra MPI libraries to link against" FORCE) endif (MPI_NUMLIBS GREATER 1) # Set up all of the appropriate cache entries - set(MPI_FOUND TRUE CACHE INTERNAL "Whether MPI was found" FORCE) - - if (NOT MPI_FORCE_RECONFIGURE) - set(MPI_COMPILE_FLAGS ${MPI_COMPILE_FLAGS_WORK} CACHE STRING "MPI compilation flags") - set(MPI_INCLUDE_PATH ${MPI_INCLUDE_PATH} CACHE STRING "MPI include path") - set(MPI_LINK_FLAGS ${MPI_LINK_FLAGS_WORK} CACHE STRING "MPI linking flags") - set(MPI_LIBRARIES ${MPI_LIBRARIES} CACHE STRING "MPI libraries to link against, separated by semicolons") - else (NOT MPI_FORCE_RECONFIGURE) - set(MPI_COMPILE_FLAGS ${MPI_COMPILE_FLAGS_WORK} CACHE STRING "MPI compilation flags" FORCE) - set(MPI_INCLUDE_PATH ${MPI_INCLUDE_PATH} CACHE STRING "MPI include path" FORCE) - set(MPI_LINK_FLAGS ${MPI_LINK_FLAGS_WORK} CACHE STRING "MPI linking flags" FORCE) - set(MPI_LIBRARIES ${MPI_LIBRARIES} CACHE STRING "MPI libraries to link against, separated by semicolons" FORCE) - endif (NOT MPI_FORCE_RECONFIGURE) + set(MPI_COMPILE_FLAGS ${MPI_COMPILE_FLAGS_WORK} CACHE STRING "MPI compilation flags" FORCE) + set(MPI_INCLUDE_PATH ${MPI_INCLUDE_PATH_WORK} CACHE STRING "MPI include path" FORCE) + set(MPI_LINK_FLAGS ${MPI_LINK_FLAGS_WORK} CACHE STRING "MPI linking flags" FORCE) else (MPI_COMPILE_CMDLINE) find_path(MPI_INCLUDE_PATH mpi.h /usr/local/include @@ -176,16 +213,16 @@ else (MPI_COMPILE_CMDLINE) /usr/local/mpi/include "C:/Program Files/MPICH/SDK/Include" "$ENV{SystemDrive}/Program Files/MPICH2/include" - "C:/Program Files/Microsoft Compute Cluster Pack/Include" + "$ENV{SystemDrive}/Program Files/Microsoft Compute Cluster Pack/Include" ) - # TODO: How do we know whether we're building 32-bit vs. 64-bit? + # TODO: How do we know whether we're building 32-bit vs. 64-bit for MS-MPI? find_library(MPI_LIBRARY NAMES mpi mpich PATHS /usr/lib /usr/local/lib /usr/local/mpi/lib "C:/Program Files/MPICH/SDK/Lib" "$ENV{SystemDrive}/Program Files/MPICH/SDK/Lib" - "C:/Program Files/Microsoft Compute Cluster Pack/Lib/i386" + "$ENV{SystemDrive}/Program Files/Microsoft Compute Cluster Pack/Lib/i386" ) find_library(MPI_LIBRARY NAMES mpich2 @@ -196,24 +233,11 @@ else (MPI_COMPILE_CMDLINE) NAMES mpi++ PATHS /usr/lib /usr/local/lib /usr/local/mpi/lib "C:/Program Files/MPICH/SDK/Lib" - "C:/Program Files/Microsoft Compute Cluster Pack/Lib/i386" - DOC "If a second MPI library is necessary, specify it here.") + DOC "Extra MPI libraries to link against.") set(MPI_COMPILE_FLAGS "" CACHE STRING "MPI compilation flags") set(MPI_LINK_FLAGS "" CACHE STRING "MPI linking flags") - - if (MPI_EXTRA_LIBRARY) - set(MPI_LIBRARIES "${MPI_LIBRARY};${MPI_EXTRA_LIBRARY}" CACHE STRING "MPI libraries to link against, separated by semicolons") - else (MPI_EXTRA_LIBRARY) - set(MPI_LIBRARIES ${MPI_LIBRARY} CACHE STRING "MPI libraries to link against, separated by semicolons") - endif (MPI_EXTRA_LIBRARY) - - if (MPI_LIBRARY) - set(MPI_FOUND TRUE CACHE INTERNAL "Whether MPI was found" FORCE) - else (MPI_LIBRARY) - set(MPI_FOUND FALSE CACHE INTERNAL "Whether MPI was found" FORCE) - endif (MPI_LIBRARY) -endif (NOT MPI_FORCE_RECONFIGURE) +endif (MPI_INCLUDE_PATH AND MPI_LIBRARY) # on BlueGene/L the MPI lib is named libmpich.rts.a, there also these additional libs are required if("${MPI_LIBRARY}" MATCHES "mpich.rts") @@ -221,10 +245,22 @@ if("${MPI_LIBRARY}" MATCHES "mpich.rts") set(MPI_LIBRARY ${MPI_LIBRARY} msglayer.rts devices.rts rts.rts devices.rts) endif("${MPI_LIBRARY}" MATCHES "mpich.rts") -set(MPI_LIBRARY ${MPI_LIBRARY} CACHE INTERNAL "MPI library to link against. Deprecated: use MPI_LIBRARIES instead") -set(MPI_EXTRA_LIBRARY ${MPI_EXTRA_LIBRARY} CACHE INTERNAL "Second MPI library to link against. Deprecated: use MPI_LIBRARIES instead") +# Set up extra variables to conform to +if (MPI_EXTRA_LIBRARY) + set(MPI_LIBRARIES ${MPI_LIBRARY} ${MPI_EXTRA_LIBRARY}) +else (MPI_EXTRA_LIBRARY) + set(MPI_LIBRARIES ${MPI_LIBRARY}) +endif (MPI_EXTRA_LIBRARY) + +if (MPI_INCLUDE_PATH AND MPI_LIBRARY) + set(MPI_FOUND TRUE) +else (MPI_INCLUDE_PATH AND MPI_LIBRARY) + set(MPI_FOUND FALSE) +endif (MPI_INCLUDE_PATH AND MPI_LIBRARY) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments find_package_handle_standard_args(MPI DEFAULT_MSG MPI_LIBRARY MPI_INCLUDE_PATH) -mark_as_advanced(MPI_INCLUDE_PATH MPI_COMPILE_FLAGS MPI_LINK_FLAGS MPI_LIBRARIES) + +mark_as_advanced(MPI_INCLUDE_PATH MPI_COMPILE_FLAGS MPI_LINK_FLAGS MPI_LIBRARY + MPI_EXTRA_LIBRARY) diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index 5005e962cf..e232525a2b 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -169,6 +169,9 @@ cmComputeLinkDepends // Enable debug mode if requested. this->DebugMode = this->Makefile->IsOn("CMAKE_LINK_DEPENDS_DEBUG_MODE"); + + // Assume no compatibility until set. + this->OldLinkDirMode = false; } //---------------------------------------------------------------------------- @@ -183,6 +186,12 @@ cmComputeLinkDepends::~cmComputeLinkDepends() } //---------------------------------------------------------------------------- +void cmComputeLinkDepends::SetOldLinkDirMode(bool b) +{ + this->OldLinkDirMode = b; +} + +//---------------------------------------------------------------------------- std::vector<cmComputeLinkDepends::LinkEntry> const& cmComputeLinkDepends::Compute() { @@ -460,6 +469,10 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index, { actual_libs.push_back(*di); } + else if(this->OldLinkDirMode) + { + this->CheckWrongConfigItem(*di); + } // Reset the link type until another explicit type is given. llt = cmTarget::GENERAL; @@ -492,6 +505,10 @@ cmComputeLinkDepends::AddTargetLinkEntries(int depender_index, { actual_libs.push_back(li->first); } + else if(this->OldLinkDirMode) + { + this->CheckWrongConfigItem(li->first); + } } // Add these entries. @@ -809,3 +826,23 @@ void cmComputeLinkDepends::DisplayFinalEntries() } fprintf(stderr, "\n"); } + +//---------------------------------------------------------------------------- +void cmComputeLinkDepends::CheckWrongConfigItem(std::string const& item) +{ + if(!this->OldLinkDirMode) + { + return; + } + + // For CMake 2.4 bug-compatibility we need to consider the output + // directories of targets linked in another configuration as link + // directories. + if(cmTarget* tgt = this->Makefile->FindTargetToUse(item.c_str())) + { + if(!tgt->IsImported()) + { + this->OldWrongConfigItems.insert(tgt); + } + } +} diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index de85fa0ff2..49e8d6b4b6 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -54,6 +54,10 @@ public: typedef std::vector<LinkEntry> EntryVector; EntryVector const& Compute(); + void SetOldLinkDirMode(bool b); + std::set<cmTarget*> const& GetOldWrongConfigItems() const + { return this->OldWrongConfigItems; } + private: // Context information. @@ -128,6 +132,11 @@ private: void VisitComponent(cmComputeComponentGraph const& ccg, unsigned int i); void EmitComponent(NodeList const& nl); void DisplayFinalEntries(); + + // Compatibility help. + bool OldLinkDirMode; + void CheckWrongConfigItem(std::string const& item); + std::set<cmTarget*> OldWrongConfigItems; }; #endif diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 82db1d3e25..fc9bf47438 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -510,6 +510,7 @@ bool cmComputeLinkInformation::Compute() // Compute the ordered link line items. cmComputeLinkDepends cld(this->Target, this->Config); + cld.SetOldLinkDirMode(this->OldLinkDirMode); cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute(); // Add the link line items. @@ -539,6 +540,25 @@ bool cmComputeLinkInformation::Compute() this->SetCurrentLinkType(this->StartLinkType); } + // Finish listing compatibility paths. + if(this->OldLinkDirMode) + { + // For CMake 2.4 bug-compatibility we need to consider the output + // directories of targets linked in another configuration as link + // directories. + std::set<cmTarget*> const& wrongItems = cld.GetOldWrongConfigItems(); + for(std::set<cmTarget*>::const_iterator i = wrongItems.begin(); + i != wrongItems.end(); ++i) + { + cmTarget* tgt = *i; + bool implib = + (this->UseImportLibrary && + (tgt->GetType() == cmTarget::SHARED_LIBRARY)); + std::string lib = tgt->GetFullPath(this->Config , implib, true); + this->OldLinkDirItems.push_back(lib); + } + } + // Finish setting up linker search directories. if(!this->FinishLinkerSearchDirectories()) { diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 914b044778..1e0a8d92cb 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -79,12 +79,14 @@ bool cmExportFileGenerator::GenerateImportFile() } std::ostream& os = *foutPtr; - // Start with the import file header. + // Isolate the file policy level. + // We use 2.6 here instead of the current version because newer + // versions of CMake should be able to export files imported by 2.6 + // until the import format changes. os << "CMAKE_POLICY(PUSH)\n" - << "CMAKE_POLICY(VERSION " - << cmVersion::GetMajorVersion() << "." - << cmVersion::GetMinorVersion() << "." - << cmVersion::GetPatchVersion() << ")\n"; + << "CMAKE_POLICY(VERSION 2.6)\n"; + + // Start with the import file header. this->GenerateImportHeaderCode(os); // Create all the imported targets. diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 27a4878b94..c7383eafe4 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -171,30 +171,12 @@ bool cmListFile::ParseFile(const char* filename, if (isProblem) { - cmOStringStream msg; - msg << "No cmake_minimum_required command is present. " - << "A line of code such as\n" - << " cmake_minimum_required(VERSION " - << cmVersion::GetMajorVersion() << "." - << cmVersion::GetMinorVersion() - << ")\n" - << "should be added at the top of the file. " - << "The version specified may be lower if you wish to " - << "support older CMake versions for this project. " - << "For more information run " - << "\"cmake --help-policy CMP0000\"."; - switch (mf->GetPolicyStatus(cmPolicies::CMP0000)) - { - case cmPolicies::WARN: - mf->IssueMessage(cmake::AUTHOR_WARNING, msg.str().c_str()); - case cmPolicies::OLD: - // Implicitly set the version for the user. - mf->SetPolicyVersion("2.4"); - break; - default: - mf->IssueMessage(cmake::FATAL_ERROR, msg.str().c_str()); - return false; - } + // Tell the top level cmMakefile to diagnose + // this violation of CMP0000. + mf->SetCheckCMP0000(true); + + // Implicitly set the version for the user. + mf->SetPolicyVersion("2.4"); } } } diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 5d30c5945e..7ee40fc128 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -31,6 +31,8 @@ #include <ctype.h> // for isspace +static bool cmLVS6G_IsFAT(const char* dir); + class cmLocalVisualStudio7GeneratorInternals { public: @@ -661,16 +663,21 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, fout << "\t\t\t\tInterfaceIdentifierFileName=\"$(InputName)_i.c\"\n"; fout << "\t\t\t\tProxyFileName=\"$(InputName)_p.c\"/>\n"; // end of <Tool Name=VCMIDLTool - - // If we are building a version 8 project file, add a flag telling the - // manifest tool to use a workaround for FAT32 file systems, which can cause - // an empty manifest to be embedded into the resulting executable. - // See CMake bug #2617. + + // Check if we need the FAT32 workaround. if ( this->Version >= 8 ) { - fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n" - << "\t\t\t\tUseFAT32Workaround=\"true\"\n" - << "\t\t\t/>\n"; + // Check the filesystem type where the target will be written. + if(cmLVS6G_IsFAT(target.GetDirectory(configName))) + { + // Add a flag telling the manifest tool to use a workaround + // for FAT32 file systems, which can cause an empty manifest + // to be embedded into the resulting executable. See CMake + // bug #2617. + fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCManifestTool\"\n" + << "\t\t\t\tUseFAT32Workaround=\"true\"\n" + << "\t\t\t/>\n"; + } } this->OutputTargetRules(fout, configName, target, libName); @@ -2054,3 +2061,21 @@ GetTargetObjectFileDirectories(cmTarget* target, dir += this->GetGlobalGenerator()->GetCMakeCFGInitDirectory(); dirs.push_back(dir); } + +//---------------------------------------------------------------------------- +#include <windows.h> +static bool cmLVS6G_IsFAT(const char* dir) +{ + if(dir[0] && dir[1] == ':') + { + char volRoot[4] = "_:/"; + volRoot[0] = dir[0]; + char fsName[16]; + if(GetVolumeInformation(volRoot, 0, 0, 0, 0, 0, fsName, 16) && + strstr(fsName, "FAT") != 0) + { + return true; + } + } + return false; +} diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index f09c605e80..135dc287d9 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -146,6 +146,10 @@ void cmMakefile::Initialize() // Enter a policy level for this directory. this->PushPolicy(); + + // By default the check is not done. It is enabled by + // cmListFileCache in the top level if necessary. + this->CheckCMP0000 = false; } unsigned int cmMakefile::GetCacheMajorVersion() @@ -561,19 +565,11 @@ bool cmMakefile::ReadListFile(const char* filename_in, } } - // If this is the directory-level CMakeLists.txt file then enforce - // policy stack depth. + // If this is the directory-level CMakeLists.txt file then perform + // some extra checks. if(this->ListFileStack.size() == 1) { - while(this->PolicyStack.size() > 1) - { - if(endScopeNicely) - { - this->IssueMessage(cmake::FATAL_ERROR, - "cmake_policy PUSH without matching POP"); - } - this->PopPolicy(false); - } + this->EnforceDirectoryLevelRules(endScopeNicely); } this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str()); @@ -585,6 +581,55 @@ bool cmMakefile::ReadListFile(const char* filename_in, return true; } +//---------------------------------------------------------------------------- +void cmMakefile::EnforceDirectoryLevelRules(bool endScopeNicely) +{ + // Enforce policy stack depth. + while(this->PolicyStack.size() > 1) + { + if(endScopeNicely) + { + this->IssueMessage(cmake::FATAL_ERROR, + "cmake_policy PUSH without matching POP"); + } + this->PopPolicy(false); + } + + // Diagnose a violation of CMP0000 if necessary. + if(this->CheckCMP0000) + { + cmOStringStream msg; + msg << "No cmake_minimum_required command is present. " + << "A line of code such as\n" + << " cmake_minimum_required(VERSION " + << cmVersion::GetMajorVersion() << "." + << cmVersion::GetMinorVersion() + << ")\n" + << "should be added at the top of the file. " + << "The version specified may be lower if you wish to " + << "support older CMake versions for this project. " + << "For more information run " + << "\"cmake --help-policy CMP0000\"."; + switch (this->GetPolicyStatus(cmPolicies::CMP0000)) + { + case cmPolicies::WARN: + // Warn because the user did not provide a mimimum required + // version. + this->IssueMessage(cmake::AUTHOR_WARNING, msg.str().c_str()); + case cmPolicies::OLD: + // OLD behavior is to use policy version 2.4 set in + // cmListFileCache. + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + // NEW behavior is to issue an error. + this->IssueMessage(cmake::FATAL_ERROR, msg.str().c_str()); + cmSystemTools::SetFatalErrorOccured(); + return; + } + } +} void cmMakefile::AddCommand(cmCommand* wg) { diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index b91ddb45e7..d8873f4c6b 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -793,6 +793,9 @@ public: void IssueMessage(cmake::MessageType t, std::string const& text) const; + /** Set whether or not to report a CMP0000 violation. */ + void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; } + protected: // add link libraries and directories to the target void AddGlobalLinkInformation(const char* name, cmTarget& target); @@ -904,6 +907,11 @@ private: typedef std::map<cmPolicies::PolicyID, cmPolicies::PolicyStatus> PolicyMap; std::vector<PolicyMap> PolicyStack; + + bool CheckCMP0000; + + // Enforce rules about CMakeLists.txt files. + void EnforceDirectoryLevelRules(bool endScopeNicely); }; diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index b37171b785..b69a7198e5 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -101,7 +101,15 @@ cmPolicies::cmPolicies() "(such as \"2.6\"). " "The command will ensure that at least the given version of CMake is " "running and help newer versions be compatible with the project. " - "See documentation of cmake_minimum_required for details.", + "See documentation of cmake_minimum_required for details.\n" + "Note that the command invocation must appear in the CMakeLists.txt " + "file itself; a call in an included file is not sufficient. " + "However, the cmake_policy command may be called to set policy " + "CMP0000 to OLD or NEW behavior explicitly. " + "The OLD behavior is to silently ignore the missing invocation. " + "The NEW behavior is to issue an error instead of a warning. " + "An included file may set CMP0000 explicitly to affect how this " + "policy is enforced for the main CMakeLists.txt file.", 2,6,0, cmPolicies::WARN ); |