Makefile: Generate single-quoted object lists for Watcom

Drop the CMAKE_NO_QUOTED_OBJECTS internal variable from the Makefile
generators.  The underlying problem is with the Watcom linker, not with
WMake.  The Watcom linker wants object files to be single-quoted.  Add
<LINK-RULE>_USE_WATCOM_QUOTE platform information variables to tell the
generators to use Watcom-style single quotes for object files on link
lines.

On Windows, Watcom uses the GetCommandLine API to get the original
command-line string and do custom parsing that expects single quotes.
On POSIX systems, Watcom approximates the original command line by
joining all argv[] entries separated by a single space.  Therefore we
need to double-quote the single-quoted arguments so that the shell does
not consume them and they are available for the parser to see.
This commit is contained in:
Jiri Malak 2014-03-25 07:17:45 +01:00 committed by Brad King
parent a863a8fecd
commit 423009c17f
8 changed files with 57 additions and 36 deletions

View File

@ -39,6 +39,11 @@ set (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-br -bm -d2 -ot -dNDEBUG")
set (CMAKE_C_STANDARD_LIBRARIES_INIT "library clbrdll.lib library plbrdll.lib library kernel32.lib library user32.lib library gdi32.lib library winspool.lib library comdlg32.lib library advapi32.lib library shell32.lib library ole32.lib library oleaut32.lib library uuid.lib library odbc32.lib library odbccp32.lib")
set (CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}")
foreach(type CREATE_SHARED_LIBRARY CREATE_SHARED_MODULE LINK_EXECUTABLE)
set(CMAKE_C_${type}_USE_WATCOM_QUOTE 1)
set(CMAKE_CXX_${type}_USE_WATCOM_QUOTE 1)
endforeach()
set(CMAKE_C_CREATE_IMPORT_LIBRARY
"wlib -c -q -n -b <TARGET_IMPLIB> +<TARGET_QUOTED>")
set(CMAKE_CXX_CREATE_IMPORT_LIBRARY ${CMAKE_C_CREATE_IMPORT_LIBRARY})

View File

@ -35,7 +35,6 @@ void cmGlobalWatcomWMakeGenerator
mf->AddDefinition("CMAKE_MANGLE_OBJECT_FILE_NAMES", "1");
mf->AddDefinition("CMAKE_MAKE_LINE_CONTINUE", "&");
mf->AddDefinition("CMAKE_MAKE_SYMBOLIC_RULE", ".SYMBOLIC");
mf->AddDefinition("CMAKE_NO_QUOTED_OBJECTS", "1");
mf->AddDefinition("CMAKE_GENERATOR_CC", "wcl386");
mf->AddDefinition("CMAKE_GENERATOR_CXX", "wcl386");
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);

View File

@ -2181,14 +2181,27 @@ cmLocalUnixMakefileGenerator3
//----------------------------------------------------------------------------
std::string
cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p)
cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p,
bool useWatcomQuote)
{
// Split the path into its components.
std::vector<std::string> components;
cmSystemTools::SplitPath(p, components);
// Open the quoted result.
std::string result = "\"";
std::string result;
if(useWatcomQuote)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
result = "'";
#else
result = "\"'";
#endif
}
else
{
result = "\"";
}
// Return an empty path if there are no components.
if(!components.empty())
@ -2232,7 +2245,18 @@ cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p)
}
// Close the quoted result.
result += "\"";
if(useWatcomQuote)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
result += "'";
#else
result += "'\"";
#endif
}
else
{
result += "\"";
}
return result;
}

View File

@ -186,7 +186,8 @@ public:
const char *targetDir,
cmLocalGenerator::RelativeRoot returnDir);
static std::string ConvertToQuotedOutputPath(const char* p);
static std::string ConvertToQuotedOutputPath(const char* p,
bool useWatcomQuote);
std::string CreateMakeVariable(const std::string& sin,
const std::string& s2in);

View File

@ -290,6 +290,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
linkRuleVar += linkLanguage;
linkRuleVar += "_LINK_EXECUTABLE";
std::string linkRule = this->GetLinkRule(linkRuleVar);
bool useWatcomQuote = this->Makefile->IsOn(linkRuleVar+"_USE_WATCOM_QUOTE");
std::vector<std::string> commands1;
cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
if(this->Target->IsExecutableWithExports())
@ -343,7 +344,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// rule.
std::string buildObjs;
this->CreateObjectLists(useLinkScript, false,
useResponseFileForObjects, buildObjs, depends);
useResponseFileForObjects, buildObjs, depends,
useWatcomQuote);
cmLocalGenerator::RuleVariables vars;
vars.RuleLauncher = "RULE_LAUNCH_LINK";

View File

@ -458,6 +458,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
this->Target);
}
bool useWatcomQuote = this->Makefile->IsOn(linkRuleVar+"_USE_WATCOM_QUOTE");
// Determine whether a link script will be used.
bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();
@ -553,7 +555,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
// rule.
std::string buildObjs;
this->CreateObjectLists(useLinkScript, useArchiveRules,
useResponseFileForObjects, buildObjs, depends);
useResponseFileForObjects, buildObjs, depends,
useWatcomQuote);
cmLocalGenerator::RuleVariables vars;
vars.TargetPDB = targetOutPathPDB.c_str();

View File

@ -1349,7 +1349,8 @@ cmMakefileTargetGenerator::AppendProgress(std::vector<std::string>& commands)
void
cmMakefileTargetGenerator
::WriteObjectsVariable(std::string& variableName,
std::string& variableNameExternal)
std::string& variableNameExternal,
bool useWatcomQuote)
{
// Write a make variable assignment that lists all objects for the
// target.
@ -1360,8 +1361,6 @@ cmMakefileTargetGenerator
<< "# Object files for target " << this->Target->GetName() << "\n"
<< variableName << " =";
std::string object;
const char* objName =
this->Makefile->GetDefinition("CMAKE_NO_QUOTED_OBJECTS");
const char* lineContinue =
this->Makefile->GetDefinition("CMAKE_MAKE_LINE_CONTINUE");
if(!lineContinue)
@ -1372,17 +1371,9 @@ cmMakefileTargetGenerator
i != this->Objects.end(); ++i)
{
*this->BuildFileStream << " " << lineContinue << "\n";
if(objName)
{
*this->BuildFileStream <<
this->Convert(*i, cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::MAKEFILE);
}
else
{
*this->BuildFileStream <<
this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str());
}
*this->BuildFileStream <<
this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str(),
useWatcomQuote);
}
*this->BuildFileStream << "\n";
@ -1404,17 +1395,9 @@ cmMakefileTargetGenerator
*this->BuildFileStream
<< " " << lineContinue << "\n"
<< this->Makefile->GetSafeDefinition("CMAKE_OBJECT_NAME");
if(objName)
{
*this->BuildFileStream <<
this->Convert(*i, cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::MAKEFILE);
}
else
{
*this->BuildFileStream <<
this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str());
}
*this->BuildFileStream <<
this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str(),
useWatcomQuote);
}
*this->BuildFileStream << "\n" << "\n";
}
@ -1882,11 +1865,13 @@ void
cmMakefileTargetGenerator
::CreateObjectLists(bool useLinkScript, bool useArchiveRules,
bool useResponseFile, std::string& buildObjs,
std::vector<std::string>& makefile_depends)
std::vector<std::string>& makefile_depends,
bool useWatcomQuote)
{
std::string variableName;
std::string variableNameExternal;
this->WriteObjectsVariable(variableName, variableNameExternal);
this->WriteObjectsVariable(variableName, variableNameExternal,
useWatcomQuote);
if(useResponseFile)
{
// MSVC response files cannot exceed 128K.

View File

@ -113,7 +113,8 @@ protected:
// write out the variable that lists the objects for this target
void WriteObjectsVariable(std::string& variableName,
std::string& variableNameExternal);
std::string& variableNameExternal,
bool useWatcomQuote);
void WriteObjectsString(std::string& buildObjs);
void WriteObjectsStrings(std::vector<std::string>& objStrings,
std::string::size_type limit = std::string::npos);
@ -172,7 +173,8 @@ protected:
/** Create lists of object files for linking and cleaning. */
void CreateObjectLists(bool useLinkScript, bool useArchiveRules,
bool useResponseFile, std::string& buildObjs,
std::vector<std::string>& makefile_depends);
std::vector<std::string>& makefile_depends,
bool useWatcomQuote);
void AddIncludeFlags(std::string& flags, const std::string& lang);