summaryrefslogtreecommitdiffstats
path: root/Include
Commit message (Expand)AuthorAgeFilesLines
* Bump version to 3.3.0b1.v3.3.0b1Georg Brandl2012-06-261-3/+3
* Issue #11626: Add _SizeT functions to stable ABI.Martin v. Löwis2012-06-231-1/+4
* Issue #15146: Add PyType_FromSpecWithBases. Patch by Robin Schreiber.Martin v. Löwis2012-06-231-0/+3
* Issue #14785: Add sys._debugmallocstats() to help debug low-level memory allo...David Malcolm2012-06-229-1/+26
* Issue #15042: Add PyState_AddModule and PyState_RemoveModule.Martin v. Löwis2012-06-221-0/+5
* Issue #14928: Fix importlib bootstrap issues by using a custom executable (Mo...Antoine Pitrou2012-06-191-0/+3
* Issue #13783: the PEP 380 implementation no longer expands the public C APINick Coghlan2012-06-172-4/+1
* Issue #15026: utf-16 encoding is now significantly faster (up to 10x).Antoine Pitrou2012-06-151-2/+2
* PEP 418: Rename adjusted attribute to adjustable in time.get_clock_info() resultVictor Stinner2012-06-121-1/+1
* Issue #14993: Use standard "unsigned char" instead of a unsigned char bitfieldVictor Stinner2012-06-041-6/+4
* Trunk merge.Barry Warsaw2012-06-041-1/+1
|\
| * __GNUC__ does not imply gcc version is present, so just check for version (cl...Benjamin Peterson2012-06-041-1/+1
* | Eric Snow's implementation of PEP 421.Barry Warsaw2012-06-032-0/+18
|/
* Issue #14090: fix some minor C API problems in default branch (3.3)Eli Bendersky2012-06-031-2/+5
* Issue #14007: implement doctype() method calling in XMLParser of _elementtree.Eli Bendersky2012-06-011-0/+2
* Post-release update.Georg Brandl2012-05-311-1/+1
* Bump version to 3.3.0a4.v3.3.0a4Georg Brandl2012-05-301-2/+2
* Issue #14744: Use the new _PyUnicodeWriter internal API to speed up str%args ...Victor Stinner2012-05-294-19/+114
* Issue #14930: Make memoryview objects weakrefable.Richard Oudkerk2012-05-281-0/+1
* s/tabs/spaces, and clean trailing whitespaceEli Bendersky2012-05-231-28/+27
* Widen ASDL sequences to Py_ssize_t lengths to better match PEP 353.Martin v. Löwis2012-05-151-4/+4
* PEP 415: Implement suppression of __context__ display with an exception attri...Benjamin Peterson2012-05-151-2/+2
* Post-3.3a3 bump.Georg Brandl2012-05-061-1/+1
* Issue #14127: Add ns= parameter to utime, futimes, and lutimes.Larry Hastings2012-05-031-0/+4
* strip is_ prefixes on clock_info fieldsBenjamin Peterson2012-05-011-2/+2
* Bump to 3.3.0a3.Georg Brandl2012-05-011-2/+2
* Issues #13959, 14647: Re-implement imp.reload() in Lib/imp.py.Brett Cannon2012-04-291-1/+0
* Issue #14521: Make result of float('nan') and float('-nan') more consistent a...Mark Dickinson2012-04-291-0/+2
* Issue #14428, #14397: Implement the PEP 418Victor Stinner2012-04-291-0/+14
* Simplify and optimize formatlong()Victor Stinner2012-04-271-2/+0
* Account for shared keys in type's __sizeof__ (#13903).Martin v. Loewis2012-04-241-0/+1
* Close #14648: Compute correctly maxchar in str.format() for substrinVictor Stinner2012-04-231-0/+9
* Implement PEP 412: Key-sharing dictionaries (closes #13903)Benjamin Peterson2012-04-232-69/+19
* Issue #14127: Add st_{cma}time_ns fields to os.stat() result object.Larry Hastings2012-04-191-0/+4
* Issue #14098: New functions PyErr_GetExcInfo and PyErr_SetExcInfo.Martin v. Löwis2012-04-191-0/+2
* Fix #14600. Correct reference handling and naming of ImportError convenience ...Brian Curtin2012-04-171-3/+2
* Issue #13889: Merge fix from 3.2.Mark Dickinson2012-04-151-0/+24
|\
| * Issue #13889: On MSVC builds, set FPU control word at runtime for all string ...Mark Dickinson2012-04-151-0/+24
| * Merge 3.2.3 release clone.Georg Brandl2012-04-111-3/+3
| |\
| | * Post-release update.Georg Brandl2012-04-111-1/+1
| | * Bump to 3.2.3 final.Georg Brandl2012-04-101-3/+3
| | * Issue #14387 : undefine 'small' so that it doesn't clash with Windows headers.Kristján Valur Jónsson2012-03-221-0/+2
* | | Issue #2377: Make importlib the implementation of __import__().Brett Cannon2012-04-145-1/+12
* | | put PyImportErrorObject with its brothersBenjamin Peterson2012-04-131-7/+7
* | | Issue #1559549: Add 'name' and 'path' attributes to ImportError.Brett Cannon2012-04-131-0/+13
* | | Reformat by replacing tabs with 4-spaces. Makes the code more PEP-7 compliantEli Bendersky2012-04-051-8/+8
* | | Rename _PyIter_GetBuiltin to _PyObject_GetBuiltin, and do not include it in t...Antoine Pitrou2012-04-042-2/+5
* | | Issue #14288: Serialization support for builtin iterators.Kristján Valur Jónsson2012-04-031-0/+2
* | | Post-release update.Georg Brandl2012-04-021-1/+1
* | | Bump to 3.3.0a2.v3.3.0a2Georg Brandl2012-04-011-2/+2
id='n706' href='#n706'>706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746
/*=========================================================================

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile$
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef cmMakefile_h
#define cmMakefile_h

#include "cmData.h"
#include "cmSystemTools.h"
#include "cmSourceGroup.h"
#include "cmTarget.h"
#include "cmListFileCache.h"
#include "cmCacheManager.h"

#include <cmsys/RegularExpression.hxx>

class cmFunctionBlocker;
class cmCommand;
class cmLocalGenerator;
class cmMakeDepend;
class cmSourceFile;
class cmTest;
class cmVariableWatch;
class cmake;

/** \class cmMakefile
 * \brief Process the input CMakeLists.txt file.
 *
 * Process and store into memory the input CMakeLists.txt file.
 * Each CMakeLists.txt file is parsed and the commands found there
 * are added into the build process.
 */
class cmMakefile
{
public:
  /**
   * Return major and minor version numbers for cmake.
   */
  static unsigned int GetMajorVersion() { return CMake_VERSION_MAJOR; }
  static unsigned int GetMinorVersion() { return CMake_VERSION_MINOR; }
  static unsigned int GetPatchVersion() { return CMake_VERSION_PATCH; }
  static const char* GetReleaseVersion();
  
  /**
   * Return the major and minor version of the cmake that
   * was used to write the currently loaded cache, note
   * this method will not work before the cache is loaded.
   */
  unsigned int GetCacheMajorVersion();
  unsigned int GetCacheMinorVersion();
  
  /**
   * Construct an empty makefile.
   */
  cmMakefile();

  /**
   * Destructor.
   */
  ~cmMakefile();

  /**
   * Read and parse a CMakeLists.txt file.
   */
  bool ReadListFile(const char* listfile, const char* external= 0); 

  /**
   * Add a function blocker to this makefile
   */
  void AddFunctionBlocker(cmFunctionBlocker *fb)
    { m_FunctionBlockers.push_back(fb);}
  void RemoveFunctionBlocker(cmFunctionBlocker *fb)
    { m_FunctionBlockers.remove(fb);}
  void RemoveFunctionBlocker(const cmListFileFunction& lff);

  /**
   * Add file to the written file list. These file should not be in the list
   * of dependencies because they cause infinite loops.
   */
  void AddWrittenFile(const char* file);
  bool HasWrittenFile(const char* file);

  /**
   * Check if there are any infinite loops
   */
  bool CheckInfiniteLoops();
  
  /**
   * Try running cmake and building a file. This is used for dynalically
   * loaded commands, not as part of the usual build process.
   */
  int TryCompile(const char *srcdir, const char *bindir, 
                 const char *projectName, const char *targetName,
                 const std::vector<std::string> *cmakeArgs,
                 std::string *output);
    
  /**
   * Specify the makefile generator. This is platform/compiler
   * dependent, although the interface is through a generic
   * superclass.
   */
  void SetLocalGenerator(cmLocalGenerator*);
  
  ///! Get the current makefile generator.
  cmLocalGenerator* GetLocalGenerator() 
    { return m_LocalGenerator;}

  /**
   * Perform FinalPass, Library dependency analysis etc before output of the
   * makefile.  
   */
  void ConfigureFinalPass();
  
  /**
   * run the final pass on all commands.
   */
  void FinalPass();
  
  /**
   * Print the object state to std::cout.
   */
  void Print();

  /** Add a custom command to the build.  */
  void AddCustomCommandToTarget(const char* target,
                                const std::vector<std::string>& depends,
                                const cmCustomCommandLines& commandLines,
                                cmTarget::CustomCommandType type,
                                const char* comment);
  void AddCustomCommandToOutput(const char* output,
                                const std::vector<std::string>& depends,
                                const char* main_dependency,
                                const cmCustomCommandLines& commandLines,
                                const char* comment,
                                bool replace = false);
  void AddCustomCommandOldStyle(const char* target,
                                const std::vector<std::string>& outputs,
                                const std::vector<std::string>& depends,
                                const char* source,
                                const cmCustomCommandLines& commandLines,
                                const char* comment);

  /**
   * Add a define flag to the build.
   */
  void AddDefineFlag(const char* definition);
  void RemoveDefineFlag(const char* definition);

  /**
   * Add an executable to the build.
   */
  cmTarget* AddExecutable(const char *exename, 
                          const std::vector<std::string> &srcs);

  /**
   * Add a utility to the build.  A utiltity target is a command that
   * is run every time the target is built.
   */
  void AddUtilityCommand(const char* utilityName, bool all,
                         const char* output,
                         const std::vector<std::string>& depends,
                         const char* command,
                         const char* arg1=0,
                         const char* arg2=0,
                         const char* arg3=0,
                         const char* arg4=0);
  void AddUtilityCommand(const char* utilityName, bool all,
                         const char* output,
                         const std::vector<std::string>& depends,
                         const cmCustomCommandLines& commandLines);

  /**
   * Add a link library to the build.
   */
  void AddLinkLibrary(const char*);
  void AddLinkLibrary(const char*, cmTarget::LinkLibraryType type);
  void AddLinkLibraryForTarget(const char *tgt, const char*, 
                               cmTarget::LinkLibraryType type);
  void AddLinkDirectoryForTarget(const char *tgt, const char* d);

  /**
   * Add a link directory to the build.
   */
  void AddLinkDirectory(const char*);

  /**
   * Get the list of link directories
   */
  std::vector<std::string>& GetLinkDirectories()
    {
      return m_LinkDirectories;
    }
  const std::vector<std::string>& GetLinkDirectories() const
    {
      return m_LinkDirectories;
    }
  void SetLinkDirectories(const std::vector<std::string>& vec)
    {
      m_LinkDirectories = vec;
    }

  /**
   * Add a subdirectory to the build.
   */
  void AddSubDirectory(const char*, bool includeTopLevel=true, bool preorder = false);
  void AddSubDirectory(const char* fullSrcDir,const char *fullBinDir, 
                       bool includeTopLevel, bool preorder,
                       bool immediate);

  /**
   * Configure a subdirectory
   */
  void ConfigureSubDirectory(cmLocalGenerator *);
                             
  /**
   * Add an include directory to the build.
   */
  void AddIncludeDirectory(const char*, bool before = false);

  /**
   * Find a library (as in cmSystemTools) but add in compiler specific paths
   */
  std::string FindLibrary(const char* name,
                          const std::vector<std::string>& path);

  /**
   * Get the include file or library search path.
   */
  void GetIncludeSearchPath(const std::vector<std::string>& callerPaths,
                            std::vector<std::string>& path);
  void GetLibrarySearchPath(const std::vector<std::string>& callerPaths,
                            std::vector<std::string>& path);

  /**
   * Add a variable definition to the build. This variable
   * can be used in CMake to refer to lists, directories, etc.
   */
  void AddDefinition(const char* name, const char* value);
  ///! Add a definition to this makefile and the global cmake cache.
  void AddCacheDefinition(const char* name, const char* value, 
                          const char* doc,
                          cmCacheManager::CacheEntryType type);

  /**
   * Add bool variable definition to the build. 
   */
  void AddDefinition(const char* name, bool);
  ///! Add a definition to this makefile and the global cmake cache.
  void AddCacheDefinition(const char* name, bool, const char* doc);

  /**
   * Remove a variable definition from the build.  This is not valid
   * for cache entries, and will only affect the current makefile.
   */
  void RemoveDefinition(const char* name);
  
  /**
   * Specify the name of the project for this build.
   */
  void SetProjectName(const char*);

  /**
   * Get the name of the project for this build.
   */
  const char* GetProjectName()
    {
      return m_ProjectName.c_str();
    }
  
  /**
   * Set the name of the library.
   */
  void AddLibrary(const char *libname, int shared,
                  const std::vector<std::string> &srcs);

  /**
   * Add a source group for consideration when adding a new source.
   */
  void AddSourceGroup(const char* name, const char* regex=0, const char* parent=0);
  
  /**
   * Add an auxiliary directory to the build.
   */
  void AddExtraDirectory(const char* dir);
  

  /**
   * Add an auxiliary directory to the build.
   */
  void MakeStartDirectoriesCurrent()
    {
      this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", 
                          m_cmStartDirectory.c_str());
      this->AddDefinition("CMAKE_CURRENT_BINARY_DIR", 
                          m_StartOutputDirectory.c_str());
    }
  
  //@{
  /**
   * Set/Get the home directory (or output directory) in the project. The
   * home directory is the top directory of the project. It is where
   * CMakeSetup or configure was run. Remember that CMake processes
   * CMakeLists files by recursing up the tree starting at the StartDirectory
   * and going up until it reaches the HomeDirectory.  
   */
  void SetHomeDirectory(const char* dir);
  const char* GetHomeDirectory() const
    {
      return m_cmHomeDirectory.c_str();
    }
  void SetHomeOutputDirectory(const char* lib);
  const char* GetHomeOutputDirectory() const
    {
      return m_HomeOutputDirectory.c_str();
    }
  //@}
  
  //@{
  /**
   * Set/Get the start directory (or output directory). The start directory
   * is the directory of the CMakeLists.txt file that started the current
   * round of processing. Remember that CMake processes CMakeLists files by
   * recursing up the tree starting at the StartDirectory and going up until
   * it reaches the HomeDirectory.  
   */
  void SetStartDirectory(const char* dir) 
    {
      m_cmStartDirectory = dir;
      cmSystemTools::ConvertToUnixSlashes(m_cmStartDirectory);
      this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", 
                          m_cmStartDirectory.c_str());
    }
  const char* GetStartDirectory() const
    {
      return m_cmStartDirectory.c_str();
    }
  void SetStartOutputDirectory(const char* lib)
    {
      m_StartOutputDirectory = lib;
      cmSystemTools::ConvertToUnixSlashes(m_StartOutputDirectory);
      cmSystemTools::MakeDirectory(m_StartOutputDirectory.c_str());
      this->AddDefinition("CMAKE_CURRENT_BINARY_DIR", 
                          m_StartOutputDirectory.c_str());
    }
  const char* GetStartOutputDirectory() const
    {
      return m_StartOutputDirectory.c_str();
    }
  //@}

  const char* GetCurrentDirectory() const 
    {
      return m_cmStartDirectory.c_str();
    }
  const char* GetCurrentOutputDirectory() const
    {
      return m_StartOutputDirectory.c_str();
    }

  /* Get the current CMakeLists.txt file that is being processed.  This
   * is just used in order to be able to 'branch' from one file to a second
   * transparently */
  const char* GetCurrentListFile() const
    {
      return m_cmCurrentListFile.c_str();
    }

  //@}

  /** 
   * Set a regular expression that include files must match
   * in order to be considered as part of the depend information.
   */
  void SetIncludeRegularExpression(const char* regex)
    {
      m_IncludeFileRegularExpression = regex;
    }
  const char* GetIncludeRegularExpression()
    { 
      return m_IncludeFileRegularExpression.c_str();
    }

  /** 
   * Set a regular expression that include files that are not found
   * must match in order to be considered a problem.
   */
  void SetComplainRegularExpression(const char* regex)
    {
      m_ComplainFileRegularExpression = regex;
    }
  const char* GetComplainRegularExpression()
    {
      return m_ComplainFileRegularExpression.c_str();
    }

  /**
   * Get the list of targets
   */
  cmTargets &GetTargets() { return m_Targets; }

  cmTarget* FindTarget(const char* name);

  /**
   * Get a list of include directories in the build.
   */
  std::vector<std::string>& GetIncludeDirectories()
    { 
      return m_IncludeDirectories;
    }
  const std::vector<std::string>& GetIncludeDirectories() const
    { 
      return m_IncludeDirectories;
    }
  void SetIncludeDirectories(const std::vector<std::string>& vec)
    {
      m_IncludeDirectories = vec;
    }

  /** Expand out any arguements in the vector that have ; separated
   *  strings into multiple arguements.  A new vector is created 
   *  containing the expanded versions of all arguments in argsIn.
   * This method differes from the one in cmSystemTools in that if
   * the CmakeLists file is version 1.2 or earlier it will check for
   * source lists being used without ${} around them
   */
  void ExpandSourceListArguments(std::vector<std::string> const& argsIn,
                                 std::vector<std::string>& argsOut,
                                 unsigned int startArgumentIndex);

  /** Get a cmSourceFile pointer for a given source name, if the name is
   *  not found, then a null pointer is returned.
   */
  cmSourceFile* GetSource(const char* sourceName) const;
  ///! Add a new cmSourceFile to the list of sources for this makefile.
  cmSourceFile* AddSource(cmSourceFile const&);

  /** Get a cmSourceFile pointer for a given source name, if the name is
   *  not found, then create the source file and return it. generated 
   * indicates if it is a generated file, this is used in determining
   * how to create the source file instance e.g. name
   */
  cmSourceFile* GetOrCreateSource(const char* sourceName, 
                                  bool generated = false);
  
  /**
   * Obtain a list of auxiliary source directories.
   */
  std::vector<std::string>& GetAuxSourceDirectories()
    {return m_AuxSourceDirectories;}

  //@{
  /**
   * Return a list of extensions associated with source and header
   * files
   */
  const std::vector<std::string>& GetSourceExtensions() const
    {return m_SourceFileExtensions;}
  const std::vector<std::string>& GetHeaderExtensions() const
    {return m_HeaderFileExtensions;}
  //@}

  /**
   * Given a variable name, return its value (as a string).
   * If the variable is not found in this makefile instance, the
   * cache is then queried.
   */
  const char* GetDefinition(const char*) const;
  const char* GetSafeDefinition(const char*) const;
  const char* GetRequiredDefinition(const char* name) const;
  /**
   * Get the list of all variables in the current space. If argument
   * cacheonly is specified and is greater than 0, then only cache
   * variables will be listed.
   */
  std::vector<std::string> GetDefinitions(int cacheonly=0) const;
  
  /** Test a boolean cache entry to see if it is true or false, 
   *  returns false if no entry defined.
   */
  bool IsOn(const char* name) const;
  bool IsSet(const char* name) const;

  /**
   * Get a list of preprocessor define flags.
   */
  const char* GetDefineFlags()
    {return m_DefineFlags.c_str();}
  
  /**
   * Get the vector of used command instances.
   */
  const std::vector<cmCommand*>& GetUsedCommands() const
    {return m_UsedCommands;}
  
  /**
   * Get the vector source groups.
   */
  const std::vector<cmSourceGroup>& GetSourceGroups() const
    { return m_SourceGroups; }

  /**
   * Get the source group
   */
  cmSourceGroup* GetSourceGroup(const char* name); 

  /**
   * Get the vector of list files on which this makefile depends
   */
  const std::vector<std::string>& GetListFiles() const
    { return m_ListFiles; }
  
  ///! When the file changes cmake will be re-run from the build system.
  void AddCMakeDependFile(const char* file)
    { m_ListFiles.push_back(file);}
  
  /**
   * Expand all defined variables in the string.  
   * Defined variables come from the m_Definitions map.
   * They are expanded with ${var} where var is the
   * entry in the m_Definitions map.  Also @var@ is
   * expanded to match autoconf style expansions.
   */
  const char *ExpandVariablesInString(std::string& source) const;
  const char *ExpandVariablesInString(std::string& source, bool escapeQuotes,
                                      bool noEscapes,
                                      bool atOnly = false,
                                      const char* filename = 0,
                                      long line = -1,
                                      bool removeEmpty = false) const;

  /**
   * Remove any remaining variables in the string. Anything with ${var} or
   * @var@ will be removed.  
   */
  void RemoveVariablesInString(std::string& source, bool atOnly = false) const;

  /**
   * Expand variables in the makefiles ivars such as link directories etc
   */
  void ExpandVariables();  

  /**
   * Replace variables and #cmakedefine lines in the given string.
   * See cmConfigureFileCommand for details.
   */
  void ConfigureString(const std::string& input, std::string& output,
                       bool atOnly, bool escapeQuotes);

  /**
   * Copy file but change lines acording to ConfigureString
   */
  int ConfigureFile(const char* infile, const char* outfile, 
                    bool copyonly, bool atOnly, bool escapeQuotes);

  /**
   * find what source group this source is in
   */
  cmSourceGroup& FindSourceGroup(const char* source,
                                 std::vector<cmSourceGroup> &groups);
  void RegisterData(cmData*);
  void RegisterData(const char*, cmData*);
  cmData* LookupData(const char*) const;
  
  /**
   * Execute a single CMake command.  Returns true if the command
   * succeeded or false if it failed.
   */
  bool ExecuteCommand(const cmListFileFunction& lff);
  
  /** Check if a command exists. */
  bool CommandExists(const char* name) const;
    
  /**
   * Add a command to this cmake instance
   */
  void AddCommand(cmCommand* );

  ///! Enable support for the named language, if null then all languages are enabled.
  void EnableLanguage(std::vector<std::string>const& languages);

  /**
   * Set/Get the name of the parent directories CMakeLists file
   * given a current CMakeLists file name
   */
  cmCacheManager *GetCacheManager() const;

  /**
   * Get the variable watch. This is used to determine when certain variables
   * are accessed.
   */
#ifdef CMAKE_BUILD_WITH_CMAKE
  cmVariableWatch* GetVariableWatch() const;
#endif

  ///! Display progress or status message.
  void DisplayStatus(const char*, float);
  
  /**
   * Expand the given list file arguments into the full set after
   * variable replacement and list expansion.
   */
  void ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
                       std::vector<std::string>& outArgs);
  /**
   * Get the instance
   */ 
  cmake *GetCMakeInstance() const;

  /**
   * Get all the source files this makefile knows about
   */
  const std::vector<cmSourceFile*> &GetSourceFiles() const 
    {return m_SourceFiles;}
  std::vector<cmSourceFile*> &GetSourceFiles() {return m_SourceFiles;}

  /**
   * Is there a source file that has the provided source file as an output?
   * if so then return it
   */
  cmSourceFile *GetSourceFileWithOutput(const char *outName);

  /**
   * Add a macro to the list of macros. The arguments should be name of the
   * macro and a documentation signature of it 
   */
  void AddMacro(const char* name, const char* signature);

  ///! Add a new cmTest to the list of tests for this makefile.
  cmTest* CreateTest(const char* testName);

  /** Get a cmTest pointer for a given test name, if the name is
   *  not found, then a null pointer is returned.
   */
  cmTest* GetTest(const char* testName) const;
  const std::vector<cmTest*> *GetTests() const;
  std::vector<cmTest*> *GetTests();

  /**
   * Get a list of macros as a ; separated string
   */
  void GetListOfMacros(std::string& macros);

  /**
   * Return a location of a file in cmake or custom modules directory
   */
  std::string GetModulesFile(const char* name);

  ///! Set/Get a property of this directory 
  void SetProperty(const char *prop, const char *value);
  const char *GetProperty(const char *prop) const;
  bool GetPropertyAsBool(const char *prop) const;

  typedef std::map<cmStdString, cmStdString> DefinitionMap;
  ///! Initialize a makefile from its parent
  void InitializeFromParent();
  
  ///! Set/Get the preorder flag
  void SetPreOrder(bool p) { this->PreOrder = p; }
  bool GetPreOrder() { return this->PreOrder; }
    
protected:
  // add link libraries and directories to the target
  void AddGlobalLinkInformation(const char* name, cmTarget& target);
  
  std::string m_Prefix;
  std::vector<std::string> m_AuxSourceDirectories; // 

  std::string m_cmStartDirectory; 
  std::string m_StartOutputDirectory; 
  std::string m_cmHomeDirectory; 
  std::string m_HomeOutputDirectory;
  std::string m_cmCurrentListFile;

  std::string m_ProjectName;    // project name

  // libraries, classes, and executables
  cmTargets m_Targets;
  std::vector<cmSourceFile*> m_SourceFiles;

  // Tests
  std::vector<cmTest*> m_Tests;
  
  // The include and link-library paths.  These may have order
  // dependency, so they must be vectors (not set).
  std::vector<std::string> m_IncludeDirectories;
  std::vector<std::string> m_LinkDirectories;
  
  std::vector<std::string> m_ListFiles; // list of command files loaded
  
  
  cmTarget::LinkLibraries m_LinkLibraries;

  std::string m_IncludeFileRegularExpression;
  std::string m_ComplainFileRegularExpression;
  std::vector<std::string> m_SourceFileExtensions;
  std::vector<std::string> m_HeaderFileExtensions;
  std::string m_DefineFlags;
  std::vector<cmSourceGroup> m_SourceGroups;
  DefinitionMap m_Definitions;
  std::vector<cmCommand*> m_UsedCommands;
  cmLocalGenerator* m_LocalGenerator;
  bool IsFunctionBlocked(const cmListFileFunction& lff);
  
private:

  void ReadSources(std::ifstream& fin, bool t);
  friend class cmMakeDepend;    // make depend needs direct access 
                                // to the m_Sources array 
  void PrintStringVector(const char* s, const std::vector<std::pair<cmStdString, bool> >& v) const;
  void PrintStringVector(const char* s, const std::vector<std::string>& v) const;
  void AddDefaultDefinitions();
  std::list<cmFunctionBlocker *> m_FunctionBlockers;

  typedef std::map<cmStdString, cmData*> DataMap;
  DataMap m_DataMap;

  typedef std::map<cmStdString, cmStdString> StringStringMap;
  StringStringMap m_MacrosMap;

  std::map<cmStdString, bool> m_SubDirectoryOrder;
  // used in AddDefinition for performance improvement
  DefinitionMap::key_type  m_TemporaryDefinitionKey;

  cmsys::RegularExpression m_cmDefineRegex;
  cmsys::RegularExpression m_cmDefine01Regex;

  std::map<cmStdString,cmStdString> m_Properties;

  // should this makefile be processed before or after processing the parent
  bool PreOrder;
};


#endif