summaryrefslogtreecommitdiffstats
path: root/Source/cmGlobalXCodeGenerator.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2008-01-14 14:20:58 (GMT)
committerBrad King <brad.king@kitware.com>2008-01-14 14:20:58 (GMT)
commit8262ccfd4efddd4928070c637ef7c414633b4b1e (patch)
treec276e3f4ec61422534586a008739bd668e1b9ce3 /Source/cmGlobalXCodeGenerator.cxx
parent2c42f755225c0cb30f04f07c9f5bd23f65ad0bd2 (diff)
downloadCMake-8262ccfd4efddd4928070c637ef7c414633b4b1e.zip
CMake-8262ccfd4efddd4928070c637ef7c414633b4b1e.tar.gz
CMake-8262ccfd4efddd4928070c637ef7c414633b4b1e.tar.bz2
ENH: Create COMPILE_DEFINITIONS property for targets and source files. Create <config>_COMPILE_DEFINITIONS property as per-configuration version. Add Preprocess test to test the feature. Document limitations on Xcode and VS6 generators.
Diffstat (limited to 'Source/cmGlobalXCodeGenerator.cxx')
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx92
1 files changed, 83 insertions, 9 deletions
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 44d857a..b59e949 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -453,6 +453,9 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
lg->AppendFlags(flags, sf->GetProperty("COMPILE_FLAGS"));
cmSystemTools::ReplaceString(flags, "\"", "\\\"");
+ // Add per-source definitions.
+ this->AppendDefines(flags, sf->GetProperty("COMPILE_DEFINITIONS"), true);
+
// Using a map and the full path guarantees that we will always get the same
// fileRef object for any given full path.
//
@@ -1260,12 +1263,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
bool shared = ((target.GetType() == cmTarget::SHARED_LIBRARY) ||
(target.GetType() == cmTarget::MODULE_LIBRARY));
- // Add the export symbol definition for shared library objects.
- if(const char* exportMacro = target.GetExportMacro())
- {
- defFlags += "-D";
- defFlags += exportMacro;
- }
const char* lang = target.GetLinkerLanguage(this);
std::string cflags;
if(lang)
@@ -1291,12 +1288,28 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
cmSystemTools::ReplaceString(defFlags, "\"", "\\\"");
cmSystemTools::ReplaceString(flags, "\"", "\\\"");
cmSystemTools::ReplaceString(cflags, "\"", "\\\"");
+
+ // Add preprocessor definitions for this target and configuration.
+ std::string ppDefs;
if(this->XcodeVersion > 15)
{
- buildSettings->AddAttribute
- ("GCC_PREPROCESSOR_DEFINITIONS",
- this->CreateString("CMAKE_INTDIR=\\\\\"$(CONFIGURATION)\\\\\""));
+ this->AppendDefines(ppDefs, "CMAKE_INTDIR=\"$(CONFIGURATION)\"");
+ }
+ if(const char* exportMacro = target.GetExportMacro())
+ {
+ // Add the export symbol definition for shared library objects.
+ this->AppendDefines(ppDefs, exportMacro);
+ }
+ this->AppendDefines(ppDefs, target.GetProperty("COMPILE_DEFINITIONS"));
+ if(configName)
+ {
+ std::string defVarName = cmSystemTools::UpperCase(configName);
+ defVarName += "_COMPILE_DEFINITIONS";
+ this->AppendDefines(ppDefs, target.GetProperty(defVarName.c_str()));
}
+ buildSettings->AddAttribute
+ ("GCC_PREPROCESSOR_DEFINITIONS", this->CreateString(ppDefs.c_str()));
+
std::string extraLinkOptions;
if(target.GetType() == cmTarget::EXECUTABLE)
{
@@ -2887,3 +2900,64 @@ std::string cmGlobalXCodeGenerator::LookupFlags(const char* varNamePrefix,
}
return default_flags;
}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::AppendDefines(std::string& defs,
+ const char* defines_list,
+ bool dflag)
+{
+ // Skip this if there are no definitions.
+ if(!defines_list)
+ {
+ return;
+ }
+
+ // Expand the list of definitions.
+ std::vector<std::string> defines;
+ cmSystemTools::ExpandListArgument(defines_list, defines);
+
+ // GCC_PREPROCESSOR_DEFINITIONS is a space-separated list of definitions.
+ // We escape everything as follows:
+ // - Place each definition in single quotes ''
+ // - Escape a single quote as \\'
+ // - Escape a backslash as \\\\
+ // Note that in the code below we need one more level of escapes for
+ // C string syntax in this source file.
+ const char* sep = defs.empty()? "" : " ";
+ for(std::vector<std::string>::const_iterator di = defines.begin();
+ di != defines.end(); ++di)
+ {
+ // Separate from previous definition.
+ defs += sep;
+ sep = " ";
+
+ // Open single quote.
+ defs += "'";
+
+ // Add -D flag if requested.
+ if(dflag)
+ {
+ defs += "-D";
+ }
+
+ // Escaped definition string.
+ for(const char* c = di->c_str(); *c; ++c)
+ {
+ if(*c == '\'')
+ {
+ defs += "\\\\'";
+ }
+ else if(*c == '\\')
+ {
+ defs += "\\\\\\\\";
+ }
+ else
+ {
+ defs += *c;
+ }
+ }
+
+ // Close single quote.
+ defs += "'";
+ }
+}