Browse Source

Merge topic 'refactor-compile-options'

d221eac Refactor target COMPILE_OPTIONS and COMPILE_FLAGS handling
b6385ca Escape target flags taken from COMPILE_OPTIONS
0c9cc9a Embarcadero: Use response files only for includes, objects, and libs
Brad King 12 years ago
parent
commit
daaf6283f5

+ 4 - 3
Modules/Platform/Windows-Embarcadero.cmake

@@ -78,23 +78,24 @@ set (CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_SHARED_LINKER_FLAGS_R
 macro(__embarcadero_language lang)
   set(CMAKE_${lang}_COMPILE_OPTIONS_DLL "${_tD}") # Note: This variable is a ';' separated list
   set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "${_tD}") # ... while this is a space separated string.
+  set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 1)
 
   # compile a source file into an object file
   # place <DEFINES> outside the response file because Borland refuses
   # to parse quotes from the response file.
   set(CMAKE_${lang}_COMPILE_OBJECT
-    "<CMAKE_${lang}_COMPILER> ${_tR} <DEFINES> ${CMAKE_START_TEMP_FILE}-DWIN32 -o<OBJECT> <FLAGS> ${_COMPILE_${lang}} <SOURCE>${CMAKE_END_TEMP_FILE}"
+    "<CMAKE_${lang}_COMPILER> ${_tR} <DEFINES> -DWIN32 -o<OBJECT> <FLAGS> ${_COMPILE_${lang}} <SOURCE>"
     )
 
   set(CMAKE_${lang}_LINK_EXECUTABLE
-    "<CMAKE_${lang}_COMPILER> ${_tR} -e<TARGET> ${CMAKE_START_TEMP_FILE}<LINK_FLAGS> <FLAGS> <LINK_LIBRARIES> <OBJECTS>${CMAKE_END_TEMP_FILE}"
+    "<CMAKE_${lang}_COMPILER> ${_tR} -e<TARGET> <LINK_FLAGS> <FLAGS> ${CMAKE_START_TEMP_FILE} <LINK_LIBRARIES> <OBJECTS>${CMAKE_END_TEMP_FILE}"
     # "implib -c -w <TARGET_IMPLIB> <TARGET>"
     )
 
   # place <DEFINES> outside the response file because Borland refuses
   # to parse quotes from the response file.
   set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE
-    "cpp32 <DEFINES> ${CMAKE_START_TEMP_FILE}-DWIN32 <FLAGS> -o<PREPROCESSED_SOURCE> ${_COMPILE_${lang}} <SOURCE>${CMAKE_END_TEMP_FILE}"
+    "cpp32 <DEFINES> -DWIN32 <FLAGS> -o<PREPROCESSED_SOURCE> ${_COMPILE_${lang}} <SOURCE>"
     )
   # Borland >= 5.6 allows -P option for cpp32, <= 5.5 does not
 

+ 1 - 28
Source/cmExtraSublimeTextGenerator.cxx

@@ -429,34 +429,7 @@ cmExtraSublimeTextGenerator::ComputeFlagsForObject(cmSourceFile* source,
   lg->AppendFlags(flags, makefile->GetDefineFlags());
 
   // Add target-specific flags.
-  std::string targetFlags;
-  lg->GetCompileOptions(targetFlags, target, config);
-  if (!targetFlags.empty())
-    {
-    std::string langIncludeExpr = "CMAKE_";
-    langIncludeExpr += language;
-    langIncludeExpr += "_FLAG_REGEX";
-    const char* regex = makefile->GetDefinition(langIncludeExpr.c_str());
-    if(regex)
-      {
-      cmsys::RegularExpression r(regex);
-      std::vector<std::string> args;
-      cmSystemTools::
-        ParseWindowsCommandLine(targetFlags.c_str(), args);
-      for(std::vector<std::string>::iterator i = args.begin();
-          i != args.end(); ++i)
-        {
-        if(r.find(i->c_str()))
-          {
-          lg->AppendFlags(flags, i->c_str());
-          }
-        }
-      }
-    else
-      {
-      lg->AppendFlags(flags, targetFlags.c_str());
-      }
-    }
+  lg->AddCompileOptions(flags, target, config, language);
 
   // Add source file specific flags.
   lg->AppendFlags(flags, source->GetProperty("COMPILE_FLAGS"));

+ 5 - 6
Source/cmGlobalXCodeGenerator.cxx

@@ -681,12 +681,6 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
 {
   // Add flags from target and source file properties.
   std::string flags;
-  std::string targetFlags;
-  lg->GetCompileOptions(targetFlags, &cmtarget, 0); // TODO: Config?
-  if(!targetFlags.empty())
-    {
-    lg->AppendFlags(flags, targetFlags.c_str());
-    }
   const char* srcfmt = sf->GetProperty("Fortran_FORMAT");
   switch(this->CurrentLocalGenerator->GetFortranFormat(srcfmt))
     {
@@ -1704,6 +1698,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
       this->CurrentLocalGenerator->AddLanguageFlags(cflags, "C", configName);
       this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target,
                                                    "C", configName);
+      this->CurrentLocalGenerator->
+        AddCompileOptions(cflags, &target, "C", configName);
       }
 
     // Add language-specific flags.
@@ -1715,6 +1711,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
 
     this->CurrentLocalGenerator->AddVisibilityPresetFlags(flags, &target,
                                                    lang);
+
+    this->CurrentLocalGenerator->
+      AddCompileOptions(flags, &target, lang, configName);
     }
   else if(binary)
   {

+ 1 - 1
Source/cmGlobalXCodeGenerator.h

@@ -85,6 +85,7 @@ public:
   virtual bool IsMultiConfig();
 
   virtual bool SetGeneratorToolset(std::string const& ts);
+  void AppendFlag(std::string& flags, std::string const& flag);
 private:
   cmXCodeObject* CreateOrGetPBXGroup(cmTarget& cmtarget,
                                      cmSourceGroup* sg);
@@ -198,7 +199,6 @@ private:
   void AppendDefines(BuildObjectListOrString& defs,
                      std::vector<std::string> const& defines,
                      bool dflag = false);
-  void AppendFlag(std::string& flags, std::string const& flag);
 
 protected:
   virtual const char* GetInstallTargetName() const { return "install"; }

+ 49 - 14
Source/cmLocalGenerator.cxx

@@ -1339,22 +1339,50 @@ std::string cmLocalGenerator::GetIncludeFlags(
 }
 
 //----------------------------------------------------------------------------
-void cmLocalGenerator::GetCompileOptions(std::string& flags,
-                                             cmTarget* target,
-                                             const char *config)
+void cmLocalGenerator::AddCompileOptions(
+  std::string& flags, cmTarget* target,
+  const char* lang, const char* config
+  )
 {
-  // Add target-specific flags.
-  if(const char *prop = target->GetProperty("COMPILE_FLAGS"))
+  std::string langFlagRegexVar = std::string("CMAKE_")+lang+"_FLAG_REGEX";
+  if(const char* langFlagRegexStr =
+     this->Makefile->GetDefinition(langFlagRegexVar.c_str()))
     {
-    this->AppendFlags(flags, prop);
+    // Filter flags acceptable to this language.
+    cmsys::RegularExpression r(langFlagRegexStr);
+    std::vector<std::string> opts;
+    if(const char* targetFlags = target->GetProperty("COMPILE_FLAGS"))
+      {
+      cmSystemTools::ParseWindowsCommandLine(targetFlags, opts);
+      }
+    target->GetCompileOptions(opts, config);
+    for(std::vector<std::string>::const_iterator i = opts.begin();
+        i != opts.end(); ++i)
+      {
+      if(r.find(i->c_str()))
+        {
+        // (Re-)Escape this flag.  COMPILE_FLAGS were already parsed
+        // as a command line above, and COMPILE_OPTIONS are escaped.
+        this->AppendFlagEscape(flags, i->c_str());
+        }
+      }
     }
-
-  std::vector<std::string> opts; // TODO: Emitted.
-  target->GetCompileOptions(opts, config);
-  for(std::vector<std::string>::const_iterator li = opts.begin();
-      li != opts.end(); ++li)
+  else
     {
-    this->AppendFlags(flags, li->c_str());
+    // Use all flags.
+    if(const char* targetFlags = target->GetProperty("COMPILE_FLAGS"))
+      {
+      // COMPILE_FLAGS are not escaped for historical reasons.
+      this->AppendFlags(flags, targetFlags);
+      }
+    std::vector<std::string> opts; // TODO: Emitted.
+    target->GetCompileOptions(opts, config);
+    for(std::vector<std::string>::const_iterator i = opts.begin();
+        i != opts.end(); ++i)
+      {
+      // COMPILE_OPTIONS are escaped.
+      this->AppendFlagEscape(flags, i->c_str());
+      }
     }
 }
 
@@ -2216,7 +2244,7 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags,
     for(std::vector<std::string>::const_iterator oi = options.begin();
         oi != options.end(); ++oi)
       {
-      this->AppendFlags(flags, this->EscapeForShell(oi->c_str()).c_str());
+      this->AppendFlagEscape(flags, oi->c_str());
       }
     }
 }
@@ -2253,6 +2281,13 @@ void cmLocalGenerator::AppendFlags(std::string& flags,
     }
 }
 
+//----------------------------------------------------------------------------
+void cmLocalGenerator::AppendFlagEscape(std::string& flags,
+                                        const char* rawFlag)
+{
+  this->AppendFlags(flags, this->EscapeForShell(rawFlag).c_str());
+}
+
 //----------------------------------------------------------------------------
 void cmLocalGenerator::AppendDefines(std::set<std::string>& defines,
                                      const char* defines_list)
@@ -2359,7 +2394,7 @@ void cmLocalGenerator::AppendFeatureOptions(
     for(std::vector<std::string>::const_iterator oi = options.begin();
         oi != options.end(); ++oi)
       {
-      this->AppendFlags(flags, this->EscapeForShell(oi->c_str()).c_str());
+      this->AppendFlagEscape(flags, oi->c_str());
       }
     }
 }

+ 3 - 3
Source/cmLocalGenerator.h

@@ -149,6 +149,7 @@ public:
                               const char* config);
   ///! Append flags to a string.
   virtual void AppendFlags(std::string& flags, const char* newFlags);
+  virtual void AppendFlagEscape(std::string& flags, const char* rawFlag);
   ///! Get the include flags for the current makefile and language
   std::string GetIncludeFlags(const std::vector<std::string> &includes,
                               const char* lang, bool forResponseFile = false,
@@ -217,9 +218,8 @@ public:
                              cmGeneratorTarget* target,
                              const char* lang = "C", const char *config = 0,
                              bool stripImplicitInclDirs = true);
-  void GetCompileOptions(std::string& flags,
-                         cmTarget* target,
-                         const char *config);
+  void AddCompileOptions(std::string& flags, cmTarget* target,
+                         const char* lang, const char* config);
 
   /** Compute the language used to compile the given source file.  */
   const char* GetSourceFileLanguage(const cmSourceFile& source);

+ 8 - 26
Source/cmLocalVisualStudio6Generator.cxx

@@ -1674,6 +1674,14 @@ void cmLocalVisualStudio6Generator
       flagVar = baseFlagVar + "_RELWITHDEBINFO";
       flagsRelWithDebInfo = this->Makefile->GetSafeDefinition(flagVar.c_str());
       flagsRelWithDebInfo += " -DCMAKE_INTDIR=\\\"RelWithDebInfo\\\" ";
+
+      this->AddCompileOptions(flags, &target, linkLanguage, 0);
+      this->AddCompileOptions(flagsDebug, &target, linkLanguage, "Debug");
+      this->AddCompileOptions(flagsRelease, &target, linkLanguage, "Release");
+      this->AddCompileOptions(flagsMinSizeRel, &target, linkLanguage,
+                              "MinSizeRel");
+      this->AddCompileOptions(flagsRelWithDebInfo, &target, linkLanguage,
+                              "RelWithDebInfo");
       }
 
     // if _UNICODE and _SBCS are not found, then add -D_MBCS
@@ -1686,32 +1694,6 @@ void cmLocalVisualStudio6Generator
       flags += " /D \"_MBCS\"";
       }
 
-    {
-    std::string targetFlags;
-    this->GetCompileOptions(targetFlags, &target, 0);
-    // Add per-target flags.
-    if(!targetFlags.empty())
-      {
-      flags += " ";
-      flags += targetFlags;
-      }
-    }
-#define ADD_FLAGS(CONFIG) \
-    { \
-    std::string targetFlags; \
-    this->GetCompileOptions(targetFlags, &target, #CONFIG); \
-    if(!targetFlags.empty()) \
-      { \
-      flags ## CONFIG += " "; \
-      flags ## CONFIG += targetFlags; \
-      } \
-    }
-
-    ADD_FLAGS(Debug)
-    ADD_FLAGS(Release)
-    ADD_FLAGS(MinSizeRel)
-    ADD_FLAGS(RelWithDebInfo)
-
     // Add per-target and per-configuration preprocessor definitions.
     std::set<std::string> definesSet;
     std::set<std::string> debugDefinesSet;

+ 3 - 9
Source/cmLocalVisualStudio7Generator.cxx

@@ -711,6 +711,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
       {
       flags += " /TP ";
       }
+
+    // Add the target-specific flags.
+    this->AddCompileOptions(flags, &target, linkLanguage, configName);
     }
 
   if(this->FortranProject)
@@ -723,15 +726,6 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
       }
     }
 
-  std::string targetFlags;
-  this->GetCompileOptions(targetFlags, &target, configName);
-  // Add the target-specific flags.
-  if(!targetFlags.empty())
-    {
-    flags += " ";
-    flags += targetFlags;
-    }
-
   // Get preprocessor definitions for this directory.
   std::string defineFlags = this->Makefile->GetDefineFlags();
   Options::Tool t = Options::Compiler;

+ 9 - 0
Source/cmLocalXCodeGenerator.cxx

@@ -33,3 +33,12 @@ cmLocalXCodeGenerator::GetTargetDirectory(cmTarget const&) const
   // No per-target directory for this generator (yet).
   return "";
 }
+
+//----------------------------------------------------------------------------
+void cmLocalXCodeGenerator::AppendFlagEscape(std::string& flags,
+                                             const char* rawFlag)
+{
+  cmGlobalXCodeGenerator* gg =
+    static_cast<cmGlobalXCodeGenerator*>(this->GlobalGenerator);
+  gg->AppendFlag(flags, rawFlag);
+}

+ 1 - 0
Source/cmLocalXCodeGenerator.h

@@ -28,6 +28,7 @@ public:
 
   virtual ~cmLocalXCodeGenerator();
   virtual std::string GetTargetDirectory(cmTarget const& target) const;
+  virtual void AppendFlagEscape(std::string& flags, const char* rawFlag);
 private:
 
 };

+ 4 - 46
Source/cmMakefileTargetGenerator.cxx

@@ -285,6 +285,10 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l)
     this->LocalGenerator->
       AppendFlags(flags,this->GetFrameworkFlags().c_str());
 
+    // Add target-specific flags.
+    this->LocalGenerator->AddCompileOptions(flags, this->Target,
+                                            lang, this->ConfigName);
+
     ByLanguageMap::value_type entry(l, flags);
     i = this->FlagsByLanguage.insert(entry).first;
     }
@@ -335,25 +339,12 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
       this->Makefile->GetSafeDefinition(compiler.c_str()) << "\n";
     }
 
-  std::string targetFlags;
   for(std::set<cmStdString>::const_iterator l = languages.begin();
       l != languages.end(); ++l)
     {
     *this->FlagFileStream << *l << "_FLAGS = " << this->GetFlags(*l) << "\n\n";
     *this->FlagFileStream << *l << "_DEFINES = " << this->GetDefines(*l) <<
       "\n\n";
-    std::string targetLangFlags;
-    this->LocalGenerator->GetCompileOptions(targetLangFlags, this->Target,
-                            this->LocalGenerator->ConfigurationName.c_str());
-    if (!targetFlags.empty() && targetFlags != targetLangFlags)
-      {
-      targetFlags += " " + targetLangFlags;
-      }
-    }
-
-  if (!targetFlags.empty())
-    {
-    *this->FlagFileStream << "# TARGET_FLAGS = " << targetFlags << "\n\n";
     }
 }
 
@@ -542,39 +533,6 @@ cmMakefileTargetGenerator
   std::string configUpper =
     cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName);
 
-  std::string targetFlags;
-  this->LocalGenerator->GetCompileOptions(targetFlags, this->Target,
-                                          configUpper.c_str());
-  if (!targetFlags.empty())
-    {
-    std::string langIncludeExpr = "CMAKE_";
-    langIncludeExpr += lang;
-    langIncludeExpr += "_FLAG_REGEX";
-    const char* regex = this->Makefile->
-      GetDefinition(langIncludeExpr.c_str());
-    if(regex)
-      {
-      cmsys::RegularExpression r(regex);
-      std::vector<std::string> args;
-      cmSystemTools::ParseWindowsCommandLine(
-        targetFlags.c_str(),
-        args);
-      for(std::vector<std::string>::iterator i = args.begin();
-          i != args.end(); ++i)
-        {
-        if(r.find(i->c_str()))
-          {
-          this->LocalGenerator->AppendFlags
-            (flags, i->c_str());
-          }
-        }
-      }
-    else
-      {
-      this->LocalGenerator->AppendFlags(flags, targetFlags.c_str());
-      }
-    }
-
   // Add Fortran format flags.
   if(strcmp(lang, "Fortran") == 0)
     {

+ 2 - 32
Source/cmNinjaTargetGenerator.cxx

@@ -174,38 +174,8 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source,
   this->LocalGenerator->AppendFlags(flags, this->Makefile->GetDefineFlags());
 
   // Add target-specific flags.
-  std::string targetFlags;
-  this->LocalGenerator->GetCompileOptions(targetFlags, this->Target, config);
-  if(!targetFlags.empty())
-    {
-    std::string langIncludeExpr = "CMAKE_";
-    langIncludeExpr += language;
-    langIncludeExpr += "_FLAG_REGEX";
-    const char* regex = this->Makefile->
-      GetDefinition(langIncludeExpr.c_str());
-    if(regex)
-      {
-      cmsys::RegularExpression r(regex);
-      std::vector<std::string> args;
-      cmSystemTools::ParseWindowsCommandLine(
-        targetFlags.c_str(),
-        args);
-      for(std::vector<std::string>::iterator i = args.begin();
-          i != args.end(); ++i)
-        {
-        if(r.find(i->c_str()))
-          {
-          this->LocalGenerator->AppendFlags
-            (flags, i->c_str());
-          }
-        }
-      }
-    else
-      {
-      this->LocalGenerator->AppendFlags
-        (flags, targetFlags.c_str());
-      }
-    }
+  this->LocalGenerator->AddCompileOptions(flags, this->Target,
+                                          language.c_str(), config);
 
     // Add source file specific flags.
     this->LocalGenerator->AppendFlags(flags,

+ 2 - 9
Source/cmVisualStudio10TargetGenerator.cxx

@@ -1276,17 +1276,10 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
       {
       flags += " /TP ";
       }
+    this->LocalGenerator->AddCompileOptions(flags, this->Target,
+                                            linkLanguage, configName.c_str());
     }
 
-  std::string targetFlags;
-  this->LocalGenerator->GetCompileOptions(targetFlags, this->Target,
-                                          configName.c_str());
-  // Add the target-specific flags.
-  if(!targetFlags.empty())
-    {
-    flags += " ";
-    flags += targetFlags;
-    }
   // Get preprocessor definitions for this directory.
   std::string defineFlags = this->Target->GetMakefile()->GetDefineFlags();
   clOptions.FixExceptionHandlingDefault();

+ 5 - 1
Tests/CompileOptions/CMakeLists.txt

@@ -5,7 +5,11 @@ project(CompileOptions)
 add_library(testlib other.cpp)
 
 add_executable(CompileOptions main.cpp)
-set_property(TARGET CompileOptions PROPERTY COMPILE_OPTIONS "$<$<CXX_COMPILER_ID:GNU>:-DTEST_DEFINE>")
+set_property(TARGET CompileOptions PROPERTY COMPILE_OPTIONS
+  "-DTEST_DEFINE"
+  "-DNEEDS_ESCAPE=\"E$CAPE\""
+  "$<$<CXX_COMPILER_ID:GNU>:-DTEST_DEFINE_GNU>"
+  )
 target_link_libraries(CompileOptions testlib)
 
 if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")

+ 14 - 5
Tests/CompileOptions/main.cpp

@@ -1,11 +1,20 @@
+#ifndef TEST_DEFINE
+# error Expected definition TEST_DEFINE
+#endif
+
+#ifndef NEEDS_ESCAPE
+# error Expected definition NEEDS_ESCAPE
+#endif
 
 #ifdef DO_GNU_TESTS
-#  ifndef TEST_DEFINE
-#    error Expected TEST_DEFINE
-#  endif
+# ifndef TEST_DEFINE_GNU
+#  error Expected definition TEST_DEFINE_GNU
+# endif
 #endif
 
-int main(int argc, char **argv)
+#include <string.h>
+
+int main()
 {
-  return 0;
+  return strcmp(NEEDS_ESCAPE, "E$CAPE") == 0 ? 0 : 1;
 }