diff options
130 files changed, 1297 insertions, 1813 deletions
diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst index a1e3e22..41265fd 100644 --- a/Help/command/target_link_libraries.rst +++ b/Help/command/target_link_libraries.rst @@ -59,10 +59,11 @@ for <target>: If an <item> is a library in a Mac OX framework, the Headers directory of the framework will also be processed as a "usage requirement". This has the same effect as passing the framework directory as an -include directory. target_link_libraries(<target> +include directory. :: + target_link_libraries(<target> <PRIVATE|PUBLIC|INTERFACE> <lib> ... [<PRIVATE|PUBLIC|INTERFACE> <lib> ... ] ...]) diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 658620f..4fcc90b 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -5,6 +5,26 @@ cmake-policies(7) .. contents:: +Introduction +============ + +Policies in CMake are used to preserve backward compatible behavior +across multiple releases. When a new policy is introduced, newer CMake +versions will begin to warn about the backward compatible behavior. It +is possible to disable the warning by explicitly requesting the OLD, or +backward compatible behavior using the :command:`cmake_policy` command. +It is also possible to request NEW, or non-backward compatible behavior +for a policy, also avoiding the warning. + +The :command:`cmake_minimum_required` command does more than report an +error if a too-old version of CMake is used to build a project. It +also sets all policies introduced in that CMake version or earlier to +NEW behavior. + +The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used +to determine whether to report an error on use of deprecated macros or +functions. + All Policies ============ diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 46190b5..2ee9bcc 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -33,7 +33,7 @@ native tool on their platform. copy_directory, copy_if_different, echo, echo_append, environment, make_directory, md5sum, remove, remove_directory, rename, tar, time, touch, touch_nocreate. In addition, some platform specific commands - are available. On Windows: comspec, delete_regv, write_regv. On + are available. On Windows: delete_regv, write_regv. On UNIX: create_symlink. * ``-L[A][H]``: List non-advanced cached variables. diff --git a/Help/policy/CMP0017.rst b/Help/policy/CMP0017.rst index c93e8b2..f74e6f0 100644 --- a/Help/policy/CMP0017.rst +++ b/Help/policy/CMP0017.rst @@ -11,7 +11,7 @@ the modules belonging to CMake always get those files included which they expect, and against which they were developed and tested. In all other cases, the files found in CMAKE_MODULE_PATH still take precedence over the ones in the CMake module directory. The OLD -behaviour is to always prefer files from CMAKE_MODULE_PATH over files +behavior is to always prefer files from CMAKE_MODULE_PATH over files from the CMake modules directory. This policy was introduced in CMake version 2.8.4. CMake version diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index e591f2c..0d7aa61 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -109,7 +109,11 @@ Id flags: ${testflags} ") # Compile the compiler identification source. - if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([0-9]+)") + if(CMAKE_GENERATOR STREQUAL "Visual Studio 6" AND + lang STREQUAL "Fortran") + set(CMAKE_${lang}_COMPILER_ID_RESULT 1) + set(CMAKE_${lang}_COMPILER_ID_OUTPUT "No Intel Fortran in VS 6") + elseif("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([0-9]+)") set(vs_version ${CMAKE_MATCH_1}) set(id_platform ${CMAKE_VS_PLATFORM_NAME}) set(id_lang "${lang}") diff --git a/Modules/Platform/Windows-MSVC-C.cmake b/Modules/Platform/Windows-MSVC-C.cmake index e81df9f..cbe1586 100644 --- a/Modules/Platform/Windows-MSVC-C.cmake +++ b/Modules/Platform/Windows-MSVC-C.cmake @@ -1,2 +1,5 @@ include(Platform/Windows-MSVC) +if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 18.0) + set(_FS_C " /FS") +endif() __windows_compiler_msvc(C) diff --git a/Modules/Platform/Windows-MSVC-CXX.cmake b/Modules/Platform/Windows-MSVC-CXX.cmake index fdd1dae..0e85005 100644 --- a/Modules/Platform/Windows-MSVC-CXX.cmake +++ b/Modules/Platform/Windows-MSVC-CXX.cmake @@ -1,3 +1,6 @@ include(Platform/Windows-MSVC) set(_COMPILE_CXX " /TP") +if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0) + set(_FS_CXX " /FS") +endif() __windows_compiler_msvc(CXX) diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 8f0add7..e29aaf4 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -241,7 +241,7 @@ macro(__windows_compiler_msvc lang) set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "<CMAKE_LINKER> /lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ") set(CMAKE_${lang}_COMPILE_OBJECT - "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <FLAGS> <DEFINES> /Fo<OBJECT> /Fd<OBJECT_DIR>/ -c <SOURCE>${CMAKE_END_TEMP_FILE}") + "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <FLAGS> <DEFINES> /Fo<OBJECT> /Fd<OBJECT_DIR>/${_FS_${lang}} -c <SOURCE>${CMAKE_END_TEMP_FILE}") set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> > <PREPROCESSED_SOURCE> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <FLAGS> <DEFINES> -E <SOURCE>${CMAKE_END_TEMP_FILE}") set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 288e867..01e4f88 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -361,8 +361,6 @@ if (WIN32) cmVisualStudioSlnParser.cxx cmVisualStudioWCEPlatformParser.h cmVisualStudioWCEPlatformParser.cxx - cmWin32ProcessExecution.cxx - cmWin32ProcessExecution.h ) endif() endif () @@ -538,16 +536,6 @@ endif() add_executable(cmake cmakemain.cxx cmcmd.cxx cmcmd.h) target_link_libraries(cmake CMakeLib) -# Build special executable for running programs on Windows 98. -# Included on any Windows (unconditional packaging required!). -if(WIN32) - if(NOT UNIX) - add_executable(cmw9xcom cmw9xcom.cxx) - target_link_libraries(cmw9xcom CMakeLib) - install(TARGETS cmw9xcom DESTINATION bin) - endif() -endif() - # Build CTest executable add_executable(ctest ctest.cxx) target_link_libraries(ctest CTestLib) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index b5d8520..321066d 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -2,5 +2,5 @@ set(CMake_VERSION_MAJOR 2) set(CMake_VERSION_MINOR 8) set(CMake_VERSION_PATCH 12) -set(CMake_VERSION_TWEAK 20131018) +set(CMake_VERSION_TWEAK 20131022) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 169ae9a..9f8cc14 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -403,11 +403,6 @@ int main (int argc, char *argv[]) } if ( parsed ) { -#ifdef _WIN32 - std::string comspec = "cmw9xcom.exe"; - cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str()); -#endif - const char* projName = mf->GetDefinition("CPACK_PACKAGE_NAME"); cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "Use generator: " << cpackGenerator->GetNameOfClass() << std::endl); diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 0829add..7fd4754 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -208,7 +208,15 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) std::set<cmStdString> emitted; { std::vector<std::string> tlibs; - depender->GetDirectLinkLibraries(0, tlibs, depender); + if (depender->GetType() == cmTarget::INTERFACE_LIBRARY) + { + // For INTERFACE_LIBRARY depend on the interface instead. + depender->GetInterfaceLinkLibraries(0, tlibs, depender); + } + else + { + depender->GetDirectLinkLibraries(0, tlibs, depender); + } // A target should not depend on itself. emitted.insert(depender->GetName()); for(std::vector<std::string>::const_iterator lib = tlibs.begin(); diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index bc4bf18..0ac969b 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -372,8 +372,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) } /* for the TRY_COMPILEs we want to be able to specify the architecture. - So the user can set CMAKE_OSX_ARCHITECTURE to i386;ppc and then set - CMAKE_TRY_COMPILE_OSX_ARCHITECTURE first to i386 and then to ppc to + So the user can set CMAKE_OSX_ARCHITECTURES to i386;ppc and then set + CMAKE_TRY_COMPILE_OSX_ARCHITECTURES first to i386 and then to ppc to have the tests run for each specific architecture. Since cmLocalGenerator doesn't allow building for "the other" architecture only via CMAKE_OSX_ARCHITECTURES. diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx index 9fdb1e8..6c11345 100644 --- a/Source/cmExecProgramCommand.cxx +++ b/Source/cmExecProgramCommand.cxx @@ -12,6 +12,8 @@ #include "cmExecProgramCommand.h" #include "cmSystemTools.h" +#include <cmsys/Process.h> + // cmExecProgramCommand bool cmExecProgramCommand ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) @@ -103,13 +105,13 @@ bool cmExecProgramCommand if(args.size() - count == 2) { cmSystemTools::MakeDirectory(args[1].c_str()); - result = cmSystemTools::RunCommand(command.c_str(), output, retVal, - args[1].c_str(), verbose); + result = cmExecProgramCommand::RunCommand(command.c_str(), output, retVal, + args[1].c_str(), verbose); } else { - result = cmSystemTools::RunCommand(command.c_str(), output, - retVal, 0, verbose); + result = cmExecProgramCommand::RunCommand(command.c_str(), output, + retVal, 0, verbose); } if(!result) { @@ -143,3 +145,189 @@ bool cmExecProgramCommand return true; } +bool cmExecProgramCommand::RunCommand(const char* command, + std::string& output, + int &retVal, + const char* dir, + bool verbose) +{ + if(cmSystemTools::GetRunCommandOutput()) + { + verbose = false; + } + +#if defined(WIN32) && !defined(__CYGWIN__) + // if the command does not start with a quote, then + // try to find the program, and if the program can not be + // found use system to run the command as it must be a built in + // shell command like echo or dir + int count = 0; + std::string shortCmd; + if(command[0] == '\"') + { + // count the number of quotes + for(const char* s = command; *s != 0; ++s) + { + if(*s == '\"') + { + count++; + if(count > 2) + { + break; + } + } + } + // if there are more than two double quotes use + // GetShortPathName, the cmd.exe program in windows which + // is used by system fails to execute if there are more than + // one set of quotes in the arguments + if(count > 2) + { + cmsys::RegularExpression quoted("^\"([^\"]*)\"[ \t](.*)"); + if(quoted.find(command)) + { + std::string cmd = quoted.match(1); + std::string args = quoted.match(2); + if(! cmSystemTools::FileExists(cmd.c_str()) ) + { + shortCmd = cmd; + } + else if(!cmSystemTools::GetShortPath(cmd.c_str(), shortCmd)) + { + cmSystemTools::Error("GetShortPath failed for " , cmd.c_str()); + return false; + } + shortCmd += " "; + shortCmd += args; + + command = shortCmd.c_str(); + } + else + { + cmSystemTools::Error("Could not parse command line with quotes ", + command); + } + } + } +#endif + + // Allocate a process instance. + cmsysProcess* cp = cmsysProcess_New(); + if(!cp) + { + cmSystemTools::Error("Error allocating process instance."); + return false; + } + +#if defined(WIN32) && !defined(__CYGWIN__) + if(dir) + { + cmsysProcess_SetWorkingDirectory(cp, dir); + } + if(cmSystemTools::GetRunCommandHideConsole()) + { + cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1); + } + cmsysProcess_SetOption(cp, cmsysProcess_Option_Verbatim, 1); + const char* cmd[] = {command, 0}; + cmsysProcess_SetCommand(cp, cmd); +#else + std::string commandInDir; + if(dir) + { + commandInDir = "cd \""; + commandInDir += dir; + commandInDir += "\" && "; + commandInDir += command; + } + else + { + commandInDir = command; + } +#ifndef __VMS + commandInDir += " 2>&1"; +#endif + command = commandInDir.c_str(); + if(verbose) + { + cmSystemTools::Stdout("running "); + cmSystemTools::Stdout(command); + cmSystemTools::Stdout("\n"); + } + fflush(stdout); + fflush(stderr); + const char* cmd[] = {"/bin/sh", "-c", command, 0}; + cmsysProcess_SetCommand(cp, cmd); +#endif + + cmsysProcess_Execute(cp); + + // Read the process output. + int length; + char* data; + int p; + while((p = cmsysProcess_WaitForData(cp, &data, &length, 0), p)) + { + if(p == cmsysProcess_Pipe_STDOUT || p == cmsysProcess_Pipe_STDERR) + { + if(verbose) + { + cmSystemTools::Stdout(data, length); + } + output.append(data, length); + } + } + + // All output has been read. Wait for the process to exit. + cmsysProcess_WaitForExit(cp, 0); + + // Check the result of running the process. + std::string msg; + switch(cmsysProcess_GetState(cp)) + { + case cmsysProcess_State_Exited: + retVal = cmsysProcess_GetExitValue(cp); + break; + case cmsysProcess_State_Exception: + retVal = -1; + msg += "\nProcess terminated due to: "; + msg += cmsysProcess_GetExceptionString(cp); + break; + case cmsysProcess_State_Error: + retVal = -1; + msg += "\nProcess failed because: "; + msg += cmsysProcess_GetErrorString(cp); + break; + case cmsysProcess_State_Expired: + retVal = -1; + msg += "\nProcess terminated due to timeout."; + break; + } + if(!msg.empty()) + { +#if defined(WIN32) && !defined(__CYGWIN__) + // Old Windows process execution printed this info. + msg += "\n\nfor command: "; + msg += command; + if(dir) + { + msg += "\nin dir: "; + msg += dir; + } + msg += "\n"; + if(verbose) + { + cmSystemTools::Stdout(msg.c_str()); + } + output += msg; +#else + // Old UNIX process execution only put message in output. + output += msg; +#endif + } + + // Delete the process instance. + cmsysProcess_Delete(cp); + + return true; +} diff --git a/Source/cmExecProgramCommand.h b/Source/cmExecProgramCommand.h index 4892dd8..6d28cdc 100644 --- a/Source/cmExecProgramCommand.h +++ b/Source/cmExecProgramCommand.h @@ -57,6 +57,10 @@ public: } cmTypeMacro(cmExecProgramCommand, cmCommand); +private: + static bool RunCommand(const char* command, std::string& output, + int &retVal, const char* directory = 0, + bool verbose = true); }; #endif diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index bd3d669..a2dd903 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -1132,7 +1132,7 @@ cmExtraEclipseCDT4Generator::GetEclipsePath(const std::string& path) #if defined(__CYGWIN__) std::string cmd = "cygpath -m " + path; std::string out; - if (!cmSystemTools::RunCommand(cmd.c_str(), out, 0, false)) + if (!cmSystemTools::RunSingleCommand(cmd.c_str(), &out)) { return path; } diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 7ab107f..ce95c08 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -435,6 +435,7 @@ cmGlobalUnixMakefileGenerator3 (l->second.GetType() == cmTarget::SHARED_LIBRARY) || (l->second.GetType() == cmTarget::MODULE_LIBRARY) || (l->second.GetType() == cmTarget::OBJECT_LIBRARY) || + (l->second.GetType() == cmTarget::INTERFACE_LIBRARY) || (l->second.GetType() == cmTarget::UTILITY)) { // Add this to the list of depends rules in this directory. @@ -612,6 +613,7 @@ cmGlobalUnixMakefileGenerator3 (t->second.GetType() == cmTarget::SHARED_LIBRARY) || (t->second.GetType() == cmTarget::MODULE_LIBRARY) || (t->second.GetType() == cmTarget::OBJECT_LIBRARY) || + (t->second.GetType() == cmTarget::INTERFACE_LIBRARY) || (t->second.GetType() == cmTarget::UTILITY))) { // Add a rule to build the target by name. @@ -633,6 +635,10 @@ cmGlobalUnixMakefileGenerator3 t->second.GetName(), depends, commands, true); + if (t->second.GetType() == cmTarget::INTERFACE_LIBRARY) + { + continue; + } // Add a fast rule to build the target std::string localName = lg->GetRelativeTargetDirectory(t->second); std::string makefileName; @@ -699,6 +705,7 @@ cmGlobalUnixMakefileGenerator3 || (t->second.GetType() == cmTarget::SHARED_LIBRARY) || (t->second.GetType() == cmTarget::MODULE_LIBRARY) || (t->second.GetType() == cmTarget::OBJECT_LIBRARY) + || (t->second.GetType() == cmTarget::INTERFACE_LIBRARY) || (t->second.GetType() == cmTarget::UTILITY))) { std::string makefileName; @@ -715,53 +722,64 @@ cmGlobalUnixMakefileGenerator3 << localName << "\n\n"; commands.clear(); - makeTargetName = localName; - makeTargetName += "/depend"; - commands.push_back(lg->GetRecursiveMakeCall - (makefileName.c_str(),makeTargetName.c_str())); - // add requires if we need it for this generator - if (needRequiresStep) + if(t->second.GetType() != cmTarget::INTERFACE_LIBRARY) { makeTargetName = localName; - makeTargetName += "/requires"; + makeTargetName += "/depend"; commands.push_back(lg->GetRecursiveMakeCall - (makefileName.c_str(),makeTargetName.c_str())); - } - makeTargetName = localName; - makeTargetName += "/build"; - commands.push_back(lg->GetRecursiveMakeCall (makefileName.c_str(),makeTargetName.c_str())); - // Write the rule. - localName += "/all"; - depends.clear(); + // add requires if we need it for this generator + if (needRequiresStep) + { + makeTargetName = localName; + makeTargetName += "/requires"; + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(),makeTargetName.c_str())); + } + makeTargetName = localName; + makeTargetName += "/build"; + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(),makeTargetName.c_str())); - std::string progressDir = - lg->GetMakefile()->GetHomeOutputDirectory(); - progressDir += cmake::GetCMakeFilesDirectory(); - { - cmOStringStream progCmd; - progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; - // all target counts - progCmd << lg->Convert(progressDir.c_str(), - cmLocalGenerator::FULL, - cmLocalGenerator::SHELL); - progCmd << " "; - std::vector<unsigned long>& progFiles = - this->ProgressMap[&t->second].Marks; - for (std::vector<unsigned long>::iterator i = progFiles.begin(); - i != progFiles.end(); ++i) + // Write the rule. + localName += "/all"; + depends.clear(); + + std::string progressDir = + lg->GetMakefile()->GetHomeOutputDirectory(); + progressDir += cmake::GetCMakeFilesDirectory(); { - progCmd << " " << *i; + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; + // all target counts + progCmd << lg->Convert(progressDir.c_str(), + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + progCmd << " "; + std::vector<unsigned long>& progFiles = + this->ProgressMap[&t->second].Marks; + for (std::vector<unsigned long>::iterator i = progFiles.begin(); + i != progFiles.end(); ++i) + { + progCmd << " " << *i; + } + commands.push_back(progCmd.str()); } - commands.push_back(progCmd.str()); + progressDir = "Built target "; + progressDir += t->first; + lg->AppendEcho(commands,progressDir.c_str()); + } + else + { + depends.clear(); } - progressDir = "Built target "; - progressDir += t->first; - lg->AppendEcho(commands,progressDir.c_str()); - this->AppendGlobalTargetDepends(depends,t->second); + if(depends.empty() && this->EmptyRuleHackDepends != "") + { + depends.push_back(this->EmptyRuleHackDepends); + } lg->WriteMakeRule(ruleFileStream, "All Build rule for target.", localName.c_str(), depends, commands, true); @@ -777,7 +795,7 @@ cmGlobalUnixMakefileGenerator3 // Write the rule. commands.clear(); - progressDir = lg->GetMakefile()->GetHomeOutputDirectory(); + std::string progressDir = lg->GetMakefile()->GetHomeOutputDirectory(); progressDir += cmake::GetCMakeFilesDirectory(); { diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx index 5b93171..e8ee33f 100644 --- a/Source/cmIncludeCommand.cxx +++ b/Source/cmIncludeCommand.cxx @@ -19,7 +19,7 @@ bool cmIncludeCommand if (args.size()< 1 || args.size() > 4) { this->SetError("called with wrong number of arguments. " - "Include only takes one file."); + "include() only takes one file."); return false; } bool optional = false; diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 898f379..7461d37 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -29,14 +29,14 @@ struct cmListFileParser ~cmListFileParser(); bool ParseFile(); bool ParseFunction(const char* name, long line); - void AddArgument(cmListFileLexer_Token* token, + bool AddArgument(cmListFileLexer_Token* token, cmListFileArgument::Delimiter delim); cmListFile* ListFile; cmMakefile* Makefile; const char* FileName; cmListFileLexer* Lexer; cmListFileFunction Function; - enum { SeparationOkay, SeparationWarning } Separation; + enum { SeparationOkay, SeparationWarning, SeparationError} Separation; }; //---------------------------------------------------------------------------- @@ -57,13 +57,26 @@ cmListFileParser::~cmListFileParser() bool cmListFileParser::ParseFile() { // Open the file. - if(!cmListFileLexer_SetFileName(this->Lexer, this->FileName)) + cmListFileLexer_BOM bom; + if(!cmListFileLexer_SetFileName(this->Lexer, this->FileName, &bom)) { cmSystemTools::Error("cmListFileCache: error can not open file ", this->FileName); return false; } + // Verify the Byte-Order-Mark, if any. + if(bom != cmListFileLexer_BOM_None && + bom != cmListFileLexer_BOM_UTF8) + { + cmListFileLexer_SetFileName(this->Lexer, 0, 0); + cmOStringStream m; + m << "File\n " << this->FileName << "\n" + << "starts with a Byte-Order-Mark that is not UTF-8."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, m.str()); + return false; + } + // Use a simple recursive-descent parser to process the token // stream. bool haveNewline = true; @@ -77,6 +90,10 @@ bool cmListFileParser::ParseFile() { haveNewline = true; } + else if(token->type == cmListFileLexer_Token_CommentBracket) + { + haveNewline = false; + } else if(token->type == cmListFileLexer_Token_Identifier) { if(haveNewline) @@ -288,7 +305,10 @@ bool cmListFileParser::ParseFunction(const char* name, long line) { parenDepth++; this->Separation = SeparationOkay; - this->AddArgument(token, cmListFileArgument::Unquoted); + if(!this->AddArgument(token, cmListFileArgument::Unquoted)) + { + return false; + } } else if(token->type == cmListFileLexer_Token_ParenRight) { @@ -298,20 +318,41 @@ bool cmListFileParser::ParseFunction(const char* name, long line) } parenDepth--; this->Separation = SeparationOkay; - this->AddArgument(token, cmListFileArgument::Unquoted); + if(!this->AddArgument(token, cmListFileArgument::Unquoted)) + { + return false; + } this->Separation = SeparationWarning; } else if(token->type == cmListFileLexer_Token_Identifier || token->type == cmListFileLexer_Token_ArgumentUnquoted) { - this->AddArgument(token, cmListFileArgument::Unquoted); + if(!this->AddArgument(token, cmListFileArgument::Unquoted)) + { + return false; + } this->Separation = SeparationWarning; } else if(token->type == cmListFileLexer_Token_ArgumentQuoted) { - this->AddArgument(token, cmListFileArgument::Quoted); + if(!this->AddArgument(token, cmListFileArgument::Quoted)) + { + return false; + } this->Separation = SeparationWarning; } + else if(token->type == cmListFileLexer_Token_ArgumentBracket) + { + if(!this->AddArgument(token, cmListFileArgument::Bracket)) + { + return false; + } + this->Separation = SeparationError; + } + else if(token->type == cmListFileLexer_Token_CommentBracket) + { + this->Separation = SeparationError; + } else { // Error. @@ -338,42 +379,32 @@ bool cmListFileParser::ParseFunction(const char* name, long line) } //---------------------------------------------------------------------------- -void cmListFileParser::AddArgument(cmListFileLexer_Token* token, +bool cmListFileParser::AddArgument(cmListFileLexer_Token* token, cmListFileArgument::Delimiter delim) { cmListFileArgument a(token->text, delim, this->FileName, token->line); this->Function.Arguments.push_back(a); - if(delim == cmListFileArgument::Unquoted) - { - // Warn about a future behavior change. - const char* c = a.Value.c_str(); - if(*c++ == '[') - { - while(*c == '=') - { ++c; } - if(*c == '[') - { - cmOStringStream m; - m << "Syntax Warning in cmake code at\n" - << " " << this->FileName << ":" << token->line << ":" - << token->column << "\n" - << "A future version of CMake may treat unquoted argument:\n" - << " " << a.Value << "\n" - << "as an opening long bracket. Double-quote the argument."; - this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str().c_str()); - } - } - } if(this->Separation == SeparationOkay) { - return; + return true; } + bool isError = (this->Separation == SeparationError || + delim == cmListFileArgument::Bracket); cmOStringStream m; - m << "Syntax Warning in cmake code at\n" + m << "Syntax " << (isError? "Error":"Warning") << " in cmake code at\n" << " " << this->FileName << ":" << token->line << ":" << token->column << "\n" << "Argument not separated from preceding token by whitespace."; - this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str().c_str()); + if(isError) + { + this->Makefile->IssueMessage(cmake::FATAL_ERROR, m.str().c_str()); + return false; + } + else + { + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str().c_str()); + return true; + } } //---------------------------------------------------------------------------- diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 7bb3b34..bede25e 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -28,7 +28,8 @@ struct cmListFileArgument enum Delimiter { Unquoted, - Quoted + Quoted, + Bracket }; cmListFileArgument(): Value(), Delim(Unquoted), FilePath(0), Line(0) {} cmListFileArgument(const cmListFileArgument& r): diff --git a/Source/cmListFileLexer.c b/Source/cmListFileLexer.c index f127add..3b08b03 100644 --- a/Source/cmListFileLexer.c +++ b/Source/cmListFileLexer.c @@ -369,8 +369,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 16 -#define YY_END_OF_BUFFER 17 +#define YY_NUM_RULES 23 +#define YY_END_OF_BUFFER 24 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -378,13 +378,16 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[45] = +static yyconst flex_int16_t yy_accept[77] = { 0, - 0, 0, 0, 0, 17, 6, 14, 1, 8, 2, - 6, 3, 4, 6, 15, 9, 11, 12, 13, 6, - 0, 6, 0, 14, 2, 0, 5, 6, 9, 0, - 10, 0, 7, 0, 0, 0, 7, 0, 7, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, + 24, 13, 21, 1, 15, 3, 13, 5, 6, 7, + 22, 22, 16, 18, 19, 20, 10, 11, 8, 12, + 9, 4, 13, 0, 13, 0, 21, 0, 0, 7, + 13, 0, 13, 0, 2, 0, 13, 16, 0, 17, + 10, 8, 4, 0, 14, 0, 0, 0, 0, 14, + 0, 0, 14, 0, 0, 0, 2, 14, 0, 0, + 0, 0, 0, 0, 0, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -395,14 +398,14 @@ static yyconst flex_int32_t yy_ec[256] = 1, 2, 1, 5, 6, 7, 1, 1, 1, 8, 9, 1, 1, 1, 1, 1, 1, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 1, 1, 1, - 1, 1, 1, 1, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 1, 12, 1, 1, 11, 1, 11, 11, 11, 11, - - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 1, 1, 1, 1, 1, 1, 1, 1, + 11, 1, 1, 1, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 13, 14, 15, 1, 12, 1, 12, 12, 12, 12, + + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -419,72 +422,111 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[13] = +static yyconst flex_int32_t yy_meta[16] = { 0, - 1, 2, 3, 2, 4, 1, 1, 1, 5, 5, - 5, 1 + 1, 1, 2, 3, 4, 3, 1, 3, 5, 6, + 1, 6, 1, 1, 7 } ; -static yyconst flex_int16_t yy_base[56] = +static yyconst flex_int16_t yy_base[95] = { 0, - 0, 0, 10, 20, 38, 32, 0, 109, 109, 0, - 28, 109, 109, 35, 0, 23, 109, 109, 44, 0, - 49, 26, 0, 0, 0, 22, 0, 0, 18, 24, - 109, 0, 61, 20, 0, 18, 0, 17, 16, 0, - 12, 11, 10, 109, 73, 16, 78, 83, 88, 93, - 12, 98, 11, 103, 9 + 0, 0, 13, 25, 14, 16, 17, 18, 90, 88, + 88, 39, 20, 237, 237, 74, 78, 237, 237, 13, + 54, 0, 71, 237, 237, 31, 0, 237, 73, 237, + 237, 0, 0, 65, 75, 0, 33, 30, 72, 0, + 0, 75, 70, 0, 74, 0, 0, 62, 70, 237, + 0, 63, 0, 85, 99, 65, 111, 62, 34, 0, + 54, 116, 0, 54, 127, 51, 237, 50, 0, 48, + 47, 39, 33, 29, 17, 237, 136, 143, 150, 157, + 164, 171, 178, 184, 191, 198, 201, 207, 214, 217, + 219, 225, 228, 230 + } ; -static yyconst flex_int16_t yy_def[56] = +static yyconst flex_int16_t yy_def[95] = { 0, - 44, 1, 45, 45, 44, 44, 46, 44, 44, 47, - 6, 44, 44, 6, 48, 49, 44, 44, 49, 6, - 44, 6, 50, 46, 47, 51, 14, 6, 49, 49, - 44, 21, 44, 21, 52, 53, 33, 51, 33, 54, - 55, 53, 55, 0, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44 + 76, 1, 77, 77, 78, 78, 79, 79, 80, 80, + 76, 76, 76, 76, 76, 76, 12, 76, 76, 12, + 76, 81, 82, 76, 76, 82, 83, 76, 76, 76, + 76, 84, 12, 85, 12, 86, 76, 76, 87, 20, + 12, 88, 12, 21, 76, 89, 12, 82, 82, 76, + 83, 76, 84, 85, 76, 54, 85, 90, 76, 55, + 87, 88, 55, 62, 88, 91, 76, 55, 92, 93, + 90, 94, 91, 93, 94, 0, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76 + } ; -static yyconst flex_int16_t yy_nxt[122] = +static yyconst flex_int16_t yy_nxt[253] = { 0, - 6, 7, 8, 7, 9, 10, 11, 12, 13, 6, - 14, 15, 17, 43, 18, 42, 38, 24, 32, 33, - 32, 19, 17, 36, 18, 37, 33, 41, 29, 30, - 37, 19, 20, 36, 30, 26, 21, 44, 22, 44, - 44, 20, 20, 23, 27, 27, 31, 44, 29, 32, - 32, 44, 44, 33, 44, 34, 44, 44, 32, 32, - 35, 33, 44, 44, 44, 21, 44, 39, 44, 44, - 33, 33, 40, 16, 16, 16, 16, 16, 25, 25, - 44, 25, 25, 28, 28, 44, 28, 28, 29, 29, - 44, 44, 29, 20, 20, 44, 20, 20, 32, 32, - - 44, 32, 32, 33, 33, 44, 33, 33, 5, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44 + 12, 13, 14, 13, 15, 16, 17, 18, 19, 12, + 12, 20, 21, 22, 12, 24, 28, 25, 28, 28, + 28, 37, 40, 37, 40, 62, 26, 24, 29, 25, + 29, 31, 31, 50, 37, 48, 37, 54, 26, 33, + 59, 63, 45, 34, 59, 35, 45, 62, 33, 33, + 33, 33, 36, 33, 41, 55, 54, 58, 42, 63, + 43, 72, 60, 41, 44, 41, 45, 46, 41, 55, + 55, 56, 70, 52, 48, 49, 67, 66, 57, 63, + 60, 64, 58, 52, 49, 39, 38, 76, 65, 55, + 14, 56, 14, 76, 76, 76, 76, 76, 57, 55, + + 76, 76, 76, 34, 76, 68, 76, 76, 55, 55, + 55, 55, 69, 55, 54, 76, 54, 76, 54, 54, + 63, 76, 64, 76, 76, 76, 76, 76, 76, 65, + 62, 76, 62, 76, 62, 62, 23, 23, 23, 23, + 23, 23, 23, 27, 27, 27, 27, 27, 27, 27, + 30, 30, 30, 30, 30, 30, 30, 32, 32, 32, + 32, 32, 32, 32, 47, 76, 47, 47, 47, 47, + 47, 48, 76, 48, 76, 48, 48, 48, 51, 76, + 51, 51, 51, 51, 53, 76, 53, 53, 53, 53, + 53, 54, 76, 76, 54, 76, 54, 54, 33, 76, + + 33, 33, 33, 33, 33, 61, 61, 62, 76, 76, + 62, 76, 62, 62, 41, 76, 41, 41, 41, 41, + 41, 71, 71, 73, 73, 55, 76, 55, 55, 55, + 55, 55, 74, 74, 75, 75, 11, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76 } ; -static yyconst flex_int16_t yy_chk[122] = +static yyconst flex_int16_t yy_chk[253] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 3, 55, 3, 53, 51, 46, 43, 42, - 41, 3, 4, 39, 4, 38, 36, 34, 30, 29, - 26, 4, 6, 22, 16, 11, 6, 5, 6, 0, - 0, 6, 6, 6, 14, 14, 19, 0, 19, 21, - 21, 0, 0, 21, 0, 21, 0, 0, 21, 21, - 21, 33, 0, 0, 0, 33, 0, 33, 0, 0, - 33, 33, 33, 45, 45, 45, 45, 45, 47, 47, - 0, 47, 47, 48, 48, 0, 48, 48, 49, 49, - 0, 0, 49, 50, 50, 0, 50, 50, 52, 52, - - 0, 52, 52, 54, 54, 0, 54, 54, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44 + 1, 1, 1, 1, 1, 3, 5, 3, 6, 7, + 8, 13, 20, 13, 20, 75, 3, 4, 5, 4, + 6, 7, 8, 26, 37, 26, 37, 74, 4, 12, + 38, 73, 38, 12, 59, 12, 59, 72, 12, 12, + 12, 12, 12, 12, 21, 71, 70, 68, 21, 66, + 21, 64, 61, 21, 21, 21, 21, 21, 21, 34, + 58, 34, 56, 52, 49, 48, 45, 43, 34, 42, + 39, 42, 35, 29, 23, 17, 16, 11, 42, 54, + 10, 54, 9, 0, 0, 0, 0, 0, 54, 55, + + 0, 0, 0, 55, 0, 55, 0, 0, 55, 55, + 55, 55, 55, 55, 57, 0, 57, 0, 57, 57, + 62, 0, 62, 0, 0, 0, 0, 0, 0, 62, + 65, 0, 65, 0, 65, 65, 77, 77, 77, 77, + 77, 77, 77, 78, 78, 78, 78, 78, 78, 78, + 79, 79, 79, 79, 79, 79, 79, 80, 80, 80, + 80, 80, 80, 80, 81, 0, 81, 81, 81, 81, + 81, 82, 0, 82, 0, 82, 82, 82, 83, 0, + 83, 83, 83, 83, 84, 0, 84, 84, 84, 84, + 84, 85, 0, 0, 85, 0, 85, 85, 86, 0, + + 86, 86, 86, 86, 86, 87, 87, 88, 0, 0, + 88, 0, 88, 88, 89, 0, 89, 89, 89, 89, + 89, 90, 90, 91, 91, 92, 0, 92, 92, 92, + 92, 92, 93, 93, 94, 94, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76 } ; /* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[17] = +static yyconst flex_int32_t yy_rule_can_match_eol[24] = { 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, }; +1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, }; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. @@ -538,10 +580,13 @@ Modify cmListFileLexer.c: struct cmListFileLexer_s { cmListFileLexer_Token token; + int bracket; + int comment; int line; int column; int size; FILE* file; + size_t cr; char* string_buffer; char* string_position; int string_left; @@ -564,10 +609,16 @@ static void cmListFileLexerDestroy(cmListFileLexer* lexer); /*--------------------------------------------------------------------------*/ -#line 570 "cmListFileLexer.c" + + + +#line 618 "cmListFileLexer.c" #define INITIAL 0 #define STRING 1 +#define BRACKET 2 +#define BRACKETEND 3 +#define COMMENT 4 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way @@ -793,10 +844,10 @@ YY_DECL int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 82 "cmListFileLexer.in.l" +#line 88 "cmListFileLexer.in.l" -#line 804 "cmListFileLexer.c" +#line 855 "cmListFileLexer.c" if ( !yyg->yy_init ) { @@ -849,13 +900,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 45 ) + if ( yy_current_state >= 77 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 109 ); + while ( yy_base[yy_current_state] != 237 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -894,69 +945,168 @@ do_action: /* This label is used only to access EOF actions. */ case 1: /* rule 1 can match eol */ YY_RULE_SETUP -#line 84 "cmListFileLexer.in.l" +#line 90 "cmListFileLexer.in.l" { lexer->token.type = cmListFileLexer_Token_Newline; cmListFileLexerSetToken(lexer, yytext, yyleng); ++lexer->line; lexer->column = 1; + BEGIN(INITIAL); return 1; } case 2: +/* rule 2 can match eol */ YY_RULE_SETUP -#line 92 "cmListFileLexer.in.l" +#line 99 "cmListFileLexer.in.l" { - lexer->column += yyleng; + const char* bracket = yytext; + lexer->comment = yytext[0] == '#'; + if(lexer->comment) + { + lexer->token.type = cmListFileLexer_Token_CommentBracket; + bracket += 1; + } + else + { + lexer->token.type = cmListFileLexer_Token_ArgumentBracket; + } + cmListFileLexerSetToken(lexer, "", 0); + lexer->bracket = (int)(strchr(bracket+1, '[') - bracket); + if(yytext[yyleng-1] == '\n') + { + ++lexer->line; + lexer->column = 1; + } + else + { + lexer->column += yyleng; + } + BEGIN(BRACKET); } YY_BREAK case 3: YY_RULE_SETUP -#line 96 "cmListFileLexer.in.l" +#line 125 "cmListFileLexer.in.l" +{ + lexer->column += yyleng; + BEGIN(COMMENT); +} + YY_BREAK +case 4: +YY_RULE_SETUP +#line 130 "cmListFileLexer.in.l" +{ + lexer->column += yyleng; +} + YY_BREAK +case 5: +YY_RULE_SETUP +#line 134 "cmListFileLexer.in.l" { lexer->token.type = cmListFileLexer_Token_ParenLeft; cmListFileLexerSetToken(lexer, yytext, yyleng); lexer->column += yyleng; return 1; } -case 4: +case 6: YY_RULE_SETUP -#line 103 "cmListFileLexer.in.l" +#line 141 "cmListFileLexer.in.l" { lexer->token.type = cmListFileLexer_Token_ParenRight; cmListFileLexerSetToken(lexer, yytext, yyleng); lexer->column += yyleng; return 1; } -case 5: +case 7: YY_RULE_SETUP -#line 110 "cmListFileLexer.in.l" +#line 148 "cmListFileLexer.in.l" { lexer->token.type = cmListFileLexer_Token_Identifier; cmListFileLexerSetToken(lexer, yytext, yyleng); lexer->column += yyleng; return 1; } -case 6: +case 8: +YY_RULE_SETUP +#line 155 "cmListFileLexer.in.l" +{ + /* Handle ]]====]=======]*/ + cmListFileLexerAppend(lexer, yytext, yyleng); + lexer->column += yyleng; + if(yyleng == lexer->bracket) + { + BEGIN(BRACKETEND); + } +} + YY_BREAK +case 9: +YY_RULE_SETUP +#line 165 "cmListFileLexer.in.l" +{ + lexer->column += yyleng; + /* Erase the partial bracket from the token. */ + lexer->token.length -= lexer->bracket; + lexer->token.text[lexer->token.length] = 0; + BEGIN(INITIAL); + return 1; +} +case 10: +YY_RULE_SETUP +#line 174 "cmListFileLexer.in.l" +{ + cmListFileLexerAppend(lexer, yytext, yyleng); + lexer->column += yyleng; +} + YY_BREAK +case 11: +/* rule 11 can match eol */ +YY_RULE_SETUP +#line 179 "cmListFileLexer.in.l" +{ + cmListFileLexerAppend(lexer, yytext, yyleng); + ++lexer->line; + lexer->column = 1; + BEGIN(BRACKET); +} + YY_BREAK +case 12: +YY_RULE_SETUP +#line 186 "cmListFileLexer.in.l" +{ + cmListFileLexerAppend(lexer, yytext, yyleng); + lexer->column += yyleng; + BEGIN(BRACKET); +} + YY_BREAK +case YY_STATE_EOF(BRACKET): +case YY_STATE_EOF(BRACKETEND): +#line 192 "cmListFileLexer.in.l" +{ + lexer->token.type = cmListFileLexer_Token_BadBracket; + BEGIN(INITIAL); + return 1; +} +case 13: YY_RULE_SETUP -#line 117 "cmListFileLexer.in.l" +#line 198 "cmListFileLexer.in.l" { lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted; cmListFileLexerSetToken(lexer, yytext, yyleng); lexer->column += yyleng; return 1; } -case 7: +case 14: YY_RULE_SETUP -#line 124 "cmListFileLexer.in.l" +#line 205 "cmListFileLexer.in.l" { lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted; cmListFileLexerSetToken(lexer, yytext, yyleng); lexer->column += yyleng; return 1; } -case 8: +case 15: YY_RULE_SETUP -#line 131 "cmListFileLexer.in.l" +#line 212 "cmListFileLexer.in.l" { lexer->token.type = cmListFileLexer_Token_ArgumentQuoted; cmListFileLexerSetToken(lexer, "", 0); @@ -964,69 +1114,69 @@ YY_RULE_SETUP BEGIN(STRING); } YY_BREAK -case 9: +case 16: YY_RULE_SETUP -#line 138 "cmListFileLexer.in.l" +#line 219 "cmListFileLexer.in.l" { cmListFileLexerAppend(lexer, yytext, yyleng); lexer->column += yyleng; } YY_BREAK -case 10: -/* rule 10 can match eol */ +case 17: +/* rule 17 can match eol */ YY_RULE_SETUP -#line 143 "cmListFileLexer.in.l" +#line 224 "cmListFileLexer.in.l" { cmListFileLexerAppend(lexer, yytext, yyleng); ++lexer->line; lexer->column = 1; } YY_BREAK -case 11: -/* rule 11 can match eol */ +case 18: +/* rule 18 can match eol */ YY_RULE_SETUP -#line 149 "cmListFileLexer.in.l" +#line 230 "cmListFileLexer.in.l" { cmListFileLexerAppend(lexer, yytext, yyleng); ++lexer->line; lexer->column = 1; } YY_BREAK -case 12: +case 19: YY_RULE_SETUP -#line 155 "cmListFileLexer.in.l" +#line 236 "cmListFileLexer.in.l" { lexer->column += yyleng; BEGIN(INITIAL); return 1; } -case 13: +case 20: YY_RULE_SETUP -#line 161 "cmListFileLexer.in.l" +#line 242 "cmListFileLexer.in.l" { cmListFileLexerAppend(lexer, yytext, yyleng); lexer->column += yyleng; } YY_BREAK case YY_STATE_EOF(STRING): -#line 166 "cmListFileLexer.in.l" +#line 247 "cmListFileLexer.in.l" { lexer->token.type = cmListFileLexer_Token_BadString; BEGIN(INITIAL); return 1; } -case 14: +case 21: YY_RULE_SETUP -#line 172 "cmListFileLexer.in.l" +#line 253 "cmListFileLexer.in.l" { lexer->token.type = cmListFileLexer_Token_Space; cmListFileLexerSetToken(lexer, yytext, yyleng); lexer->column += yyleng; return 1; } -case 15: +case 22: YY_RULE_SETUP -#line 179 "cmListFileLexer.in.l" +#line 260 "cmListFileLexer.in.l" { lexer->token.type = cmListFileLexer_Token_BadCharacter; cmListFileLexerSetToken(lexer, yytext, yyleng); @@ -1034,18 +1184,19 @@ YY_RULE_SETUP return 1; } case YY_STATE_EOF(INITIAL): -#line 186 "cmListFileLexer.in.l" +case YY_STATE_EOF(COMMENT): +#line 267 "cmListFileLexer.in.l" { lexer->token.type = cmListFileLexer_Token_None; cmListFileLexerSetToken(lexer, 0, 0); return 0; } -case 16: +case 23: YY_RULE_SETUP -#line 192 "cmListFileLexer.in.l" +#line 273 "cmListFileLexer.in.l" ECHO; YY_BREAK -#line 1064 "cmListFileLexer.c" +#line 1217 "cmListFileLexer.c" case YY_END_OF_BUFFER: { @@ -1337,7 +1488,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 45 ) + if ( yy_current_state >= 77 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1366,11 +1517,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 45 ) + if ( yy_current_state >= 77 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 44); + yy_is_jam = (yy_current_state == 76); return yy_is_jam ? 0 : yy_current_state; } @@ -2166,7 +2317,7 @@ void cmListFileLexer_yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 192 "cmListFileLexer.in.l" +#line 273 "cmListFileLexer.in.l" @@ -2243,7 +2394,38 @@ static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer, { if(lexer->file) { - return (int)fread(buffer, 1, bufferSize, lexer->file); + /* Convert CRLF -> LF explicitly. The C FILE "t"ext mode + does not convert newlines on all platforms. Move any + trailing CR to the start of the buffer for the next read. */ + size_t cr = lexer->cr; + size_t n; + buffer[0] = '\r'; + n = fread(buffer+cr, 1, bufferSize-cr, lexer->file); + if(n) + { + char* o = buffer; + const char* i = buffer; + const char* e; + n += cr; + cr = (buffer[n-1] == '\r')? 1:0; + e = buffer + n - cr; + while(i != e) + { + if(i[0] == '\r' && i[1] == '\n') + { + ++i; + } + *o++ = *i++; + } + n = o - buffer; + } + else + { + n = cr; + cr = 0; + } + lexer->cr = cr; + return n; } else if(lexer->string_left) { @@ -2307,19 +2489,68 @@ cmListFileLexer* cmListFileLexer_New() /*--------------------------------------------------------------------------*/ void cmListFileLexer_Delete(cmListFileLexer* lexer) { - cmListFileLexer_SetFileName(lexer, 0); + cmListFileLexer_SetFileName(lexer, 0, 0); free(lexer); } /*--------------------------------------------------------------------------*/ -int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name) +static cmListFileLexer_BOM cmListFileLexer_ReadBOM(FILE* f) +{ + unsigned char b[2]; + if(fread(b, 1, 2, f) == 2) + { + if(b[0] == 0xEF && b[1] == 0xBB) + { + if(fread(b, 1, 1, f) == 1 && b[0] == 0xBF) + { + return cmListFileLexer_BOM_UTF8; + } + } + else if(b[0] == 0xFE && b[1] == 0xFF) + { + /* UTF-16 BE */ + return cmListFileLexer_BOM_UTF16BE; + } + else if(b[0] == 0 && b[1] == 0) + { + if(fread(b, 1, 2, f) == 2 && b[0] == 0xFE && b[1] == 0xFF) + { + return cmListFileLexer_BOM_UTF32BE; + } + } + else if(b[0] == 0xFF && b[1] == 0xFE) + { + fpos_t p; + fgetpos(f, &p); + if(fread(b, 1, 2, f) == 2 && b[0] == 0 && b[1] == 0) + { + return cmListFileLexer_BOM_UTF32LE; + } + fsetpos(f, &p); + return cmListFileLexer_BOM_UTF16LE; + } + } + rewind(f); + return cmListFileLexer_BOM_None; +} + +/*--------------------------------------------------------------------------*/ +int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name, + cmListFileLexer_BOM* bom) { int result = 1; cmListFileLexerDestroy(lexer); if(name) { - lexer->file = fopen(name, "r"); - if(!lexer->file) + lexer->file = fopen(name, "rb"); + if(lexer->file) + { + if(bom) + { + *bom = cmListFileLexer_ReadBOM(lexer->file); + } + } + else { result = 0; } @@ -2365,7 +2596,7 @@ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer) } else { - cmListFileLexer_SetFileName(lexer, 0); + cmListFileLexer_SetFileName(lexer, 0, 0); return 0; } } @@ -2411,7 +2642,10 @@ const char* cmListFileLexer_GetTypeAsString(cmListFileLexer* lexer, case cmListFileLexer_Token_ParenRight: return "right paren"; case cmListFileLexer_Token_ArgumentUnquoted: return "unquoted argument"; case cmListFileLexer_Token_ArgumentQuoted: return "quoted argument"; + case cmListFileLexer_Token_ArgumentBracket: return "bracket argument"; + case cmListFileLexer_Token_CommentBracket: return "bracket comment"; case cmListFileLexer_Token_BadCharacter: return "bad character"; + case cmListFileLexer_Token_BadBracket: return "unterminated bracket"; case cmListFileLexer_Token_BadString: return "unterminated string"; } return "unknown token"; diff --git a/Source/cmListFileLexer.h b/Source/cmListFileLexer.h index cc78b5c..bd2868a 100644 --- a/Source/cmListFileLexer.h +++ b/Source/cmListFileLexer.h @@ -22,7 +22,10 @@ typedef enum cmListFileLexer_Type_e cmListFileLexer_Token_ParenRight, cmListFileLexer_Token_ArgumentUnquoted, cmListFileLexer_Token_ArgumentQuoted, + cmListFileLexer_Token_ArgumentBracket, + cmListFileLexer_Token_CommentBracket, cmListFileLexer_Token_BadCharacter, + cmListFileLexer_Token_BadBracket, cmListFileLexer_Token_BadString } cmListFileLexer_Type; @@ -36,6 +39,17 @@ struct cmListFileLexer_Token_s int column; }; +enum cmListFileLexer_BOM_e +{ + cmListFileLexer_BOM_None, + cmListFileLexer_BOM_UTF8, + cmListFileLexer_BOM_UTF16BE, + cmListFileLexer_BOM_UTF16LE, + cmListFileLexer_BOM_UTF32BE, + cmListFileLexer_BOM_UTF32LE +}; +typedef enum cmListFileLexer_BOM_e cmListFileLexer_BOM; + typedef struct cmListFileLexer_s cmListFileLexer; #ifdef __cplusplus @@ -44,7 +58,8 @@ extern "C" #endif cmListFileLexer* cmListFileLexer_New(); -int cmListFileLexer_SetFileName(cmListFileLexer*, const char*); +int cmListFileLexer_SetFileName(cmListFileLexer*, const char*, + cmListFileLexer_BOM* bom); int cmListFileLexer_SetString(cmListFileLexer*, const char*); cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer*); long cmListFileLexer_GetCurrentLine(cmListFileLexer*); diff --git a/Source/cmListFileLexer.in.l b/Source/cmListFileLexer.in.l index bd3c1eb..ecaf156 100644 --- a/Source/cmListFileLexer.in.l +++ b/Source/cmListFileLexer.in.l @@ -42,10 +42,13 @@ Modify cmListFileLexer.c: struct cmListFileLexer_s { cmListFileLexer_Token token; + int bracket; + int comment; int line; int column; int size; FILE* file; + size_t cr; char* string_buffer; char* string_position; int string_left; @@ -74,22 +77,57 @@ static void cmListFileLexerDestroy(cmListFileLexer* lexer); %option noyywrap %pointer %x STRING +%x BRACKET +%x BRACKETEND +%x COMMENT MAKEVAR \$\([A-Za-z0-9_]*\) -UNQUOTED ([^ \t\r\n\(\)#\\\"]|\\.) -LEGACY {MAKEVAR}|{UNQUOTED}|\"({MAKEVAR}|{UNQUOTED}|[ \t])*\" +UNQUOTED ([^ \t\r\n\(\)#\\\"[=]|\\.) +LEGACY {MAKEVAR}|{UNQUOTED}|\"({MAKEVAR}|{UNQUOTED}|[ \t[=])*\" %% -\n { +<INITIAL,COMMENT>\n { lexer->token.type = cmListFileLexer_Token_Newline; cmListFileLexerSetToken(lexer, yytext, yyleng); ++lexer->line; lexer->column = 1; + BEGIN(INITIAL); return 1; } -#.* { +#?\[=*\[\n? { + const char* bracket = yytext; + lexer->comment = yytext[0] == '#'; + if(lexer->comment) + { + lexer->token.type = cmListFileLexer_Token_CommentBracket; + bracket += 1; + } + else + { + lexer->token.type = cmListFileLexer_Token_ArgumentBracket; + } + cmListFileLexerSetToken(lexer, "", 0); + lexer->bracket = (int)(strchr(bracket+1, '[') - bracket); + if(yytext[yyleng-1] == '\n') + { + ++lexer->line; + lexer->column = 1; + } + else + { + lexer->column += yyleng; + } + BEGIN(BRACKET); +} + +# { + lexer->column += yyleng; + BEGIN(COMMENT); +} + +<COMMENT>.* { lexer->column += yyleng; } @@ -107,21 +145,64 @@ LEGACY {MAKEVAR}|{UNQUOTED}|\"({MAKEVAR}|{UNQUOTED}|[ \t])*\" return 1; } -[A-Za-z_][A-Za-z0-9_]+ { +[A-Za-z_][A-Za-z0-9_]* { lexer->token.type = cmListFileLexer_Token_Identifier; cmListFileLexerSetToken(lexer, yytext, yyleng); lexer->column += yyleng; return 1; } -({UNQUOTED})({UNQUOTED})* { +<BRACKET>\]=* { + /* Handle ]]====]=======]*/ + cmListFileLexerAppend(lexer, yytext, yyleng); + lexer->column += yyleng; + if(yyleng == lexer->bracket) + { + BEGIN(BRACKETEND); + } +} + +<BRACKETEND>\] { + lexer->column += yyleng; + /* Erase the partial bracket from the token. */ + lexer->token.length -= lexer->bracket; + lexer->token.text[lexer->token.length] = 0; + BEGIN(INITIAL); + return 1; +} + +<BRACKET>([^]\n])+ { + cmListFileLexerAppend(lexer, yytext, yyleng); + lexer->column += yyleng; +} + +<BRACKET,BRACKETEND>\n { + cmListFileLexerAppend(lexer, yytext, yyleng); + ++lexer->line; + lexer->column = 1; + BEGIN(BRACKET); +} + +<BRACKET,BRACKETEND>. { + cmListFileLexerAppend(lexer, yytext, yyleng); + lexer->column += yyleng; + BEGIN(BRACKET); +} + +<BRACKET,BRACKETEND><<EOF>> { + lexer->token.type = cmListFileLexer_Token_BadBracket; + BEGIN(INITIAL); + return 1; +} + +({UNQUOTED}|=|\[=*{UNQUOTED})({UNQUOTED}|[[=])* { lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted; cmListFileLexerSetToken(lexer, yytext, yyleng); lexer->column += yyleng; return 1; } -({MAKEVAR}|{UNQUOTED})({LEGACY})* { +({MAKEVAR}|{UNQUOTED}|=|\[=*{LEGACY})({LEGACY}|[[=])* { lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted; cmListFileLexerSetToken(lexer, yytext, yyleng); lexer->column += yyleng; @@ -264,7 +345,38 @@ static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer, { if(lexer->file) { - return (int)fread(buffer, 1, bufferSize, lexer->file); + /* Convert CRLF -> LF explicitly. The C FILE "t"ext mode + does not convert newlines on all platforms. Move any + trailing CR to the start of the buffer for the next read. */ + size_t cr = lexer->cr; + size_t n; + buffer[0] = '\r'; + n = fread(buffer+cr, 1, bufferSize-cr, lexer->file); + if(n) + { + char* o = buffer; + const char* i = buffer; + const char* e; + n += cr; + cr = (buffer[n-1] == '\r')? 1:0; + e = buffer + n - cr; + while(i != e) + { + if(i[0] == '\r' && i[1] == '\n') + { + ++i; + } + *o++ = *i++; + } + n = o - buffer; + } + else + { + n = cr; + cr = 0; + } + lexer->cr = cr; + return n; } else if(lexer->string_left) { @@ -328,19 +440,68 @@ cmListFileLexer* cmListFileLexer_New() /*--------------------------------------------------------------------------*/ void cmListFileLexer_Delete(cmListFileLexer* lexer) { - cmListFileLexer_SetFileName(lexer, 0); + cmListFileLexer_SetFileName(lexer, 0, 0); free(lexer); } /*--------------------------------------------------------------------------*/ -int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name) +static cmListFileLexer_BOM cmListFileLexer_ReadBOM(FILE* f) +{ + unsigned char b[2]; + if(fread(b, 1, 2, f) == 2) + { + if(b[0] == 0xEF && b[1] == 0xBB) + { + if(fread(b, 1, 1, f) == 1 && b[0] == 0xBF) + { + return cmListFileLexer_BOM_UTF8; + } + } + else if(b[0] == 0xFE && b[1] == 0xFF) + { + /* UTF-16 BE */ + return cmListFileLexer_BOM_UTF16BE; + } + else if(b[0] == 0 && b[1] == 0) + { + if(fread(b, 1, 2, f) == 2 && b[0] == 0xFE && b[1] == 0xFF) + { + return cmListFileLexer_BOM_UTF32BE; + } + } + else if(b[0] == 0xFF && b[1] == 0xFE) + { + fpos_t p; + fgetpos(f, &p); + if(fread(b, 1, 2, f) == 2 && b[0] == 0 && b[1] == 0) + { + return cmListFileLexer_BOM_UTF32LE; + } + fsetpos(f, &p); + return cmListFileLexer_BOM_UTF16LE; + } + } + rewind(f); + return cmListFileLexer_BOM_None; +} + +/*--------------------------------------------------------------------------*/ +int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name, + cmListFileLexer_BOM* bom) { int result = 1; cmListFileLexerDestroy(lexer); if(name) { - lexer->file = fopen(name, "r"); - if(!lexer->file) + lexer->file = fopen(name, "rb"); + if(lexer->file) + { + if(bom) + { + *bom = cmListFileLexer_ReadBOM(lexer->file); + } + } + else { result = 0; } @@ -386,7 +547,7 @@ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer) } else { - cmListFileLexer_SetFileName(lexer, 0); + cmListFileLexer_SetFileName(lexer, 0, 0); return 0; } } @@ -432,7 +593,10 @@ const char* cmListFileLexer_GetTypeAsString(cmListFileLexer* lexer, case cmListFileLexer_Token_ParenRight: return "right paren"; case cmListFileLexer_Token_ArgumentUnquoted: return "unquoted argument"; case cmListFileLexer_Token_ArgumentQuoted: return "quoted argument"; + case cmListFileLexer_Token_ArgumentBracket: return "bracket argument"; + case cmListFileLexer_Token_CommentBracket: return "bracket comment"; case cmListFileLexer_Token_BadCharacter: return "bad character"; + case cmListFileLexer_Token_BadBracket: return "unterminated bracket"; case cmListFileLexer_Token_BadString: return "unterminated string"; } return "unknown token"; diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 2443583..508eca1 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -381,6 +381,7 @@ void cmLocalUnixMakefileGenerator3 (t->second.GetType() == cmTarget::SHARED_LIBRARY) || (t->second.GetType() == cmTarget::MODULE_LIBRARY) || (t->second.GetType() == cmTarget::OBJECT_LIBRARY) || + (t->second.GetType() == cmTarget::INTERFACE_LIBRARY) || (t->second.GetType() == cmTarget::UTILITY)) { emitted.insert(t->second.GetName()); @@ -1158,27 +1159,25 @@ cmLocalUnixMakefileGenerator3 const std::vector<std::string>& files, cmTarget& target, const char* filename) { + std::string cleanfile = this->Makefile->GetCurrentOutputDirectory(); + cleanfile += "/"; + cleanfile += this->GetTargetDirectory(target); + cleanfile += "/cmake_clean"; + if(filename) + { + cleanfile += "_"; + cleanfile += filename; + } + cleanfile += ".cmake"; + std::string cleanfilePath = this->Convert(cleanfile.c_str(), FULL); + std::ofstream fout(cleanfilePath.c_str()); + if(!fout) + { + cmSystemTools::Error("Could not create ", cleanfilePath.c_str()); + } if(!files.empty()) { - std::string cleanfile = this->Makefile->GetCurrentOutputDirectory(); - cleanfile += "/"; - cleanfile += this->GetTargetDirectory(target); - cleanfile += "/cmake_clean"; - if(filename) - { - cleanfile += "_"; - cleanfile += filename; - } - cleanfile += ".cmake"; - std::string cleanfilePath = this->Convert(cleanfile.c_str(), FULL); - std::ofstream fout(cleanfilePath.c_str()); - if(!fout) - { - cmSystemTools::Error("Could not create ", cleanfilePath.c_str()); - } fout << "file(REMOVE_RECURSE\n"; - std::string remove = "$(CMAKE_COMMAND) -P "; - remove += this->Convert(cleanfile.c_str(), START_OUTPUT, SHELL); for(std::vector<std::string>::const_iterator f = files.begin(); f != files.end(); ++f) { @@ -1186,27 +1185,29 @@ cmLocalUnixMakefileGenerator3 fout << " " << this->EscapeForCMake(fc.c_str()) << "\n"; } fout << ")\n"; - commands.push_back(remove); - - // For the main clean rule add per-language cleaning. - if(!filename) + } + std::string remove = "$(CMAKE_COMMAND) -P "; + remove += this->Convert(cleanfile.c_str(), START_OUTPUT, SHELL); + commands.push_back(remove); + + // For the main clean rule add per-language cleaning. + if(!filename) + { + // Get the set of source languages in the target. + std::set<cmStdString> languages; + target.GetLanguages(languages); + fout << "\n" + << "# Per-language clean rules from dependency scanning.\n" + << "foreach(lang"; + for(std::set<cmStdString>::const_iterator l = languages.begin(); + l != languages.end(); ++l) { - // Get the set of source languages in the target. - std::set<cmStdString> languages; - target.GetLanguages(languages); - fout << "\n" - << "# Per-language clean rules from dependency scanning.\n" - << "foreach(lang"; - for(std::set<cmStdString>::const_iterator l = languages.begin(); - l != languages.end(); ++l) - { - fout << " " << *l; - } - fout << ")\n" - << " include(" << this->GetTargetDirectory(target) - << "/cmake_clean_${lang}.cmake OPTIONAL)\n" - << "endforeach()\n"; + fout << " " << *l; } + fout << ")\n" + << " include(" << this->GetTargetDirectory(target) + << "/cmake_clean_${lang}.cmake OPTIONAL)\n" + << "endforeach()\n"; } } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index a390e06..13c43fa 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -2867,6 +2867,12 @@ bool cmMakefile::ExpandArguments( outArgs.reserve(inArgs.size()); for(i = inArgs.begin(); i != inArgs.end(); ++i) { + // No expansion in a bracket argument. + if(i->Delim == cmListFileArgument::Bracket) + { + outArgs.push_back(i->Value); + continue; + } // Expand the variables in the argument. value = i->Value; this->ExpandVariablesInString(value, false, false, false, diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index ea9663f..29365a3 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -82,6 +82,9 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles() case cmTarget::OBJECT_LIBRARY: this->WriteObjectLibraryRules(); break; + case cmTarget::INTERFACE_LIBRARY: + // Nothing to do. + break; default: // If language is not known, this is an error. cmSystemTools::Error("Unknown Library Type"); diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 9ca9149..6770e10 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -75,6 +75,7 @@ cmMakefileTargetGenerator::New(cmTarget *tgt) case cmTarget::SHARED_LIBRARY: case cmTarget::MODULE_LIBRARY: case cmTarget::OBJECT_LIBRARY: + case cmTarget::INTERFACE_LIBRARY: result = new cmMakefileLibraryTargetGenerator(tgt); break; case cmTarget::UTILITY: diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index cbd4632..8320ecf 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -115,19 +115,6 @@ bool cmSystemTools::s_FatalErrorOccured = false; bool cmSystemTools::s_DisableMessages = false; bool cmSystemTools::s_ForceUnixPaths = false; -std::string cmSystemTools::s_Windows9xComspecSubstitute = "command.com"; -void cmSystemTools::SetWindows9xComspecSubstitute(const char* str) -{ - if ( str ) - { - cmSystemTools::s_Windows9xComspecSubstitute = str; - } -} -const char* cmSystemTools::GetWindows9xComspecSubstitute() -{ - return cmSystemTools::s_Windows9xComspecSubstitute.c_str(); -} - void (*cmSystemTools::s_ErrorCallback)(const char*, const char*, bool&, void*); void (*cmSystemTools::s_StdoutCallback)(const char*, int len, void*); @@ -787,351 +774,6 @@ bool cmSystemTools::RunSingleCommand( return cmSystemTools::RunSingleCommand(args, output,retVal, dir, outputflag, timeout); } -bool cmSystemTools::RunCommand(const char* command, - std::string& output, - const char* dir, - bool verbose, - int timeout) -{ - int dummy; - return cmSystemTools::RunCommand(command, output, dummy, - dir, verbose, timeout); -} - -#if defined(WIN32) && !defined(__CYGWIN__) -#include "cmWin32ProcessExecution.h" -// use this for shell commands like echo and dir -bool RunCommandViaWin32(const char* command, - const char* dir, - std::string& output, - int& retVal, - bool verbose, - int timeout) -{ -#if defined(__BORLANDC__) - return - cmWin32ProcessExecution:: - BorlandRunCommand(command, dir, output, - retVal, - verbose, timeout, - cmSystemTools::GetRunCommandHideConsole()); -#else // Visual studio - ::SetLastError(ERROR_SUCCESS); - if ( ! command ) - { - cmSystemTools::Error("No command specified"); - return false; - } - cmWin32ProcessExecution resProc; - if(cmSystemTools::GetRunCommandHideConsole()) - { - resProc.SetHideWindows(true); - } - - if ( cmSystemTools::GetWindows9xComspecSubstitute() ) - { - resProc.SetConsoleSpawn(cmSystemTools::GetWindows9xComspecSubstitute() ); - } - if ( !resProc.StartProcess(command, dir, verbose) ) - { - output = resProc.GetOutput(); - if(verbose) - { - cmSystemTools::Stdout(output.c_str()); - } - return false; - } - resProc.Wait(timeout); - output = resProc.GetOutput(); - retVal = resProc.GetExitValue(); - return true; -#endif -} - -// use this for shell commands like echo and dir -bool RunCommandViaSystem(const char* command, - const char* dir, - std::string& output, - int& retVal, - bool verbose) -{ - std::cout << "@@ " << command << std::endl; - - std::string commandInDir; - if(dir) - { - commandInDir = "cd "; - commandInDir += cmSystemTools::ConvertToOutputPath(dir); - commandInDir += " && "; - commandInDir += command; - } - else - { - commandInDir = command; - } - command = commandInDir.c_str(); - std::string commandToFile = command; - commandToFile += " > "; - std::string tempFile; - tempFile += _tempnam(0, "cmake"); - - commandToFile += tempFile; - retVal = system(commandToFile.c_str()); - std::ifstream fin(tempFile.c_str()); - if(!fin) - { - if(verbose) - { - std::string errormsg = "RunCommand produced no output: command: \""; - errormsg += command; - errormsg += "\""; - errormsg += "\nOutput file: "; - errormsg += tempFile; - cmSystemTools::Error(errormsg.c_str()); - } - fin.close(); - cmSystemTools::RemoveFile(tempFile.c_str()); - return false; - } - bool multiLine = false; - std::string line; - while(cmSystemTools::GetLineFromStream(fin, line)) - { - output += line; - if(multiLine) - { - output += "\n"; - } - multiLine = true; - } - fin.close(); - cmSystemTools::RemoveFile(tempFile.c_str()); - return true; -} - -#else // We have popen - -// BeOS seems to return from a successful pclose() before the process has -// legitimately exited, or at least before SIGCHLD is thrown...the signal may -// come quite some time after pclose returns! This causes havoc with later -// parts of CMake that expect to catch the signal from other child processes, -// so we explicitly wait to catch it here. This should be safe to do with -// popen() so long as we don't actually collect the zombie process ourselves. -#ifdef __BEOS__ -#include <signal.h> -#undef SIGBUS // this is the same as SIGSEGV on BeOS and causes issues below. -static volatile bool beos_seen_signal = false; -static void beos_popen_workaround(int sig) -{ - beos_seen_signal = true; -} -#endif - -bool RunCommandViaPopen(const char* command, - const char* dir, - std::string& output, - int& retVal, - bool verbose, - int /*timeout*/) -{ - // if only popen worked on windows..... - std::string commandInDir; - if(dir) - { - commandInDir = "cd \""; - commandInDir += dir; - commandInDir += "\" && "; - commandInDir += command; - } - else - { - commandInDir = command; - } -#ifndef __VMS - commandInDir += " 2>&1"; -#endif - command = commandInDir.c_str(); - const int BUFFER_SIZE = 4096; - char buffer[BUFFER_SIZE]; - if(verbose) - { - cmSystemTools::Stdout("running "); - cmSystemTools::Stdout(command); - cmSystemTools::Stdout("\n"); - } - fflush(stdout); - fflush(stderr); - -#ifdef __BEOS__ - beos_seen_signal = false; - signal(SIGCHLD, beos_popen_workaround); -#endif - - FILE* cpipe = popen(command, "r"); - if(!cpipe) - { -#ifdef __BEOS__ - signal(SIGCHLD, SIG_DFL); -#endif - return false; - } - if (!fgets(buffer, BUFFER_SIZE, cpipe)) - { - buffer[0] = 0; - } - while(!feof(cpipe)) - { - if(verbose) - { - cmSystemTools::Stdout(buffer); - } - output += buffer; - if(!fgets(buffer, BUFFER_SIZE, cpipe)) - { - buffer[0] = 0; - } - } - - retVal = pclose(cpipe); - -#ifdef __BEOS__ - for (int i = 0; (!beos_seen_signal) && (i < 3); i++) - { - ::sleep(1); // signals should interrupt this... - } - - if (!beos_seen_signal) - { - signal(SIGCHLD, SIG_DFL); // oh well, didn't happen. Go on anyhow. - } -#endif - - if (WIFEXITED(retVal)) - { - retVal = WEXITSTATUS(retVal); - return true; - } - if (WIFSIGNALED(retVal)) - { - retVal = WTERMSIG(retVal); - cmOStringStream error; - error << "\nProcess terminated due to "; - switch (retVal) - { -#ifdef SIGKILL - case SIGKILL: - error << "SIGKILL"; - break; -#endif -#ifdef SIGFPE - case SIGFPE: - error << "SIGFPE"; - break; -#endif -#ifndef __HAIKU__ -#ifdef SIGBUS - case SIGBUS: - error << "SIGBUS"; - break; -#endif -#endif -#ifdef SIGSEGV - case SIGSEGV: - error << "SIGSEGV"; - break; -#endif - default: - error << "signal " << retVal; - break; - } - output += error.str(); - } - return false; -} - -#endif // endif WIN32 not CYGWIN - - -// run a command unix uses popen (easy) -// windows uses system and ShortPath -bool cmSystemTools::RunCommand(const char* command, - std::string& output, - int &retVal, - const char* dir, - bool verbose, - int timeout) -{ - if(s_DisableRunCommandOutput) - { - verbose = false; - } - -#if defined(WIN32) && !defined(__CYGWIN__) - // if the command does not start with a quote, then - // try to find the program, and if the program can not be - // found use system to run the command as it must be a built in - // shell command like echo or dir - int count = 0; - if(command[0] == '\"') - { - // count the number of quotes - for(const char* s = command; *s != 0; ++s) - { - if(*s == '\"') - { - count++; - if(count > 2) - { - break; - } - } - } - // if there are more than two double quotes use - // GetShortPathName, the cmd.exe program in windows which - // is used by system fails to execute if there are more than - // one set of quotes in the arguments - if(count > 2) - { - cmsys::RegularExpression quoted("^\"([^\"]*)\"[ \t](.*)"); - if(quoted.find(command)) - { - std::string shortCmd; - std::string cmd = quoted.match(1); - std::string args = quoted.match(2); - if(! cmSystemTools::FileExists(cmd.c_str()) ) - { - shortCmd = cmd; - } - else if(!cmSystemTools::GetShortPath(cmd.c_str(), shortCmd)) - { - cmSystemTools::Error("GetShortPath failed for " , cmd.c_str()); - return false; - } - shortCmd += " "; - shortCmd += args; - - //return RunCommandViaSystem(shortCmd.c_str(), dir, - // output, retVal, verbose); - //return WindowsRunCommand(shortCmd.c_str(), dir, - //output, retVal, verbose); - return RunCommandViaWin32(shortCmd.c_str(), dir, - output, retVal, verbose, timeout); - } - else - { - cmSystemTools::Error("Could not parse command line with quotes ", - command); - } - } - } - // if there is only one set of quotes or no quotes then just run the command - //return RunCommandViaSystem(command, dir, output, retVal, verbose); - //return WindowsRunCommand(command, dir, output, retVal, verbose); - return ::RunCommandViaWin32(command, dir, output, retVal, verbose, timeout); -#else - return ::RunCommandViaPopen(command, dir, output, retVal, verbose, timeout); -#endif -} bool cmSystemTools::DoesFileExistWithExtensions( const char* name, diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index cbc1140..07235da 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -191,23 +191,6 @@ public: static std::string ComputeStringMD5(const char* input); /** - * Run an executable command and put the stdout in output. - * A temporary file is created in the binaryDir for storing the - * output because windows does not have popen. - * - * If verbose is false, no user-viewable output from the program - * being run will be generated. - * - * If timeout is specified, the command will be terminated after - * timeout expires. - */ - static bool RunCommand(const char* command, std::string& output, - const char* directory = 0, - bool verbose = true, int timeout = 0); - static bool RunCommand(const char* command, std::string& output, - int &retVal, const char* directory = 0, - bool verbose = true, int timeout = 0); - /** * Run a single executable command * * Output is controlled with outputflag. If outputflag is OUTPUT_NONE, no @@ -312,14 +295,6 @@ public: */ static FileFormat GetFileFormat(const char* ext); - /** - * On Windows 9x we need a comspec (command.com) substitute to run - * programs correctly. This string has to be constant available - * through the running of program. This method does not create a copy. - */ - static void SetWindows9xComspecSubstitute(const char*); - static const char* GetWindows9xComspecSubstitute(); - /** Windows if this is true, the CreateProcess in RunCommand will * not show new consol windows when running programs. */ @@ -488,8 +463,6 @@ private: static void* s_ErrorCallbackClientData; static void* s_StdoutCallbackClientData; static void* s_InterruptCallbackClientData; - - static std::string s_Windows9xComspecSubstitute; }; #endif diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index b6182ab..6e5e0ff 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1112,6 +1112,29 @@ void cmTarget::GetDirectLinkLibraries(const char *config, } //---------------------------------------------------------------------------- +void cmTarget::GetInterfaceLinkLibraries(const char *config, + std::vector<std::string> &libs, cmTarget *head) +{ + const char *prop = this->GetProperty("INTERFACE_LINK_LIBRARIES"); + if (prop) + { + cmListFileBacktrace lfbt; + cmGeneratorExpression ge(lfbt); + const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop); + + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + this->GetName(), + "INTERFACE_LINK_LIBRARIES", 0, 0); + cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile, + config, + false, + head, + &dagChecker), + libs); + } +} + +//---------------------------------------------------------------------------- std::string cmTarget::GetDebugGeneratorExpressions(const std::string &value, cmTarget::LinkLibraryType llt) { @@ -1990,7 +2013,6 @@ static void processIncludeDirectories(cmTarget *tgt, { case cmPolicies::WARN: { - cmOStringStream w; e << (mf->GetPolicies() ->GetPolicyWarning(cmPolicies::CMP0021)) << "\n"; messageType = cmake::AUTHOR_WARNING; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 3c36da7..e8f4e08 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -177,6 +177,9 @@ public: void GetDirectLinkLibraries(const char *config, std::vector<std::string> &, cmTarget *head); + void GetInterfaceLinkLibraries(const char *config, + std::vector<std::string> &, + cmTarget *head); /** Compute the link type to use for the given configuration. */ LinkLibraryType ComputeLinkType(const char* config); diff --git a/Source/cmWin32ProcessExecution.cxx b/Source/cmWin32ProcessExecution.cxx deleted file mode 100644 index 1bdeffb..0000000 --- a/Source/cmWin32ProcessExecution.cxx +++ /dev/null @@ -1,884 +0,0 @@ -/*============================================================================ - CMake - Cross Platform Makefile Generator - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium - - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ -#include "cmWin32ProcessExecution.h" - -#include "cmSystemTools.h" - -#include <malloc.h> -#include <io.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <windows.h> - -#if defined(__BORLANDC__) -# define STRICMP stricmp -# define TO_INTPTR(x) ((long)(x)) -#endif // Borland -#if defined(_MSC_VER) // Visual studio -# if ( _MSC_VER >= 1300 ) -# include <stddef.h> -# define TO_INTPTR(x) ((intptr_t)(x)) -# else // Visual Studio 6 -# define TO_INTPTR(x) ((long)(x)) -# endif // Visual studio .NET -# define STRICMP _stricmp -#endif // Visual Studio -#if defined(__MINGW32__) -# include <stdint.h> -# define TO_INTPTR(x) ((intptr_t)(x)) -# define STRICMP _stricmp -#endif // MinGW - -#define POPEN_1 1 -#define POPEN_2 2 -#define POPEN_3 3 -#define POPEN_4 4 - -#define cmMAX(x,y) (((x)<(y))?(y):(x)) - -void DisplayErrorMessage() -{ - LPVOID lpMsgBuf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL - ); - // Process any inserts in lpMsgBuf. - // ... - // Display the string. - MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION ); - // Free the buffer. - LocalFree( lpMsgBuf ); -} - -// Code from a Borland web site with the following explaination : -/* In this article, I will explain how to spawn a console application - * and redirect its standard input/output using anonymous pipes. An - * anonymous pipe is a pipe that goes only in one direction (read - * pipe, write pipe, etc.). Maybe you are asking, "why would I ever - * need to do this sort of thing?" One example would be a Windows - * telnet server, where you spawn a shell and listen on a port and - * send and receive data between the shell and the socket - * client. (Windows does not really have a built-in remote - * shell). First, we should talk about pipes. A pipe in Windows is - * simply a method of communication, often between process. The SDK - * defines a pipe as "a communication conduit with two ends; - a process - * with a handle to one end can communicate with a process having a - * handle to the other end." In our case, we are using "anonymous" - * pipes, one-way pipes that "transfer data between a parent process - * and a child process or between two child processes of the same - * parent process." It's easiest to imagine a pipe as its namesake. An - * actual pipe running between processes that can carry data. We are - * using anonymous pipes because the console app we are spawning is a - * child process. We use the CreatePipe function which will create an - * anonymous pipe and return a read handle and a write handle. We will - * create two pipes, on for stdin and one for stdout. We will then - * monitor the read end of the stdout pipe to check for display on our - * child process. Every time there is something availabe for reading, - * we will display it in our app. Consequently, we check for input in - * our app and send it off to the write end of the stdin pipe. */ - -inline bool IsWinNT() -//check if we're running NT -{ - OSVERSIONINFO osv; - osv.dwOSVersionInfoSize = sizeof(osv); - GetVersionEx(&osv); - return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT); -} - -//--------------------------------------------------------------------------- -bool cmWin32ProcessExecution::BorlandRunCommand( - const char* command, const char* dir, - std::string& output, int& retVal, bool verbose, int /* timeout */, - bool hideWindows) -{ - //verbose = true; - //std::cerr << std::endl - // << "WindowsRunCommand(" << command << ")" << std::endl - // << std::flush; - const int BUFFER_SIZE = 4096; - char buf[BUFFER_SIZE]; - -//i/o buffer - STARTUPINFO si; - SECURITY_ATTRIBUTES sa; - SECURITY_DESCRIPTOR sd; - -//security information for pipes - PROCESS_INFORMATION pi; - HANDLE newstdin,newstdout,read_stdout,write_stdin; - -//pipe handles - if (IsWinNT()) -//initialize security descriptor (Windows NT) - { - InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION); - SetSecurityDescriptorDacl(&sd, true, NULL, false); - sa.lpSecurityDescriptor = &sd; - - } - else sa.lpSecurityDescriptor = NULL; - sa.nLength = sizeof(SECURITY_ATTRIBUTES); - sa.bInheritHandle = true; - -//allow inheritable handles - if (!CreatePipe(&newstdin,&write_stdin,&sa,0)) -//create stdin pipe - { - return false; - } - if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) -//create stdout pipe - { - CloseHandle(newstdin); - CloseHandle(write_stdin); - return false; - - } - GetStartupInfo(&si); - -//set startupinfo for the spawned process - /* The dwFlags member tells CreateProcess how to make the - * process. STARTF_USESTDHANDLES validates the hStd* - * members. STARTF_USESHOWWINDOW validates the wShowWindow - * member. */ - - si.cb = sizeof(STARTUPINFO); - si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; - si.hStdOutput = newstdout; - si.hStdError = newstdout; - si.wShowWindow = SW_SHOWDEFAULT; - if(hideWindows) - { - si.wShowWindow = SW_HIDE; - } - -//set the new handles for the child process si.hStdInput = newstdin; - char* commandAndArgs = strcpy(new char[strlen(command)+1], command); - if (!CreateProcess(NULL,commandAndArgs,NULL,NULL,TRUE, - 0, // CREATE_NEW_CONSOLE, - NULL,dir,&si,&pi)) - { - std::cerr << "CreateProcess failed " << commandAndArgs << std::endl; - CloseHandle(newstdin); - CloseHandle(newstdout); - CloseHandle(read_stdout); - CloseHandle(write_stdin); - delete [] commandAndArgs; - return false; - - } - delete [] commandAndArgs; - unsigned long exit=0; - -//process exit code unsigned - unsigned long bread; - -//bytes read unsigned - unsigned long avail; - -//bytes available - memset(buf, 0, sizeof(buf)); - for(;;) -//main program loop - { - Sleep(10); -//check to see if there is any data to read from stdout - //std::cout << "Peek for data..." << std::endl; - PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL); - if (bread != 0) - { - memset(buf, 0, sizeof(buf)); - if (avail > 1023) - { - while (bread >= 1023) - { - //std::cout << "Read data..." << std::endl; - ReadFile(read_stdout,buf,1023,&bread,NULL); - - //read the stdout pipe - memset(buf, 0, sizeof(buf)); - output += buf; - if (verbose) - { - cmSystemTools::Stdout(buf); - } - } - } - else - { - ReadFile(read_stdout,buf,1023,&bread,NULL); - output += buf; - if(verbose) - { - cmSystemTools::Stdout(buf); - } - - } - - } - - //std::cout << "Check for process..." << std::endl; - GetExitCodeProcess(pi.hProcess,&exit); - -//while the process is running - if (exit != STILL_ACTIVE) break; - - } - WaitForSingleObject(pi.hProcess, INFINITE); - GetExitCodeProcess(pi.hProcess,&exit); - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); - CloseHandle(newstdin); - -//clean stuff up - CloseHandle(newstdout); - CloseHandle(read_stdout); - CloseHandle(write_stdin); - retVal = exit; - return true; - -} - -bool cmWin32ProcessExecution::StartProcess( - const char* cmd, const char* path, bool verbose) -{ - this->Initialize(); - this->Verbose = verbose; - return this->PrivateOpen(cmd, path, _O_RDONLY | _O_TEXT, POPEN_3); -} - -bool cmWin32ProcessExecution::Wait(int timeout) -{ - return this->PrivateClose(timeout); -} - -static BOOL RealPopenCreateProcess(const char *cmdstring, - const char *path, - const char *szConsoleSpawn, - HANDLE hStdin, - HANDLE hStdout, - HANDLE hStderr, - HANDLE *hProcess, - bool hideWindows, - std::string& output) -{ - PROCESS_INFORMATION piProcInfo; - STARTUPINFO siStartInfo; - char *s1=0,*s2=0; - const char *s3 = " /c "; - int i = GetEnvironmentVariable("COMSPEC",NULL,0); - if (i) - { - char *comshell; - - s1 = (char *)malloc(i); - int x = GetEnvironmentVariable("COMSPEC", s1, i); - if (!x) - { - free(s1); - return x; - } - - /* Explicitly check if we are using COMMAND.COM. If we are - * then use the w9xpopen hack. - */ - comshell = s1 + x; - while (comshell >= s1 && *comshell != '\\') - --comshell; - ++comshell; - - if (GetVersion() < 0x80000000 && - STRICMP(comshell, "command.com") != 0) - { - /* NT/2000 and not using command.com. */ - x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1; - s2 = (char *)malloc(x); - ZeroMemory(s2, x); - //sprintf(s2, "%s%s%s", s1, s3, cmdstring); - sprintf(s2, "%s", cmdstring); - } - else - { - /* - * Oh gag, we're on Win9x or using COMMAND.COM. Use - * the workaround listed in KB: Q150956 - */ - char modulepath[_MAX_PATH]; - struct stat statinfo; - GetModuleFileName(NULL, modulepath, sizeof(modulepath)); - for (i = x = 0; modulepath[i]; i++) - if (modulepath[i] == '\\') - x = i+1; - modulepath[x] = '\0'; - /* Create the full-name to w9xpopen, so we can test it exists */ - strncat(modulepath, - szConsoleSpawn, - (sizeof(modulepath)/sizeof(modulepath[0])) - -strlen(modulepath)); - if (stat(modulepath, &statinfo) != 0) - { - /* Eeek - file-not-found - possibly an embedding - situation - see if we can locate it in sys.prefix - */ - strncpy(modulepath, - ".", - sizeof(modulepath)/sizeof(modulepath[0])); - if (modulepath[strlen(modulepath)-1] != '\\') - strcat(modulepath, "\\"); - strncat(modulepath, - szConsoleSpawn, - (sizeof(modulepath)/sizeof(modulepath[0])) - -strlen(modulepath)); - /* No where else to look - raise an easily identifiable - error, rather than leaving Windows to report - "file not found" - as the user is probably blissfully - unaware this shim EXE is used, and it will confuse them. - (well, it confused me for a while ;-) - */ - if (stat(modulepath, &statinfo) != 0) - { - std::cout - << "Can not locate '" << modulepath - << "' which is needed " - "for popen to work with your shell " - "or platform." << std::endl; - free(s1); - free(s2); - return FALSE; - } - } - x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1 + - (int)strlen(modulepath) + - (int)strlen(szConsoleSpawn) + 1; - if(s2) - { - free(s2); - } - s2 = (char *)malloc(x); - ZeroMemory(s2, x); - sprintf( - s2, - "%s %s%s%s", - modulepath, - s1, - s3, - cmdstring); - sprintf( - s2, - "%s %s", - modulepath, - cmdstring); - } - } - - /* Could be an else here to try cmd.exe / command.com in the path - Now we'll just error out.. */ - else - { - std::cout << "Cannot locate a COMSPEC environment variable to " - << "use as the shell" << std::endl; - free(s2); - free(s1); - return FALSE; - } - - ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); - siStartInfo.cb = sizeof(STARTUPINFO); - siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; - siStartInfo.hStdInput = hStdin; - siStartInfo.hStdOutput = hStdout; - siStartInfo.hStdError = hStderr; - siStartInfo.wShowWindow = SW_SHOWDEFAULT; - if(hideWindows) - { - siStartInfo.wShowWindow = SW_HIDE; - } - - //std::cout << "Create process: " << s2 << std::endl; - if (CreateProcess(NULL, - s2, - NULL, - NULL, - TRUE, - 0, //CREATE_NEW_CONSOLE, - NULL, - path, - &siStartInfo, - &piProcInfo) ) - { - /* Close the handles now so anyone waiting is woken. */ - CloseHandle(piProcInfo.hThread); - /* Return process handle */ - *hProcess = piProcInfo.hProcess; - //std::cout << "Process created..." << std::endl; - free(s2); - free(s1); - return TRUE; - } - - output += "CreateProcessError: "; - { - /* Format the error message. */ - char message[1024]; - DWORD original = GetLastError(); - DWORD length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, 0, original, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - message, 1023, 0); - if(length < 1) - { - /* FormatMessage failed. Use a default message. */ - _snprintf(message, 1023, - "Process execution failed with error 0x%X. " - "FormatMessage failed with error 0x%X", - original, GetLastError()); - } - output += message; - } - output += "\n"; - output += "for command: "; - output += s2; - if(path) - { - output += "\nin dir: "; - output += path; - } - output += "\n"; - free(s2); - free(s1); - return FALSE; -} - -/* The following code is based off of KB: Q190351 */ - -bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring, - const char* path, - int mode, - int n) -{ - HANDLE hProcess; - - SECURITY_ATTRIBUTES saAttr; - BOOL fSuccess; - int fd1, fd2, fd3; - this->hChildStdinRd = 0; - this->hChildStdinWr = 0; - this->hChildStdoutRd = 0; - this->hChildStdoutWr = 0; - this->hChildStderrRd = 0; - this->hChildStderrWr = 0; - this->hChildStdinWrDup = 0; - this->hChildStdoutRdDup = 0; - this->hChildStderrRdDup = 0; - - saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); - saAttr.bInheritHandle = TRUE; - saAttr.lpSecurityDescriptor = NULL; - - fd1 = 0; - fd2 = 0; - fd3 = 0; - - if (!CreatePipe(&this->hChildStdinRd, &this->hChildStdinWr, &saAttr, 0)) - { - this->Output += "CreatePipeError\n"; - return false; - } - - /* Create new output read handle and the input write handle. Set - * the inheritance properties to FALSE. Otherwise, the child inherits - * these handles; resulting in non-closeable handles to the pipes - * being created. */ - fSuccess = DuplicateHandle(GetCurrentProcess(), this->hChildStdinWr, - GetCurrentProcess(), &this->hChildStdinWrDup, 0, - FALSE, - DUPLICATE_SAME_ACCESS); - if (!fSuccess) - { - this->Output += "DuplicateHandleError\n"; - return false; - } - - - /* Close the inheritable version of ChildStdin - that we're using. */ - CloseHandle(hChildStdinWr); - - if (!CreatePipe(&this->hChildStdoutRd, &this->hChildStdoutWr, &saAttr, 0)) - { - this->Output += "CreatePipeError\n"; - return false; - } - - fSuccess = DuplicateHandle(GetCurrentProcess(), this->hChildStdoutRd, - GetCurrentProcess(), &this->hChildStdoutRdDup, 0, - FALSE, DUPLICATE_SAME_ACCESS); - if (!fSuccess) - { - this->Output += "DuplicateHandleError\n"; - return false; - } - - /* Close the inheritable version of ChildStdout - that we're using. */ - CloseHandle(hChildStdoutRd); - - if (n != POPEN_4) - { - if (!CreatePipe(&this->hChildStderrRd, &this->hChildStderrWr, &saAttr, 0)) - { - this->Output += "CreatePipeError\n"; - return false; - } - fSuccess = DuplicateHandle(GetCurrentProcess(), - this->hChildStderrRd, - GetCurrentProcess(), - &this->hChildStderrRdDup, 0, - FALSE, DUPLICATE_SAME_ACCESS); - if (!fSuccess) - { - this->Output += "DuplicateHandleError\n"; - return false; - } - /* Close the inheritable version of ChildStdErr that we're using. */ - CloseHandle(hChildStderrRd); - - } - - switch (n) - { - case POPEN_1: - switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) - { - case _O_WRONLY | _O_TEXT: - /* Case for writing to child Stdin in text mode. */ - fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode); - /* We don't care about these pipes anymore, - so close them. */ - break; - - case _O_RDONLY | _O_TEXT: - /* Case for reading from child Stdout in text mode. */ - fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode); - /* We don't care about these pipes anymore, - so close them. */ - break; - - case _O_RDONLY | _O_BINARY: - /* Case for readinig from child Stdout in - binary mode. */ - fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode); - /* We don't care about these pipes anymore, - so close them. */ - break; - - case _O_WRONLY | _O_BINARY: - /* Case for writing to child Stdin in binary mode. */ - fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode); - /* We don't care about these pipes anymore, - so close them. */ - break; - } - break; - - case POPEN_2: - case POPEN_4: - //if ( 1 ) - { - fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode); - fd2 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode); - break; - } - - case POPEN_3: - //if ( 1) - { - fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode); - fd2 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode); - fd3 = _open_osfhandle(TO_INTPTR(this->hChildStderrRdDup), mode); - break; - } - } - - if (n == POPEN_4) - { - if (!RealPopenCreateProcess(cmdstring, - path, - this->ConsoleSpawn.c_str(), - this->hChildStdinRd, - this->hChildStdoutWr, - this->hChildStdoutWr, - &hProcess, this->HideWindows, - this->Output)) - { - if(fd1 >= 0) - { - close(fd1); - } - if(fd2 >= 0) - { - close(fd2); - } - if(fd3 >= 0) - { - close(fd3); - } - return 0; - } - } - else - { - if (!RealPopenCreateProcess(cmdstring, - path, - this->ConsoleSpawn.c_str(), - this->hChildStdinRd, - this->hChildStdoutWr, - this->hChildStderrWr, - &hProcess, this->HideWindows, - this->Output)) - { - if(fd1 >= 0) - { - close(fd1); - } - if(fd2 >= 0) - { - close(fd2); - } - if(fd3 >= 0) - { - close(fd3); - } - return 0; - } - } - - /* Child is launched. Close the parents copy of those pipe - * handles that only the child should have open. You need to - * make sure that no handles to the write end of the output pipe - * are maintained in this process or else the pipe will not close - * when the child process exits and the ReadFile will hang. */ - this->ProcessHandle = hProcess; - if ( fd1 >= 0 ) - { - this->pStdIn = fd1; - } - if ( fd2 >= 0 ) - { - this->pStdOut = fd2; - } - if ( fd3 >= 0 ) - { - this->pStdErr = fd3; - } - - return true; -} - -bool cmWin32ProcessExecution::CloseHandles() -{ - if(this->pStdErr != -1 ) - { - // this will close this as well: this->hChildStderrRdDup - _close(this->pStdErr); - this->pStdErr = -1; - this->hChildStderrRdDup = 0; - } - if(this->pStdIn != -1 ) - { - // this will close this as well: this->hChildStdinWrDup - _close(this->pStdIn); - this->pStdIn = -1; - this->hChildStdinWrDup = 0; - } - if(this->pStdOut != -1 ) - { - // this will close this as well: this->hChildStdoutRdDup - _close(this->pStdOut); - this->pStdOut = -1; - this->hChildStdoutRdDup = 0; - } - - bool ret = true; - if (this->hChildStdinRd && !CloseHandle(this->hChildStdinRd)) - { - ret = false; - } - this->hChildStdinRd = 0; - // now close these two - if (this->hChildStdoutWr && !CloseHandle(this->hChildStdoutWr)) - { - ret = false; - } - this->hChildStdoutWr = 0; - if (this->hChildStderrWr && !CloseHandle(this->hChildStderrWr)) - { - ret = false; - } - this->hChildStderrWr = 0; - return ret; -} -cmWin32ProcessExecution::~cmWin32ProcessExecution() -{ - this->CloseHandles(); -} - -bool cmWin32ProcessExecution::PrivateClose(int /* timeout */) -{ - HANDLE hProcess = this->ProcessHandle; - - int result = -1; - DWORD exit_code; - - std::string output = ""; - bool done = false; - while(!done) - { - Sleep(10); - bool have_some = false; - struct _stat fsout; - struct _stat fserr; - int rout = _fstat(this->pStdOut, &fsout); - int rerr = _fstat(this->pStdErr, &fserr); - if ( rout && rerr ) - { - break; - } - if (fserr.st_size > 0) - { - char buffer[1024]; - int len = read(this->pStdErr, buffer, 1023); - buffer[len] = 0; - if ( this->Verbose ) - { - cmSystemTools::Stdout(buffer); - } - output += buffer; - have_some = true; - } - if (fsout.st_size > 0) - { - char buffer[1024]; - int len = read(this->pStdOut, buffer, 1023); - buffer[len] = 0; - if ( this->Verbose ) - { - cmSystemTools::Stdout(buffer); - } - output += buffer; - have_some = true; - } - unsigned long exitCode; - if ( ! have_some ) - { - GetExitCodeProcess(hProcess,&exitCode); - if (exitCode != STILL_ACTIVE) - { - break; - } - } - } - - - if (WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED && - GetExitCodeProcess(hProcess, &exit_code)) - { - result = exit_code; - } - else - { - /* Indicate failure - this will cause the file object - * to raise an I/O error and translate the last Win32 - * error code from errno. We do have a problem with - * last errors that overlap the normal errno table, - * but that's a consistent problem with the file object. - */ - if (result != EOF) - { - /* If the error wasn't from the fclose(), then - * set errno for the file object error handling. - */ - errno = GetLastError(); - } - result = -1; - } - - /* Free up the native handle at this point */ - CloseHandle(hProcess); - this->ExitValue = result; - this->Output += output; - bool ret = this->CloseHandles(); - if ( result < 0 || !ret) - { - return false; - } - return true; -} - -int cmWin32ProcessExecution::Windows9xHack(const char* command) -{ - BOOL bRet; - STARTUPINFO si; - PROCESS_INFORMATION pi; - DWORD exit_code=0; - - if (!command) - { - cmSystemTools::Error("Windows9xHack: Command not specified"); - return 1; - } - - /* Make child process use this app's standard files. */ - ZeroMemory(&si, sizeof si); - si.cb = sizeof si; - si.dwFlags = STARTF_USESTDHANDLES; - si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); - si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); - si.hStdError = GetStdHandle(STD_ERROR_HANDLE); - - - char * app = 0; - char* cmd = new char[ strlen(command) + 1 ]; - strcpy(cmd, command); - - bRet = CreateProcess( - app, cmd, - 0, 0, - TRUE, 0, - 0, 0, - &si, &pi - ); - delete [] cmd; - - if (bRet) - { - if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED) - { - GetExitCodeProcess(pi.hProcess, &exit_code); - } - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - return exit_code; - } - - return 1; -} diff --git a/Source/cmWin32ProcessExecution.h b/Source/cmWin32ProcessExecution.h deleted file mode 100644 index 2127ebd2..0000000 --- a/Source/cmWin32ProcessExecution.h +++ /dev/null @@ -1,169 +0,0 @@ -/*============================================================================ - CMake - Cross Platform Makefile Generator - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium - - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ -#ifndef cmWin32ProcessExecution_h -#define cmWin32ProcessExecution_h - -#include "cmStandardIncludes.h" -#include "windows.h" - -class cmMakefile; - -/** \class cmWin32ProcessExecution - * \brief A process executor for windows - * - * cmWin32ProcessExecution is a class that provides a "clean" way of - * executing processes on Windows. It is modified code from Python 2.1 - * distribution. - * - * Portable 'popen' replacement for Win32. - * - * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks and 2.0 - * integration by Fredrik Lundh <fredrik@pythonware.com> Return code - * handling by David Bolen <db3l@fitlinxx.com>. - * - * Modified for CMake. - * - * For more information, please check Microsoft Knowledge Base - * Articles Q190351 and Q150956. - */ -class cmWin32ProcessExecution -{ -public: - cmWin32ProcessExecution() - { - this->HideWindows = false; - this->SetConsoleSpawn("w9xpopen.exe"); - this->Initialize(); - } - ~cmWin32ProcessExecution(); - ///! If true windows will be created hidden. - void SetHideWindows(bool v) { this->HideWindows = v; } - - /** - * Initialize the process execution datastructure. Do not call while - * running the process. - */ - void Initialize() - { - this->ProcessHandle = 0; - this->ExitValue = -1; - // Comment this out. Maybe we will need it in the future. - // file IO access to the process might be cool. - //this->StdIn = 0; - //this->StdOut = 0; - //this->StdErr = 0; - this->pStdIn = -1; - this->pStdOut = -1; - this->pStdErr = -1; - } - - /** - * Start the process in the directory path. Make sure that the - * executable is either in the path or specify the full path. The - * argument verbose specifies whether or not to display output while - * it is being generated. - */ - bool StartProcess(const char*, const char* path, bool verbose); - - /** - * Wait for the process to finish. If timeout is specified, it will - * break the process after timeout expires. (Timeout code is not yet - * implemented. - */ - bool Wait(int timeout); - - /** - * Get the output of the process (mixed stdout and stderr) as - * std::string. - */ - const std::string GetOutput() const { return this->Output; } - - /** - * Get the return value of the process. If the process is still - * running, the return value is -1. - */ - int GetExitValue() const { return this->ExitValue; } - - /** - * On Windows 9x there is a bug in the process execution code which - * may result in blocking. That is why this workaround is - * used. Specify the console spawn, which should run the - * Windows9xHack code. - */ - void SetConsoleSpawn(const char* prog) { this->ConsoleSpawn = prog; } - static int Windows9xHack(const char* command); - - /** Code from a Borland web site with the following explaination : - * In this article, I will explain how to spawn a console - * application and redirect its standard input/output using - * anonymous pipes. An anonymous pipe is a pipe that goes only in - * one direction (read pipe, write pipe, etc.). Maybe you are - * asking, "why would I ever need to do this sort of thing?" One - * example would be a Windows telnet server, where you spawn a shell - * and listen on a port and send and receive data between the shell - * and the socket client. (Windows does not really have a built-in - * remote shell). First, we should talk about pipes. A pipe in - * Windows is simply a method of communication, often between - * process. The SDK defines a pipe as "a communication conduit with - * two ends; a process with a handle to one end can communicate with - * a process having a handle to the other end." In our case, we are - * using "anonymous" pipes, one-way pipes that "transfer data - * between a parent process and a child process or between two child - * processes of the same parent process." It's easiest to imagine a - * pipe as its namesake. An actual pipe running between processes - * that can carry data. We are using anonymous pipes because the - * console app we are spawning is a child process. We use the - * CreatePipe function which will create an anonymous pipe and - * return a read handle and a write handle. We will create two - * pipes, on for stdin and one for stdout. We will then monitor the - * read end of the stdout pipe to check for display on our child - * process. Every time there is something availabe for reading, we - * will display it in our app. Consequently, we check for input in - * our app and send it off to the write end of the stdin pipe. - */ - static bool BorlandRunCommand(const char* command, - const char* dir, - std::string& output, int& retVal, - bool verbose, - int timeout, bool hideWindows); - -private: - bool CloseHandles(); - bool PrivateOpen(const char*, const char*, int, int); - bool PrivateClose(int timeout); - - HANDLE ProcessHandle; - HANDLE hChildStdinRd; - HANDLE hChildStdinWr; - HANDLE hChildStdoutRd; - HANDLE hChildStdoutWr; - HANDLE hChildStderrRd; - HANDLE hChildStderrWr; - HANDLE hChildStdinWrDup; - HANDLE hChildStdoutRdDup; - HANDLE hChildStderrRdDup; - - - int pStdIn; - int pStdOut; - int pStdErr; - - int ExitValue; - - std::string Output; - std::string ConsoleSpawn; - bool Verbose; - bool HideWindows; -}; - - -#endif diff --git a/Source/cmake.cxx b/Source/cmake.cxx index d11a40b..9c79516 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -1104,10 +1104,6 @@ int cmake::AddCMakePaths() ("CMAKE_ROOT", cMakeRoot.c_str(), "Path to CMake installation.", cmCacheManager::INTERNAL); -#ifdef _WIN32 - std::string comspec = "cmw9xcom.exe"; - cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str()); -#endif return 1; } diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 48d7d7b..9814aea 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -29,10 +29,6 @@ #include "cmVisualStudioWCEPlatformParser.h" #endif -#if defined(_WIN32) && !defined(__CYGWIN__) -# include "cmWin32ProcessExecution.h" -#endif - #include <time.h> #include <stdlib.h> // required for atoi @@ -79,7 +75,6 @@ void CMakeCommandUsage(const char* program) << " touch_nocreate file - touch a file but do not create it.\n" #if defined(_WIN32) && !defined(__CYGWIN__) << "Available on Windows only:\n" - << " comspec - on windows 9x use this for RunCommand\n" << " delete_regv key - delete registry value\n" << " env_vs8_wince sdkname - displays a batch file which sets the " "environment for the provided Windows CE SDK installed in VS2005\n" @@ -743,13 +738,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) // Remove file else if (args[1] == "comspec" && args.size() > 2) { - unsigned int cc; - std::string command = args[2]; - for ( cc = 3; cc < args.size(); cc ++ ) - { - command += " " + args[cc]; - } - return cmWin32ProcessExecution::Windows9xHack(command.c_str()); + std::cerr << "Win9x helper \"cmake -E comspec\" no longer supported\n"; + return 1; } else if (args[1] == "env_vs8_wince" && args.size() == 3) { diff --git a/Source/cmw9xcom.cxx b/Source/cmw9xcom.cxx deleted file mode 100644 index ab238d5..0000000 --- a/Source/cmw9xcom.cxx +++ /dev/null @@ -1,45 +0,0 @@ -/*============================================================================ - CMake - Cross Platform Makefile Generator - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium - - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ -#include "cmSystemTools.h" -#include "cmWin32ProcessExecution.h" - -// this is a test driver program for cmake. -int main (int argc, char *argv[]) -{ - cmSystemTools::EnableMSVCDebugHook(); - if ( argc <= 1 ) - { - std::cerr << "Usage: " << argv[0] << " executable" << std::endl; - return 1; - } - std::string arg = argv[1]; - if ( (arg.find_first_of(" ") != arg.npos) && - (arg.find_first_of("\"") == arg.npos) ) - { - arg = "\"" + arg + "\""; - } - std::string command = arg; - int cc; - for ( cc = 2; cc < argc; cc ++ ) - { - std::string nextArg = argv[cc]; - if ( (nextArg.find_first_of(" ") != nextArg.npos) && - (nextArg.find_first_of("\"") == nextArg.npos) ) - { - nextArg = "\"" + nextArg + "\""; - } - command += " "; - command += nextArg; - } - - return cmWin32ProcessExecution::Windows9xHack(command.c_str()); -} diff --git a/Source/ctest.cxx b/Source/ctest.cxx index 16cdd13..12e71b6 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -171,10 +171,6 @@ int main (int argc, char *argv[]) } } -#ifdef _WIN32 - std::string comspec = "cmw9xcom.exe"; - cmSystemTools::SetWindows9xComspecSubstitute(comspec.c_str()); -#endif // copy the args to a vector std::vector<std::string> args; for(int i =0; i < argc; ++i) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 7dee86a..b9c99e3 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -261,6 +261,23 @@ if(BUILD_TESTING) PASS_REGULAR_EXPRESSION "(file is not of required architecture|does not match cputype|not the architecture being linked)") endif() + if(CMAKE_TEST_GENERATOR MATCHES Make) + set(InterfaceBuildTargets_libname testlib) + if (CMAKE_TEST_GENERATOR MATCHES "Borland|Watcom") + set(InterfaceBuildTargets_libname testlib.lib) + endif() + add_test(InterfaceBuildTargets ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/InterfaceBuildTargets" + "${CMake_BINARY_DIR}/Tests/InterfaceBuildTargets" + --build-two-config + ${build_generator_args} + --build-project InterfaceBuildTargets + --test-command ${CMAKE_CMAKE_COMMAND} -E touch_nocreate ${InterfaceBuildTargets_libname} + ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/InterfaceBuildTargets") + endif() + list(APPEND TEST_BUILD_DIRS ${CMake_TEST_INSTALL_PREFIX}) if(NOT QT4_FOUND) diff --git a/Tests/InterfaceBuildTargets/CMakeLists.txt b/Tests/InterfaceBuildTargets/CMakeLists.txt new file mode 100644 index 0000000..a00e5d5 --- /dev/null +++ b/Tests/InterfaceBuildTargets/CMakeLists.txt @@ -0,0 +1,13 @@ +project(InterfaceBuildTargets) + +add_library(testlib EXCLUDE_FROM_ALL testlib.cxx) +set_property(TARGET testlib PROPERTY PREFIX "") +if(CMAKE_GENERATOR MATCHES "Borland|Watcom") + # These librarians add the .lib suffix anyway. + set_property(TARGET testlib PROPERTY SUFFIX ".lib") +else() + set_property(TARGET testlib PROPERTY SUFFIX "") +endif() + +add_library(iface INTERFACE) +target_link_libraries(iface INTERFACE testlib) diff --git a/Tests/InterfaceBuildTargets/main.cxx b/Tests/InterfaceBuildTargets/main.cxx new file mode 100644 index 0000000..e9ad257 --- /dev/null +++ b/Tests/InterfaceBuildTargets/main.cxx @@ -0,0 +1,5 @@ + +int main(int, char**) +{ + return 0; +} diff --git a/Tests/InterfaceBuildTargets/testlib.cxx b/Tests/InterfaceBuildTargets/testlib.cxx new file mode 100644 index 0000000..02bd6b0 --- /dev/null +++ b/Tests/InterfaceBuildTargets/testlib.cxx @@ -0,0 +1,5 @@ + +void testlib(void) +{ + +} diff --git a/Tests/RunCMake/CMP0026/CMakeLists.txt b/Tests/RunCMake/CMP0026/CMakeLists.txt index e8db6b0..12cd3c7 100644 --- a/Tests/RunCMake/CMP0026/CMakeLists.txt +++ b/Tests/RunCMake/CMP0026/CMakeLists.txt @@ -1,3 +1,3 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.4) project(${RunCMake_TEST} NONE) include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/Syntax/.gitattributes b/Tests/RunCMake/Syntax/.gitattributes index fc9ebff..35a9eaf 100644 --- a/Tests/RunCMake/Syntax/.gitattributes +++ b/Tests/RunCMake/Syntax/.gitattributes @@ -1 +1,3 @@ CommandTabs.cmake whitespace=-tab-in-indent +StringCRLF.cmake whitespace=cr-at-eol -crlf +BracketCRLF.cmake whitespace=cr-at-eol -crlf diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-BE-result.txt b/Tests/RunCMake/Syntax/BOM-UTF-16-BE-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/BOM-UTF-16-BE-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt new file mode 100644 index 0000000..b3f1e47 --- /dev/null +++ b/Tests/RunCMake/Syntax/BOM-UTF-16-BE-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at CMakeLists.txt:3 \(include\): + File + + .*/Tests/RunCMake/Syntax/BOM-UTF-16-BE.cmake + + starts with a Byte-Order-Mark that is not UTF-8. diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-BE.cmake b/Tests/RunCMake/Syntax/BOM-UTF-16-BE.cmake Binary files differnew file mode 100644 index 0000000..c51f6e6 --- /dev/null +++ b/Tests/RunCMake/Syntax/BOM-UTF-16-BE.cmake diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-LE-result.txt b/Tests/RunCMake/Syntax/BOM-UTF-16-LE-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/BOM-UTF-16-LE-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt new file mode 100644 index 0000000..c08c902 --- /dev/null +++ b/Tests/RunCMake/Syntax/BOM-UTF-16-LE-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at CMakeLists.txt:3 \(include\): + File + + .*/Tests/RunCMake/Syntax/BOM-UTF-16-LE.cmake + + starts with a Byte-Order-Mark that is not UTF-8. diff --git a/Tests/RunCMake/Syntax/BOM-UTF-16-LE.cmake b/Tests/RunCMake/Syntax/BOM-UTF-16-LE.cmake Binary files differnew file mode 100644 index 0000000..b57446f --- /dev/null +++ b/Tests/RunCMake/Syntax/BOM-UTF-16-LE.cmake diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-BE-result.txt b/Tests/RunCMake/Syntax/BOM-UTF-32-BE-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/BOM-UTF-32-BE-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt new file mode 100644 index 0000000..5dde4e3 --- /dev/null +++ b/Tests/RunCMake/Syntax/BOM-UTF-32-BE-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at CMakeLists.txt:3 \(include\): + File + + .*/Tests/RunCMake/Syntax/BOM-UTF-32-BE.cmake + + starts with a Byte-Order-Mark that is not UTF-8. diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-BE.cmake b/Tests/RunCMake/Syntax/BOM-UTF-32-BE.cmake Binary files differnew file mode 100644 index 0000000..23c57f3 --- /dev/null +++ b/Tests/RunCMake/Syntax/BOM-UTF-32-BE.cmake diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-LE-result.txt b/Tests/RunCMake/Syntax/BOM-UTF-32-LE-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/BOM-UTF-32-LE-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt b/Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt new file mode 100644 index 0000000..eb054ec --- /dev/null +++ b/Tests/RunCMake/Syntax/BOM-UTF-32-LE-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at CMakeLists.txt:3 \(include\): + File + + .*/Tests/RunCMake/Syntax/BOM-UTF-32-LE.cmake + + starts with a Byte-Order-Mark that is not UTF-8. diff --git a/Tests/RunCMake/Syntax/BOM-UTF-32-LE.cmake b/Tests/RunCMake/Syntax/BOM-UTF-32-LE.cmake Binary files differnew file mode 100644 index 0000000..c330f5b --- /dev/null +++ b/Tests/RunCMake/Syntax/BOM-UTF-32-LE.cmake diff --git a/Tests/RunCMake/Syntax/BOM-UTF-8-stdout.txt b/Tests/RunCMake/Syntax/BOM-UTF-8-stdout.txt new file mode 100644 index 0000000..5776d6e --- /dev/null +++ b/Tests/RunCMake/Syntax/BOM-UTF-8-stdout.txt @@ -0,0 +1 @@ +-- message diff --git a/Tests/RunCMake/Syntax/BOM-UTF-8.cmake b/Tests/RunCMake/Syntax/BOM-UTF-8.cmake new file mode 100644 index 0000000..bdff83b --- /dev/null +++ b/Tests/RunCMake/Syntax/BOM-UTF-8.cmake @@ -0,0 +1 @@ +message(STATUS "message") diff --git a/Tests/RunCMake/Syntax/Bracket0-stderr.txt b/Tests/RunCMake/Syntax/Bracket0-stderr.txt new file mode 100644 index 0000000..39cc2bc --- /dev/null +++ b/Tests/RunCMake/Syntax/Bracket0-stderr.txt @@ -0,0 +1 @@ +^1 \${var} \\n 4$ diff --git a/Tests/RunCMake/Syntax/Bracket0.cmake b/Tests/RunCMake/Syntax/Bracket0.cmake new file mode 100644 index 0000000..4bc0172 --- /dev/null +++ b/Tests/RunCMake/Syntax/Bracket0.cmake @@ -0,0 +1 @@ +message([[1 ${var} \n 4]]) diff --git a/Tests/RunCMake/Syntax/Bracket1-stderr.txt b/Tests/RunCMake/Syntax/Bracket1-stderr.txt new file mode 100644 index 0000000..e1e13c1 --- /dev/null +++ b/Tests/RunCMake/Syntax/Bracket1-stderr.txt @@ -0,0 +1 @@ +^1 \${var} \\n 4\]==$ diff --git a/Tests/RunCMake/Syntax/Bracket1.cmake b/Tests/RunCMake/Syntax/Bracket1.cmake new file mode 100644 index 0000000..587a575 --- /dev/null +++ b/Tests/RunCMake/Syntax/Bracket1.cmake @@ -0,0 +1,2 @@ +message([==[1 ]==] [=[ +${var} \n 4]==]=]) diff --git a/Tests/RunCMake/Syntax/Bracket2-stdout.txt b/Tests/RunCMake/Syntax/Bracket2-stdout.txt new file mode 100644 index 0000000..0f8aa2f --- /dev/null +++ b/Tests/RunCMake/Syntax/Bracket2-stdout.txt @@ -0,0 +1,2 @@ +-- Bracket Argument 1 +-- Bracket Argument 2 diff --git a/Tests/RunCMake/Syntax/Bracket2.cmake b/Tests/RunCMake/Syntax/Bracket2.cmake new file mode 100644 index 0000000..5c5feed --- /dev/null +++ b/Tests/RunCMake/Syntax/Bracket2.cmake @@ -0,0 +1,2 @@ +message(STATUS [[Bracket Argument 1]] #[[Bracket Comment 1]]) +message(STATUS #[[Bracket Comment 2]] [[Bracket Argument 2]]) diff --git a/Tests/RunCMake/Syntax/BracketBackslash-result.txt b/Tests/RunCMake/Syntax/BracketBackslash-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketBackslash-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/BracketBackslash-stderr.txt b/Tests/RunCMake/Syntax/BracketBackslash-stderr.txt new file mode 100644 index 0000000..b746953 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketBackslash-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at BracketBackslash.cmake:1 \(message\): + a\\ + + b +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/Syntax/BracketBackslash.cmake b/Tests/RunCMake/Syntax/BracketBackslash.cmake new file mode 100644 index 0000000..5478e5d --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketBackslash.cmake @@ -0,0 +1,2 @@ +message(FATAL_ERROR [==[a\ +b]==]) diff --git a/Tests/RunCMake/Syntax/BracketCRLF-stderr.txt b/Tests/RunCMake/Syntax/BracketCRLF-stderr.txt new file mode 100644 index 0000000..7aef26e --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketCRLF-stderr.txt @@ -0,0 +1 @@ +CRLF->LF worked diff --git a/Tests/RunCMake/Syntax/BracketCRLF.cmake b/Tests/RunCMake/Syntax/BracketCRLF.cmake new file mode 100644 index 0000000..bda0e17 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketCRLF.cmake @@ -0,0 +1,8 @@ +if([[
+]] STREQUAL "" AND
+[[a
+b]] STREQUAL "a\nb")
+ message("CRLF->LF worked")
+else()
+ message(FATAL_ERROR "CRLF->LF failed")
+endif()
diff --git a/Tests/RunCMake/Syntax/BracketComment0-stdout.txt b/Tests/RunCMake/Syntax/BracketComment0-stdout.txt new file mode 100644 index 0000000..c9c0be4 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment0-stdout.txt @@ -0,0 +1 @@ +-- The above FATAL_ERROR did not occur. diff --git a/Tests/RunCMake/Syntax/BracketComment0.cmake b/Tests/RunCMake/Syntax/BracketComment0.cmake new file mode 100644 index 0000000..0ee95de --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment0.cmake @@ -0,0 +1,5 @@ +#[=[ +#]] +message(FATAL_ERROR "This is commented out.") +#]==]=] +message(STATUS "The above FATAL_ERROR did not occur.") diff --git a/Tests/RunCMake/Syntax/BracketComment1-result.txt b/Tests/RunCMake/Syntax/BracketComment1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/BracketComment1-stderr.txt b/Tests/RunCMake/Syntax/BracketComment1-stderr.txt new file mode 100644 index 0000000..a9373de --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment1-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at BracketComment1.cmake:2 \(message\): + This is not commented out. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/Syntax/BracketComment1.cmake b/Tests/RunCMake/Syntax/BracketComment1.cmake new file mode 100644 index 0000000..2ec9d20 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment1.cmake @@ -0,0 +1,3 @@ +##[[ +message(FATAL_ERROR "This is not commented out.") +#]] diff --git a/Tests/RunCMake/Syntax/BracketComment2-result.txt b/Tests/RunCMake/Syntax/BracketComment2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/BracketComment2-stderr.txt b/Tests/RunCMake/Syntax/BracketComment2-stderr.txt new file mode 100644 index 0000000..7e98222 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment2-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at BracketComment2.cmake:2 \(message\): + This is not commented out. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/Syntax/BracketComment2.cmake b/Tests/RunCMake/Syntax/BracketComment2.cmake new file mode 100644 index 0000000..3eda32d --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment2.cmake @@ -0,0 +1,3 @@ +# [[ +message(FATAL_ERROR "This is not commented out.") +#]] diff --git a/Tests/RunCMake/Syntax/BracketComment3-stdout.txt b/Tests/RunCMake/Syntax/BracketComment3-stdout.txt new file mode 100644 index 0000000..c9c0be4 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment3-stdout.txt @@ -0,0 +1 @@ +-- The above FATAL_ERROR did not occur. diff --git a/Tests/RunCMake/Syntax/BracketComment3.cmake b/Tests/RunCMake/Syntax/BracketComment3.cmake new file mode 100644 index 0000000..ffd03a9 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment3.cmake @@ -0,0 +1,4 @@ +#[[Text on opening line +message(FATAL_ERROR "This is commented out.") +#]=]] +message(STATUS "The above FATAL_ERROR did not occur.") diff --git a/Tests/RunCMake/Syntax/BracketComment4-result.txt b/Tests/RunCMake/Syntax/BracketComment4-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment4-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/BracketComment4-stderr.txt b/Tests/RunCMake/Syntax/BracketComment4-stderr.txt new file mode 100644 index 0000000..8ba32c2 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment4-stderr.txt @@ -0,0 +1,7 @@ +CMake Error: Error in cmake code at +.*/Tests/RunCMake/Syntax/BracketComment4.cmake:3: +Parse error. Expected a newline, got identifier with text "message". +CMake Error at CMakeLists.txt:3 \(include\): + include could not find load file: + + BracketComment4.cmake diff --git a/Tests/RunCMake/Syntax/BracketComment4.cmake b/Tests/RunCMake/Syntax/BracketComment4.cmake new file mode 100644 index 0000000..9d586f1 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment4.cmake @@ -0,0 +1,3 @@ +#[[ +message(FATAL_ERROR "This is commented out.") +#]] message(STATUS "This command not allowed here") diff --git a/Tests/RunCMake/Syntax/BracketComment5-stdout.txt b/Tests/RunCMake/Syntax/BracketComment5-stdout.txt new file mode 100644 index 0000000..c9c0be4 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment5-stdout.txt @@ -0,0 +1 @@ +-- The above FATAL_ERROR did not occur. diff --git a/Tests/RunCMake/Syntax/BracketComment5.cmake b/Tests/RunCMake/Syntax/BracketComment5.cmake new file mode 100644 index 0000000..bb6d9f3 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketComment5.cmake @@ -0,0 +1,6 @@ +#[[ +message(FATAL_ERROR "This is commented out.") +#]] #[[ +message(FATAL_ERROR "This is commented out.") +#]] #message(FATAL_ERROR "This is commented out.") +message(STATUS "The above FATAL_ERROR did not occur.") diff --git a/Tests/RunCMake/Syntax/BracketNoSpace0-result.txt b/Tests/RunCMake/Syntax/BracketNoSpace0-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace0-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt new file mode 100644 index 0000000..afd91f9 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace0-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at CMakeLists.txt:3 \(include\): + Syntax Error in cmake code at + + .*/Tests/RunCMake/Syntax/BracketNoSpace0.cmake:1:27 + + Argument not separated from preceding token by whitespace. diff --git a/Tests/RunCMake/Syntax/BracketNoSpace0.cmake b/Tests/RunCMake/Syntax/BracketNoSpace0.cmake new file mode 100644 index 0000000..1de1450 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace0.cmake @@ -0,0 +1 @@ +message(STATUS [[bracket]]unquoted) diff --git a/Tests/RunCMake/Syntax/BracketNoSpace1-result.txt b/Tests/RunCMake/Syntax/BracketNoSpace1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt new file mode 100644 index 0000000..826e511 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace1-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at CMakeLists.txt:3 \(include\): + Syntax Error in cmake code at + + .*/Tests/RunCMake/Syntax/BracketNoSpace1.cmake:1:24 + + Argument not separated from preceding token by whitespace. diff --git a/Tests/RunCMake/Syntax/BracketNoSpace1.cmake b/Tests/RunCMake/Syntax/BracketNoSpace1.cmake new file mode 100644 index 0000000..7982bf3 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace1.cmake @@ -0,0 +1 @@ +message(STATUS "string"[[bracket]]) diff --git a/Tests/RunCMake/Syntax/BracketNoSpace2-result.txt b/Tests/RunCMake/Syntax/BracketNoSpace2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt new file mode 100644 index 0000000..23ecdcd --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace2-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at CMakeLists.txt:3 \(include\): + Syntax Error in cmake code at + + .*/Tests/RunCMake/Syntax/BracketNoSpace2.cmake:1:44 + + Argument not separated from preceding token by whitespace. diff --git a/Tests/RunCMake/Syntax/BracketNoSpace2.cmake b/Tests/RunCMake/Syntax/BracketNoSpace2.cmake new file mode 100644 index 0000000..f1507f3 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace2.cmake @@ -0,0 +1 @@ +message(STATUS "string"#[[bracket comment]][[bracket]]) diff --git a/Tests/RunCMake/Syntax/BracketNoSpace3-result.txt b/Tests/RunCMake/Syntax/BracketNoSpace3-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt new file mode 100644 index 0000000..906d6fc --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace3-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at CMakeLists.txt:3 \(include\): + Syntax Error in cmake code at + + .*/Tests/RunCMake/Syntax/BracketNoSpace3.cmake:1:45 + + Argument not separated from preceding token by whitespace. diff --git a/Tests/RunCMake/Syntax/BracketNoSpace3.cmake b/Tests/RunCMake/Syntax/BracketNoSpace3.cmake new file mode 100644 index 0000000..45dc900 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace3.cmake @@ -0,0 +1 @@ +message(STATUS "string" #[[bracket comment]][[bracket]]) diff --git a/Tests/RunCMake/Syntax/BracketNoSpace4-result.txt b/Tests/RunCMake/Syntax/BracketNoSpace4-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace4-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt new file mode 100644 index 0000000..a461e93 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace4-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at CMakeLists.txt:3 \(include\): + Syntax Error in cmake code at + + .*/Tests/RunCMake/Syntax/BracketNoSpace4.cmake:1:44 + + Argument not separated from preceding token by whitespace. diff --git a/Tests/RunCMake/Syntax/BracketNoSpace4.cmake b/Tests/RunCMake/Syntax/BracketNoSpace4.cmake new file mode 100644 index 0000000..cb4ddbe --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace4.cmake @@ -0,0 +1 @@ +message(STATUS "string"#[[bracket comment]]"string") diff --git a/Tests/RunCMake/Syntax/BracketNoSpace5-result.txt b/Tests/RunCMake/Syntax/BracketNoSpace5-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace5-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt b/Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt new file mode 100644 index 0000000..ff8bf1c --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace5-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at CMakeLists.txt:3 \(include\): + Syntax Error in cmake code at + + .*/Tests/RunCMake/Syntax/BracketNoSpace5.cmake:1:45 + + Argument not separated from preceding token by whitespace. diff --git a/Tests/RunCMake/Syntax/BracketNoSpace5.cmake b/Tests/RunCMake/Syntax/BracketNoSpace5.cmake new file mode 100644 index 0000000..c684523 --- /dev/null +++ b/Tests/RunCMake/Syntax/BracketNoSpace5.cmake @@ -0,0 +1 @@ +message(STATUS "string" #[[bracket comment]]"string") diff --git a/Tests/RunCMake/Syntax/BracketWarn-stderr.txt b/Tests/RunCMake/Syntax/BracketWarn-stderr.txt deleted file mode 100644 index 4a9cca6..0000000 --- a/Tests/RunCMake/Syntax/BracketWarn-stderr.txt +++ /dev/null @@ -1,35 +0,0 @@ -CMake Warning \(dev\) at CMakeLists.txt:3 \(include\): - Syntax Warning in cmake code at - - .*/Tests/RunCMake/Syntax/BracketWarn.cmake:1:16 - - A future version of CMake may treat unquoted argument: - - \[\[ - - as an opening long bracket. Double-quote the argument. -This warning is for project developers. Use -Wno-dev to suppress it. - -CMake Warning \(dev\) at CMakeLists.txt:3 \(include\): - Syntax Warning in cmake code at - - .*/Tests/RunCMake/Syntax/BracketWarn.cmake:1:19 - - A future version of CMake may treat unquoted argument: - - \[=\[ - - as an opening long bracket. Double-quote the argument. -This warning is for project developers. Use -Wno-dev to suppress it. - -CMake Warning \(dev\) at CMakeLists.txt:3 \(include\): - Syntax Warning in cmake code at - - .*/Tests/RunCMake/Syntax/BracketWarn.cmake:1:27 - - A future version of CMake may treat unquoted argument: - - \[==\[x - - as an opening long bracket. Double-quote the argument. -This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/Syntax/BracketWarn-stdout.txt b/Tests/RunCMake/Syntax/BracketWarn-stdout.txt deleted file mode 100644 index 01b2caa..0000000 --- a/Tests/RunCMake/Syntax/BracketWarn-stdout.txt +++ /dev/null @@ -1 +0,0 @@ --- \[\[\[=\[\[=x\[==\[x diff --git a/Tests/RunCMake/Syntax/BracketWarn.cmake b/Tests/RunCMake/Syntax/BracketWarn.cmake deleted file mode 100644 index 8f33946..0000000 --- a/Tests/RunCMake/Syntax/BracketWarn.cmake +++ /dev/null @@ -1 +0,0 @@ -message(STATUS [[ [=[ [=x [==[x) diff --git a/Tests/RunCMake/Syntax/CommandError2-result.txt b/Tests/RunCMake/Syntax/CommandError2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/CommandError2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/CommandError2-stderr.txt b/Tests/RunCMake/Syntax/CommandError2-stderr.txt new file mode 100644 index 0000000..f4dfc77 --- /dev/null +++ b/Tests/RunCMake/Syntax/CommandError2-stderr.txt @@ -0,0 +1,7 @@ +CMake Error: Error in cmake code at +.*/Tests/RunCMake/Syntax/CommandError2.cmake:1: +Parse error. Expected a command name, got bracket argument with text "oops-not-a-comment". +CMake Error at CMakeLists.txt:3 \(include\): + include could not find load file: + + CommandError2.cmake diff --git a/Tests/RunCMake/Syntax/CommandError2.cmake b/Tests/RunCMake/Syntax/CommandError2.cmake new file mode 100644 index 0000000..a269682 --- /dev/null +++ b/Tests/RunCMake/Syntax/CommandError2.cmake @@ -0,0 +1 @@ +message("Example Message") [[oops-not-a-comment]] diff --git a/Tests/RunCMake/Syntax/OneLetter-stderr.txt b/Tests/RunCMake/Syntax/OneLetter-stderr.txt new file mode 100644 index 0000000..87c01c7 --- /dev/null +++ b/Tests/RunCMake/Syntax/OneLetter-stderr.txt @@ -0,0 +1 @@ +message diff --git a/Tests/RunCMake/Syntax/OneLetter.cmake b/Tests/RunCMake/Syntax/OneLetter.cmake new file mode 100644 index 0000000..3c341fa --- /dev/null +++ b/Tests/RunCMake/Syntax/OneLetter.cmake @@ -0,0 +1,7 @@ +function(f) + g(${ARGN}) +endfunction() +macro(g) + message(${ARGN}) +endmacro() +f(message) diff --git a/Tests/RunCMake/Syntax/ParenNoSpace0-stdout.txt b/Tests/RunCMake/Syntax/ParenNoSpace0-stdout.txt new file mode 100644 index 0000000..5c4076f --- /dev/null +++ b/Tests/RunCMake/Syntax/ParenNoSpace0-stdout.txt @@ -0,0 +1,3 @@ +-- \(unquoted\) +-- \(quoted\) +-- \(bracket\) diff --git a/Tests/RunCMake/Syntax/ParenNoSpace0.cmake b/Tests/RunCMake/Syntax/ParenNoSpace0.cmake new file mode 100644 index 0000000..175fe4a --- /dev/null +++ b/Tests/RunCMake/Syntax/ParenNoSpace0.cmake @@ -0,0 +1,3 @@ +message(STATUS (unquoted)) +message(STATUS ("quoted")) +message(STATUS ([[bracket]])) diff --git a/Tests/RunCMake/Syntax/ParenNoSpace1-result.txt b/Tests/RunCMake/Syntax/ParenNoSpace1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/ParenNoSpace1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt b/Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt new file mode 100644 index 0000000..64ef8b1 --- /dev/null +++ b/Tests/RunCMake/Syntax/ParenNoSpace1-stderr.txt @@ -0,0 +1,22 @@ +CMake Warning \(dev\) at CMakeLists.txt:3 \(include\): + Syntax Warning in cmake code at + + .*/Tests/RunCMake/Syntax/ParenNoSpace1.cmake:1:26 + + Argument not separated from preceding token by whitespace. +This warning is for project developers. Use -Wno-dev to suppress it. + +CMake Warning \(dev\) at CMakeLists.txt:3 \(include\): + Syntax Warning in cmake code at + + .*/Tests/RunCMake/Syntax/ParenNoSpace1.cmake:2:26 + + Argument not separated from preceding token by whitespace. +This warning is for project developers. Use -Wno-dev to suppress it. + +CMake Error at CMakeLists.txt:3 \(include\): + Syntax Error in cmake code at + + .*/Tests/RunCMake/Syntax/ParenNoSpace1.cmake:3:29 + + Argument not separated from preceding token by whitespace. diff --git a/Tests/RunCMake/Syntax/ParenNoSpace1.cmake b/Tests/RunCMake/Syntax/ParenNoSpace1.cmake new file mode 100644 index 0000000..550339a --- /dev/null +++ b/Tests/RunCMake/Syntax/ParenNoSpace1.cmake @@ -0,0 +1,3 @@ +message(STATUS (unquoted)unquoted) +message(STATUS ("quoted")"quoted") +message(STATUS ([[bracket]])[[bracket]]) diff --git a/Tests/RunCMake/Syntax/ParenNoSpace-stderr.txt b/Tests/RunCMake/Syntax/ParenNoSpace2-stderr.txt index 10f3293..10f3293 100644 --- a/Tests/RunCMake/Syntax/ParenNoSpace-stderr.txt +++ b/Tests/RunCMake/Syntax/ParenNoSpace2-stderr.txt diff --git a/Tests/RunCMake/Syntax/ParenNoSpace-stdout.txt b/Tests/RunCMake/Syntax/ParenNoSpace2-stdout.txt index 72addd7..0e657b9 100644 --- a/Tests/RunCMake/Syntax/ParenNoSpace-stdout.txt +++ b/Tests/RunCMake/Syntax/ParenNoSpace2-stdout.txt @@ -1,2 +1,3 @@ -- unquoted\(unquoted\) -- quoted\(quoted\) +-- bracket\(bracket\) diff --git a/Tests/RunCMake/Syntax/ParenNoSpace.cmake b/Tests/RunCMake/Syntax/ParenNoSpace2.cmake index c690d96..c46a887 100644 --- a/Tests/RunCMake/Syntax/ParenNoSpace.cmake +++ b/Tests/RunCMake/Syntax/ParenNoSpace2.cmake @@ -1,2 +1,3 @@ message(STATUS unquoted(unquoted)) message(STATUS "quoted"("quoted")) +message(STATUS [[bracket]]([[bracket]])) diff --git a/Tests/RunCMake/Syntax/RunCMakeTest.cmake b/Tests/RunCMake/Syntax/RunCMakeTest.cmake index 94963f3..f5e0d11 100644 --- a/Tests/RunCMake/Syntax/RunCMakeTest.cmake +++ b/Tests/RunCMake/Syntax/RunCMakeTest.cmake @@ -1,18 +1,47 @@ include(RunCMake) +run_cmake(BOM-UTF-8) +run_cmake(BOM-UTF-16-LE) +run_cmake(BOM-UTF-16-BE) +run_cmake(BOM-UTF-32-LE) +run_cmake(BOM-UTF-32-BE) run_cmake(CommandSpaces) run_cmake(CommandTabs) run_cmake(CommandNewlines) run_cmake(CommandComments) run_cmake(CommandError0) run_cmake(CommandError1) +run_cmake(CommandError2) run_cmake(String0) run_cmake(String1) +run_cmake(StringCRLF) run_cmake(StringNoSpace) +run_cmake(OneLetter) run_cmake(Unquoted0) run_cmake(Unquoted1) -run_cmake(ParenNoSpace) +run_cmake(Bracket0) +run_cmake(Bracket1) +run_cmake(Bracket2) +run_cmake(BracketBackslash) +run_cmake(BracketCRLF) +run_cmake(BracketComment0) +run_cmake(BracketComment1) +run_cmake(BracketComment2) +run_cmake(BracketComment3) +run_cmake(BracketComment4) +run_cmake(BracketComment5) +run_cmake(BracketNoSpace0) +run_cmake(BracketNoSpace1) +run_cmake(BracketNoSpace2) +run_cmake(BracketNoSpace3) +run_cmake(BracketNoSpace4) +run_cmake(BracketNoSpace5) +run_cmake(ParenNoSpace0) +run_cmake(ParenNoSpace1) +run_cmake(ParenNoSpace2) run_cmake(UnterminatedCall1) run_cmake(UnterminatedCall2) run_cmake(UnterminatedString) -run_cmake(BracketWarn) +run_cmake(UnterminatedBracket0) +run_cmake(UnterminatedBracket1) +run_cmake(UnterminatedBracketComment) diff --git a/Tests/RunCMake/Syntax/StringCRLF-stderr.txt b/Tests/RunCMake/Syntax/StringCRLF-stderr.txt new file mode 100644 index 0000000..7aef26e --- /dev/null +++ b/Tests/RunCMake/Syntax/StringCRLF-stderr.txt @@ -0,0 +1 @@ +CRLF->LF worked diff --git a/Tests/RunCMake/Syntax/StringCRLF.cmake b/Tests/RunCMake/Syntax/StringCRLF.cmake new file mode 100644 index 0000000..d20cfea --- /dev/null +++ b/Tests/RunCMake/Syntax/StringCRLF.cmake @@ -0,0 +1,6 @@ +if("a
+b" STREQUAL "a\nb")
+ message("CRLF->LF worked")
+else()
+ message(FATAL_ERROR "CRLF->LF failed")
+endif()
diff --git a/Tests/RunCMake/Syntax/UnterminatedBracket0-result.txt b/Tests/RunCMake/Syntax/UnterminatedBracket0-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/UnterminatedBracket0-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/UnterminatedBracket0-stderr.txt b/Tests/RunCMake/Syntax/UnterminatedBracket0-stderr.txt new file mode 100644 index 0000000..3559c18 --- /dev/null +++ b/Tests/RunCMake/Syntax/UnterminatedBracket0-stderr.txt @@ -0,0 +1,8 @@ +CMake Error: Error in cmake code at +.*/Syntax/UnterminatedBracket0.cmake:2: +Parse error. Function missing ending "\)". Instead found unterminated bracket with text "\) +". +CMake Error at CMakeLists.txt:3 \(include\): + include could not find load file: + + UnterminatedBracket0.cmake$ diff --git a/Tests/RunCMake/Syntax/UnterminatedBracket0.cmake b/Tests/RunCMake/Syntax/UnterminatedBracket0.cmake new file mode 100644 index 0000000..98cd906 --- /dev/null +++ b/Tests/RunCMake/Syntax/UnterminatedBracket0.cmake @@ -0,0 +1 @@ +set(var [[) diff --git a/Tests/RunCMake/Syntax/UnterminatedBracket1-result.txt b/Tests/RunCMake/Syntax/UnterminatedBracket1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/UnterminatedBracket1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/UnterminatedBracket1-stderr.txt b/Tests/RunCMake/Syntax/UnterminatedBracket1-stderr.txt new file mode 100644 index 0000000..55d458b --- /dev/null +++ b/Tests/RunCMake/Syntax/UnterminatedBracket1-stderr.txt @@ -0,0 +1,8 @@ +CMake Error: Error in cmake code at +.*/Syntax/UnterminatedBracket1.cmake:2: +Parse error. Function missing ending "\)". Instead found unterminated bracket with text "\]\]\) +". +CMake Error at CMakeLists.txt:3 \(include\): + include could not find load file: + + UnterminatedBracket1.cmake$ diff --git a/Tests/RunCMake/Syntax/UnterminatedBracket1.cmake b/Tests/RunCMake/Syntax/UnterminatedBracket1.cmake new file mode 100644 index 0000000..706f7a3 --- /dev/null +++ b/Tests/RunCMake/Syntax/UnterminatedBracket1.cmake @@ -0,0 +1 @@ +set(var [=[]]) diff --git a/Tests/RunCMake/Syntax/UnterminatedBracketComment-result.txt b/Tests/RunCMake/Syntax/UnterminatedBracketComment-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/UnterminatedBracketComment-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/UnterminatedBracketComment-stderr.txt b/Tests/RunCMake/Syntax/UnterminatedBracketComment-stderr.txt new file mode 100644 index 0000000..0a799eb --- /dev/null +++ b/Tests/RunCMake/Syntax/UnterminatedBracketComment-stderr.txt @@ -0,0 +1,8 @@ +CMake Error: Error in cmake code at +.*/Syntax/UnterminatedBracketComment.cmake:1: +Parse error. Expected a command name, got unterminated bracket with text "#\]\] +". +CMake Error at CMakeLists.txt:3 \(include\): + include could not find load file: + + UnterminatedBracketComment.cmake diff --git a/Tests/RunCMake/Syntax/UnterminatedBracketComment.cmake b/Tests/RunCMake/Syntax/UnterminatedBracketComment.cmake new file mode 100644 index 0000000..ad71f3c --- /dev/null +++ b/Tests/RunCMake/Syntax/UnterminatedBracketComment.cmake @@ -0,0 +1,2 @@ +#[=[ +#]] @@ -301,8 +301,7 @@ CMAKE_CXX_SOURCES="\ if ${cmake_system_mingw}; then CMAKE_CXX_SOURCES="${CMAKE_CXX_SOURCES}\ cmGlobalMSYSMakefileGenerator \ - cmGlobalMinGWMakefileGenerator \ - cmWin32ProcessExecution" + cmGlobalMinGWMakefileGenerator" fi CMAKE_C_SOURCES="\ |