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:
parent
a863a8fecd
commit
423009c17f
|
@ -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})
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
if(useWatcomQuote)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
result += "'";
|
||||
#else
|
||||
result += "'\"";
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
result += "\"";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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->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->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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue