ENH: make properties a bit more formal with documentation and chaining

This commit is contained in:
Ken Martin 2006-12-07 09:45:32 -05:00
parent 833548f53a
commit 27379d7b08
44 changed files with 1131 additions and 128 deletions

View File

@ -146,10 +146,10 @@ SET(SRCS
cmProperty.h
cmPropertyDefinition.cxx
cmPropertyDefinition.h
# cmPropertyDefinitionMap.cxx
# cmPropertyDefinitionMap.h
# cmPropertyMap.cxx
# cmPropertyMap.h
cmPropertyDefinitionMap.cxx
cmPropertyDefinitionMap.h
cmPropertyMap.cxx
cmPropertyMap.h
cmSourceFile.cxx
cmSourceFile.h
cmSourceGroup.cxx

View File

@ -69,6 +69,8 @@ bool cmAuxSourceDirectoryCommand::InitialPass
// add the file as a class file so
// depends can be done
cmSourceFile cmfile;
cmfile.GetProperties().SetCMakeInstance
(this->Makefile->GetCMakeInstance());
cmfile.SetName(fullname.c_str(),
this->Makefile->GetCurrentDirectory(),
this->Makefile->GetSourceExtensions(),

View File

@ -507,6 +507,14 @@ void * CCONV cmCreateSourceFile()
return (void *)(new cmSourceFile);
}
void * CCONV cmCreateNewSourceFile(void *arg)
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
cmSourceFile *sf = new cmSourceFile;
sf->GetProperties().SetCMakeInstance(mf->GetCMakeInstance());
return (void *)sf;
}
void CCONV cmDestroySourceFile(void *arg)
{
cmSourceFile *sf = static_cast<cmSourceFile *>(arg);
@ -624,6 +632,16 @@ void CCONV cmFree(void *data)
free(data);
}
void CCONV DefineSourceFileProperty (void *arg, const char *name,
const char *briefDocs,
const char *longDocs,
int chained)
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
mf->GetCMakeInstance()->DefineProperty(name,cmProperty::SOURCE_FILE,
briefDocs, longDocs,chained);
}
} // close the extern "C" scope
cmCAPI cmStaticCAPI =
@ -683,5 +701,7 @@ cmCAPI cmStaticCAPI =
cmAddCustomCommandToOutput,
cmAddCustomCommandToTarget,
cmDisplayStatus,
cmCreateNewSourceFile,
DefineSourceFileProperty,
};

View File

@ -170,6 +170,13 @@ typedef struct
/* display status information */
void (CCONV *DisplaySatus) (void *info, const char *message);
/* new functions added after 2.4 */
void *(CCONV *CreateNewSourceFile) (void *mf);
void (CCONV *DefineSourceFileProperty) (void *mf, const char *name,
const char *briefDocs,
const char *longDocs,
int chained);
/* this is the end of the C function stub API structure */
} cmCAPI;

View File

@ -20,6 +20,7 @@
#include "cmAuxSourceDirectoryCommand.cxx"
#include "cmBuildNameCommand.cxx"
#include "cmCreateTestSourceList.cxx"
#include "cmDefinePropertyCommand.cxx"
#include "cmElseIfCommand.cxx"
#include "cmEnableLanguageCommand.cxx"
#include "cmEndMacroCommand.cxx"
@ -44,6 +45,7 @@
#include "cmRemoveDefinitionsCommand.cxx"
#include "cmSeparateArgumentsCommand.cxx"
#include "cmSetDirectoryPropertiesCommand.cxx"
#include "cmSetPropertiesCommand.cxx"
#include "cmSetTargetPropertiesCommand.cxx"
#include "cmSetTestsPropertiesCommand.cxx"
#include "cmSourceGroupCommand.cxx"
@ -75,6 +77,7 @@ void GetPredefinedCommands(std::list<cmCommand*>&
commands.push_back(new cmAuxSourceDirectoryCommand);
commands.push_back(new cmBuildNameCommand);
commands.push_back(new cmCreateTestSourceList);
commands.push_back(new cmDefinePropertyCommand);
commands.push_back(new cmElseIfCommand);
commands.push_back(new cmEnableLanguageCommand);
commands.push_back(new cmEndMacroCommand);
@ -100,6 +103,7 @@ void GetPredefinedCommands(std::list<cmCommand*>&
commands.push_back(new cmRemoveDefinitionsCommand);
commands.push_back(new cmSeparateArgumentsCommand);
commands.push_back(new cmSetDirectoryPropertiesCommand);
commands.push_back(new cmSetPropertiesCommand);
commands.push_back(new cmSetTargetPropertiesCommand);
commands.push_back(new cmSetTestsPropertiesCommand);
commands.push_back(new cmSourceGroupCommand);

View File

@ -172,6 +172,7 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args)
// Create the source list
cmSourceFile cfile;
cfile.GetProperties().SetCMakeInstance(this->Makefile->GetCMakeInstance());
std::string sourceListValue;
cfile.SetProperty("ABSTRACT","0");
@ -185,6 +186,8 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args)
for(i = testsBegin; i != tests.end(); ++i)
{
cmSourceFile icfile;
icfile.GetProperties().
SetCMakeInstance(this->Makefile->GetCMakeInstance());
icfile.SetProperty("ABSTRACT","0");
icfile.SetName(i->c_str(),
this->Makefile->GetCurrentDirectory(),

View File

@ -0,0 +1,64 @@
/*=========================================================================
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.
=========================================================================*/
#include "cmDefinePropertyCommand.h"
#include "cmake.h"
// cmDefinePropertiesCommand
bool cmDefinePropertyCommand::InitialPass(
std::vector<std::string> const& args)
{
if(args.size() < 5 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
// determine the scope
cmProperty::ScopeType scope;
if (args[1] == "GLOBAL")
{
scope = cmProperty::GLOBAL;
}
else if (args[1] == "DIRECTORY")
{
scope = cmProperty::DIRECTORY;
}
else if (args[1] == "TARGET")
{
scope = cmProperty::TARGET;
}
else if (args[1] == "SOURCE_FILE")
{
scope = cmProperty::SOURCE_FILE;
}
else if (args[1] == "TEST")
{
scope = cmProperty::TEST;
}
else
{
this->SetError("called with illegal arguments.");
return false;
}
this->Makefile->GetCMakeInstance()->DefineProperty
(args[0].c_str(), scope,args[2].c_str(), args[3].c_str(),
cmSystemTools::IsOn(args[4].c_str()));
return true;
}

View File

@ -0,0 +1,74 @@
/*=========================================================================
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 cmDefinesPropertyCommand_h
#define cmDefinesPropertyCommand_h
#include "cmCommand.h"
class cmDefinePropertyCommand : public cmCommand
{
public:
virtual cmCommand* Clone()
{
return new cmDefinePropertyCommand;
}
/**
* This is called when the command is first encountered in
* the input file.
*/
virtual bool InitialPass(std::vector<std::string> const& args);
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() { return "DEFINE_PROPERTY";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return "Define properties used by CMake.";
}
/**
* Longer documentation.
*/
virtual const char* GetFullDocumentation()
{
return
" DEFINE_PROPERTY(property_name scope_value\n"
" short_description\n"
" full_description chain)\n"
"Define a property for a scope. The scope_value is either GLOBAL "
"DIRECTORY, TARGET, TEST, SOURCE_FILE. The short and full "
"descriptions are used to document the property, chain indicates "
"if that property chains such that a request for the property "
"on a target will chain up to the directory if it is not set on the "
"target. In such cases the property's scope is the most specific. "
"In that example the scope would be TARGET even though it can "
"chain up to DIRECTORY and GLOBAL."
;
}
cmTypeMacro(cmDefinePropertyCommand, cmCommand);
};
#endif

View File

@ -51,6 +51,14 @@ static const cmDocumentationEntry cmDocumentationCommandsHeader[] =
{0,0,0}
};
//----------------------------------------------------------------------------
static const cmDocumentationEntry cmDocumentationPropertiesHeader[] =
{
{0,
"The following properties are available in CMakeLists.txt code:", 0},
{0,0,0}
};
//----------------------------------------------------------------------------
static const cmDocumentationEntry cmDocumentationModulesHeader[] =
{
@ -226,8 +234,11 @@ bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os)
return this->PrintDocumentationSingle(os);
case cmDocumentation::SingleModule:
return this->PrintDocumentationSingleModule(os);
case cmDocumentation::SingleProperty:
return this->PrintDocumentationSingleProperty(os);
case cmDocumentation::List: return this->PrintDocumentationList(os);
case cmDocumentation::ModuleList: return this->PrintModuleList(os);
case cmDocumentation::PropertyList: return this->PrintPropertyList(os);
case cmDocumentation::Full: return this->PrintDocumentationFull(os);
case cmDocumentation::HTML: return this->PrintDocumentationHTML(os);
case cmDocumentation::Man: return this->PrintDocumentationMan(os);
@ -470,6 +481,15 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv)
i = i+1;
}
}
else if(strcmp(argv[i], "--help-property") == 0)
{
type = cmDocumentation::SingleProperty;
if((i+1 < argc) && !this->IsOption(argv[i+1]))
{
this->SinglePropertyName = argv[i+1];
i = i+1;
}
}
else if(strcmp(argv[i], "--help-command-list") == 0)
{
type = cmDocumentation::List;
@ -478,6 +498,10 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv)
{
type = cmDocumentation::ModuleList;
}
else if(strcmp(argv[i], "--help-property-list") == 0)
{
type = cmDocumentation::PropertyList;
}
else if(strcmp(argv[i], "--copyright") == 0)
{
type = cmDocumentation::Copyright;
@ -555,6 +579,13 @@ void cmDocumentation::SetCommandsSection(const cmDocumentationEntry* section)
this->CommandsSection);
}
//----------------------------------------------------------------------------
void cmDocumentation::SetPropertiesSection(const cmDocumentationEntry* section)
{
this->SetSection(cmDocumentationPropertiesHeader, section, 0,
this->PropertiesSection);
}
//----------------------------------------------------------------------------
void cmDocumentation
::SetGeneratorsSection(const cmDocumentationEntry* section)
@ -1118,6 +1149,35 @@ bool cmDocumentation::PrintDocumentationSingleModule(std::ostream& os)
return false;
}
//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationSingleProperty(std::ostream& os)
{
if(this->PropertiesSection.empty())
{
os << "Internal error: properties list is empty." << std::endl;
return false;
}
if(this->SinglePropertyName.length() == 0)
{
os << "Argument --help-property needs a property name.\n";
return false;
}
for(cmDocumentationEntry* entry = &this->PropertiesSection[0];
entry->brief; ++entry)
{
if(entry->name && this->SinglePropertyName == entry->name)
{
this->PrintDocumentationCommand(os, entry);
return true;
}
}
// Argument was not a command. Complain.
os << "Argument \"" << this->SinglePropertyName.c_str()
<< "\" to --help-property is not a CMake property. "
<< "Use --help-property-list to see all properties.\n";
return false;
}
//----------------------------------------------------------------------------
bool cmDocumentation::PrintDocumentationList(std::ostream& os)
{
@ -1137,6 +1197,25 @@ bool cmDocumentation::PrintDocumentationList(std::ostream& os)
return true;
}
//----------------------------------------------------------------------------
bool cmDocumentation::PrintPropertyList(std::ostream& os)
{
if(this->PropertiesSection.empty())
{
os << "Internal error: properties list is empty." << std::endl;
return false;
}
for(cmDocumentationEntry* entry = &this->PropertiesSection[0];
entry->brief; ++entry)
{
if(entry->name)
{
os << entry->name << std::endl;
}
}
return true;
}
//----------------------------------------------------------------------------
bool cmDocumentation::PrintModuleList(std::ostream& os)
{
@ -1261,6 +1340,10 @@ void cmDocumentation::CreateFullDocumentation()
{
this->AddSection("Standard CMake Modules", &this->ModulesSection[0]);
}
if(!this->PropertiesSection.empty())
{
this->AddSection("Standard Properties", &this->PropertiesSection[0]);
}
this->AddSection("Copyright", cmDocumentationCopyright);
this->AddSection("See Also", cmDocumentationStandardSeeAlso);
}

View File

@ -29,7 +29,8 @@ public:
// High-level interface for standard documents:
/** Types of help provided. */
enum Type { None, Usage, Single, SingleModule, List, ModuleList,
enum Type { None, Usage, Single, SingleModule, SingleProperty,
List, ModuleList, PropertyList,
Full, HTML, Man, Copyright, Version };
/**
@ -70,6 +71,9 @@ public:
/** Set the listfile commands for standard document generation. */
void SetCommandsSection(const cmDocumentationEntry*);
/** Set the properties for standard document generation. */
void SetPropertiesSection(const cmDocumentationEntry*);
/** Set the generator descriptions for standard document generation. */
void SetGeneratorsSection(const cmDocumentationEntry*);
@ -132,8 +136,10 @@ private:
bool PrintVersion(std::ostream& os);
bool PrintDocumentationList(std::ostream& os);
bool PrintModuleList(std::ostream& os);
bool PrintPropertyList(std::ostream& os);
bool PrintDocumentationSingle(std::ostream& os);
bool PrintDocumentationSingleModule(std::ostream& os);
bool PrintDocumentationSingleProperty(std::ostream& os);
bool PrintDocumentationUsage(std::ostream& os);
bool PrintDocumentationFull(std::ostream& os);
bool PrintDocumentationHTML(std::ostream& os);
@ -159,11 +165,13 @@ private:
std::vector<cmDocumentationEntry> OptionsSection;
std::vector<cmDocumentationEntry> CommandsSection;
std::vector<cmDocumentationEntry> ModulesSection;
std::vector<cmDocumentationEntry> PropertiesSection;
std::vector<cmDocumentationEntry> GeneratorsSection;
std::vector<cmDocumentationEntry> SeeAlsoSection;
std::string SeeAlsoString;
std::string SingleCommand;
std::string SingleModuleName;
std::string SinglePropertyName;
std::string CMakeRoot;
std::vector< char* > ModuleStrings;
std::vector< const char* > Names;

View File

@ -54,6 +54,8 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args)
if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE"))
{
cmSourceFile header_file;
header_file.GetProperties().SetCMakeInstance
(this->Makefile->GetCMakeInstance());
std::string srcName = cmSystemTools::GetFilenameWithoutExtension(*i);
const bool headerFileOnly = true;
header_file.SetName(srcName.c_str(),

View File

@ -87,7 +87,8 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf)
mf.ExpandArguments(lff.Arguments, expandedArguments);
if ((!expandedArguments.empty() &&
(expandedArguments[0] == this->Args[0]))
|| mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS"))
|| cmSystemTools::IsOn
(mf.GetPropertyOrDefinition("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS")))
{
return true;
}

View File

@ -1595,6 +1595,7 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(
{
// Package
cmTarget target;
target.GetProperties().SetCMakeInstance(this->CMakeInstance);
target.SetType(cmTarget::GLOBAL_TARGET, name);
target.SetInAll(false);

View File

@ -96,7 +96,8 @@ bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
{
if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endif"))
{
if (mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS")
if (cmSystemTools::IsOn
(mf.GetPropertyOrDefinition("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS"))
|| lff.Arguments == this->Args)
{
return true;

View File

@ -36,8 +36,9 @@ bool cmInstallFilesCommand
// Create an INSTALL_FILES target specifically for this path.
this->TargetName = "INSTALL_FILES_"+args[0];
cmTarget& target = this->Makefile->GetTargets()[this->TargetName];
target.SetInAll(false);
target.SetType(cmTarget::INSTALL_FILES, this->TargetName.c_str());
target.SetMakefile(this->Makefile);
target.SetInAll(false);
target.SetInstallPath(args[0].c_str());
if((args.size() > 1) && (args[1] == "FILES"))

View File

@ -33,8 +33,9 @@ bool cmInstallProgramsCommand
// Create an INSTALL_PROGRAMS target specifically for this path.
this->TargetName = "INSTALL_PROGRAMS_"+args[0];
cmTarget& target = this->Makefile->GetTargets()[this->TargetName];
target.SetInAll(false);
target.SetType(cmTarget::INSTALL_PROGRAMS, this->TargetName.c_str());
target.SetMakefile(this->Makefile);
target.SetInAll(false);
target.SetInstallPath(args[0].c_str());
std::vector<std::string>::const_iterator s = args.begin();

View File

@ -117,6 +117,7 @@ void cmLocalGenerator::SetGlobalGenerator(cmGlobalGenerator *gg)
this->GlobalGenerator = gg;
// setup the home directories
this->Makefile->GetProperties().SetCMakeInstance(gg->GetCMakeInstance());
this->Makefile->SetHomeDirectory(
gg->GetCMakeInstance()->GetHomeDirectory());
this->Makefile->SetHomeOutputDirectory(
@ -200,15 +201,15 @@ void cmLocalGenerator::GenerateTestFiles()
fout << "\"";
}
fout << ")" << std::endl;
std::map<cmStdString,cmStdString>::const_iterator pit;
const std::map<cmStdString,cmStdString>* mpit = &test->GetProperties();
cmPropertyMap::const_iterator pit;
cmPropertyMap* mpit = &test->GetProperties();
if ( mpit->size() )
{
fout << "SET_TESTS_PROPERTIES(" << test->GetName() << " PROPERTIES ";
for ( pit = mpit->begin(); pit != mpit->end(); ++ pit )
{
fout << " " << pit->first.c_str() << " \"";
const char* value = pit->second.c_str();
const char* value = pit->second.GetValue();
for ( ; *value; ++ value )
{
switch ( *value )

View File

@ -316,7 +316,8 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf)
mf.ExpandArguments(lff.Arguments, expandedArguments);
if ((!expandedArguments.empty() &&
(expandedArguments[0] == this->Args[0]))
|| mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS"))
|| cmSystemTools::IsOn
(mf.GetPropertyOrDefinition("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS")))
{
return true;
}

View File

@ -816,9 +816,9 @@ void cmMakefile::AddUtilityCommand(const char* utilityName, bool all,
{
// Create a target instance for this utility.
cmTarget target;
target.SetMakefile(this);
target.SetType(cmTarget::UTILITY, utilityName);
target.SetInAll(all);
target.SetMakefile(this);
if(!comment)
{
@ -1309,6 +1309,7 @@ void cmMakefile::AddLibrary(const char* lname, int shared,
default:
target.SetType(cmTarget::STATIC_LIBRARY, lname);
}
target.SetMakefile(this);
// Clear its dependencies. Otherwise, dependencies might persist
// over changes in CMakeLists.txt, making the information stale and
@ -1316,7 +1317,6 @@ void cmMakefile::AddLibrary(const char* lname, int shared,
target.ClearDependencyInformation( *this, lname );
target.SetInAll(in_all);
target.GetSourceLists() = srcs;
target.SetMakefile(this);
this->AddGlobalLinkInformation(lname, target);
cmTargets::iterator it =
this->Targets.insert(cmTargets::value_type(lname,target)).first;
@ -1329,9 +1329,9 @@ cmTarget* cmMakefile::AddExecutable(const char *exeName,
{
cmTarget target;
target.SetType(cmTarget::EXECUTABLE, exeName);
target.SetMakefile(this);
target.SetInAll(in_all);
target.GetSourceLists() = srcs;
target.SetMakefile(this);
this->AddGlobalLinkInformation(exeName, target);
cmTargets::iterator it =
this->Targets.insert(cmTargets::value_type(exeName,target)).first;
@ -2281,6 +2281,7 @@ cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
// we must create one
cmSourceFile file;
file.GetProperties().SetCMakeInstance(this->GetCMakeInstance());
std::string path = cmSystemTools::GetFilenamePath(src);
if(generated)
{
@ -2328,6 +2329,7 @@ cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
this->AddSource(file);
src = file.GetFullPath();
ret = this->GetSource(src.c_str());
ret->GetProperties().SetCMakeInstance(this->GetCMakeInstance());
if (!ret)
{
cmSystemTools::Error(
@ -2738,10 +2740,27 @@ void cmMakefile::SetProperty(const char* prop, const char* value)
{
value = "NOTFOUND";
}
this->Properties[prop] = value;
this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY);
}
const char *cmMakefile::GetPropertyOrDefinition(const char* prop)
{
const char *ret = this->GetProperty(prop, cmProperty::DIRECTORY);
if (!ret)
{
ret = this->GetDefinition(prop);
}
return ret;
}
const char *cmMakefile::GetProperty(const char* prop)
{
return this->GetProperty(prop, cmProperty::DIRECTORY);
}
const char *cmMakefile::GetProperty(const char* prop,
cmProperty::ScopeType scope)
{
// watch for specific properties
if (!strcmp("PARENT_DIRECTORY",prop))
@ -2764,24 +2783,21 @@ const char *cmMakefile::GetProperty(const char* prop)
}
this->SetProperty("LISTFILE_STACK",tmp.c_str());
}
std::map<cmStdString,cmStdString>::const_iterator i =
this->Properties.find(prop);
if (i != this->Properties.end())
bool chain = false;
const char *retVal =
this->Properties.GetPropertyValue(prop, scope, chain);
if (chain)
{
return i->second.c_str();
return this->GetCMakeInstance()->GetProperty(prop,scope);
}
return 0;
return retVal;
}
bool cmMakefile::GetPropertyAsBool(const char* prop) const
bool cmMakefile::GetPropertyAsBool(const char* prop)
{
std::map<cmStdString,cmStdString>::const_iterator i =
this->Properties.find(prop);
if (i != this->Properties.end())
{
return cmSystemTools::IsOn(i->second.c_str());
}
return false;
return cmSystemTools::IsOn(this->GetProperty(prop));
}
@ -2810,6 +2826,7 @@ cmTest* cmMakefile::CreateTest(const char* testName)
}
test = new cmTest;
test->SetName(testName);
test->SetMakefile(this);
this->Tests.push_back(test);
return test;
}
@ -2855,3 +2872,43 @@ std::string cmMakefile::GetListFileStack()
}
return tmp;
}
// define properties
void cmMakefile::DefineProperties(cmake *cm)
{
cm->DefineProperty
("ADDITIONAL_MAKE_CLEAN_FILES", cmProperty::DIRECTORY,
"Addditional files to clean during the make clean stage.",
"A list of files that will be cleaned as a part of the "
"\"make clean\" stage. ");
cm->DefineProperty
("CLEAN_NO_CUSTOM", cmProperty::DIRECTORY,
"Should the output of custom commands be left.",
"If this is true then the outputs of custom commands for this "
"directory will not be removed during the \"make clean\" stage. ");
cm->DefineProperty
("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS", cmProperty::DIRECTORY,
"Allow loops to have non-matching closing statements.",
"If this is set then the closing statement of control "
"structures in CMake will not require an exact match to the "
"opening statement. For example IF(foo) will not require "
"ENDIF(foo) but simple ENDIF() will work.",
true);
cm->DefineProperty
("LISTFILE_STACK", cmProperty::DIRECTORY,
"The current stack of listfiles being processed.",
"This property is mainly useful when trying to debug errors "
"in your CMake scripts. It returns a list of what list files "
"are currently being processed, in order. So if one listfile "
"does an INCLUDE command then that is effectively pushing "
"the included listfile onto the stack.");
cm->DefineProperty
("TEST_INCLUDE_FILE", cmProperty::DIRECTORY,
"A cmake file that will be included when ctest is run.",
"If you specify TEST_INCLUDE_FILE, that file will be "
"included and processed when ctest is run on the directory.");
}

View File

@ -22,6 +22,7 @@
#include "cmTarget.h"
#include "cmListFileCache.h"
#include "cmCacheManager.h"
#include "cmPropertyMap.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
#include "cmSourceGroup.h"
@ -697,7 +698,12 @@ public:
///! Set/Get a property of this directory
void SetProperty(const char *prop, const char *value);
const char *GetProperty(const char *prop);
bool GetPropertyAsBool(const char *prop) const;
const char *GetPropertyOrDefinition(const char *prop);
const char *GetProperty(const char *prop, cmProperty::ScopeType scope);
bool GetPropertyAsBool(const char *prop);
// Get the properties
cmPropertyMap &GetProperties() { return this->Properties; };
typedef std::map<cmStdString, cmStdString> DefinitionMap;
///! Initialize a makefile from its parent
@ -711,6 +717,10 @@ public:
{ this->InstallGenerators.push_back(g); }
std::vector<cmInstallGenerator*>& GetInstallGenerators()
{ return this->InstallGenerators; }
// Define the properties
static void DefineProperties(cmake *cm);
protected:
// add link libraries and directories to the target
void AddGlobalLinkInformation(const char* name, cmTarget& target);
@ -791,7 +801,7 @@ private:
cmsys::RegularExpression cmDefineRegex;
cmsys::RegularExpression cmDefine01Regex;
std::map<cmStdString,cmStdString> Properties;
cmPropertyMap Properties;
// should this makefile be processed before or after processing the parent
bool PreOrder;

View File

@ -18,6 +18,9 @@
#include "cmSystemTools.h"
#include "cmake.h"
// define STRICT to get checking of all set and get property calls
//#define STRICT
cmProperty *cmPropertyMap::GetOrCreateProperty(const char *name)
{
cmPropertyMap::iterator it = this->find(name);
@ -41,7 +44,7 @@ void cmPropertyMap::SetProperty(const char *name, const char *value,
return;
}
#if 0
#ifdef STRICT
if (!this->CMakeInstance)
{
cmSystemTools::Error("CMakeInstance not set on a property map!");
@ -92,7 +95,7 @@ const char *cmPropertyMap
}
// has the property been defined?
#if 0
#ifdef STRICT
if (!this->CMakeInstance)
{
cmSystemTools::Error("CMakeInstance not set on a property map!");
@ -131,7 +134,10 @@ const char *cmPropertyMap
if (it == this->end())
{
// should we chain up?
chain = this->CMakeInstance->IsPropertyChained(name,scope);
if (this->CMakeInstance)
{
chain = this->CMakeInstance->IsPropertyChained(name,scope);
}
return 0;
}

View File

@ -28,58 +28,73 @@ bool cmSetDirectoryPropertiesCommand::InitialPass(
return false;
}
std::vector<std::string>::const_iterator ait;
for ( ait = args.begin()+1;
ait != args.end();
ait += 2 )
std::string errors;
bool ret =
cmSetDirectoryPropertiesCommand::RunCommand(this->Makefile,
args.begin() + 1,
args.end(), errors);
if (!ret)
{
if ( ait +1 == args.end() )
this->SetError(errors.c_str());
}
return ret;
}
bool cmSetDirectoryPropertiesCommand
::RunCommand(cmMakefile *mf,
std::vector<std::string>::const_iterator ait,
std::vector<std::string>::const_iterator aitend,
std::string &errors)
{
for (; ait != aitend; ait += 2 )
{
if ( ait +1 == aitend)
{
this->SetError("Wrong number of arguments");
errors = "Wrong number of arguments";
return false;
}
const std::string& prop = *ait;
const std::string& value = *(ait+1);
if ( prop == "VARIABLES" )
{
this->SetError
("Variables and cache variables should be set using SET command");
errors =
"Variables and cache variables should be set using SET command";
return false;
}
else if ( prop == "MACROS" )
{
this->SetError
("Commands and macros cannot be set using SET_CMAKE_PROPERTIES");
errors =
"Commands and macros cannot be set using SET_CMAKE_PROPERTIES";
return false;
}
else if ( prop == "INCLUDE_DIRECTORIES" )
{
std::vector<std::string> varArgsExpanded;
cmSystemTools::ExpandListArgument(value, varArgsExpanded);
this->Makefile->SetIncludeDirectories(varArgsExpanded);
mf->SetIncludeDirectories(varArgsExpanded);
}
else if ( prop == "LINK_DIRECTORIES" )
{
std::vector<std::string> varArgsExpanded;
cmSystemTools::ExpandListArgument(value, varArgsExpanded);
this->Makefile->SetLinkDirectories(varArgsExpanded);
mf->SetLinkDirectories(varArgsExpanded);
}
else if ( prop == "INCLUDE_REGULAR_EXPRESSION" )
{
this->Makefile->SetIncludeRegularExpression(value.c_str());
mf->SetIncludeRegularExpression(value.c_str());
}
else
{
if ( prop == "ADDITIONAL_MAKE_CLEAN_FILES" )
{
// This property is not inherrited
if ( strcmp(this->Makefile->GetCurrentDirectory(),
this->Makefile->GetStartDirectory()) != 0 )
if ( strcmp(mf->GetCurrentDirectory(),
mf->GetStartDirectory()) != 0 )
{
continue;
}
}
this->Makefile->SetProperty(prop.c_str(), value.c_str());
mf->SetProperty(prop.c_str(), value.c_str());
}
}

View File

@ -51,6 +51,14 @@ public:
return "Set a property of the directory.";
}
/**
* Static entry point for use by other commands
*/
static bool RunCommand(cmMakefile *mf,
std::vector<std::string>::const_iterator ait,
std::vector<std::string>::const_iterator aitend,
std::string &errors);
/**
* Longer documentation.
*/

View File

@ -71,26 +71,13 @@ bool cmSetTargetPropertiesCommand::InitialPass(
return false;
}
cmTargets& targets = this->Makefile->GetTargets();
// now loop over all the targets
int i;
unsigned int k;
for(i = 0; i < numFiles; ++i)
{
// if the file is already in the makefile just set properites on it
cmTargets::iterator t = targets.find(args[i]);
if ( t != targets.end())
{
cmTarget& target = t->second;
// now loop through all the props and set them
for (k = 0; k < propertyPairs.size(); k = k + 2)
{
target.SetProperty(propertyPairs[k].c_str(),
propertyPairs[k+1].c_str());
}
}
// if file is not already in the makefile, then add it
else
bool ret = cmSetTargetPropertiesCommand::SetOneTarget
(args[i].c_str(),propertyPairs,this->Makefile);
if (!ret)
{
std::string message = "Can not find target to add properties to: ";
message += args[i];
@ -101,3 +88,30 @@ bool cmSetTargetPropertiesCommand::InitialPass(
return true;
}
bool cmSetTargetPropertiesCommand
::SetOneTarget(const char *tname,
std::vector<std::string> &propertyPairs,
cmMakefile *mf)
{
cmTargets& targets = mf->GetTargets();
// if the file is already in the makefile just set properites on it
cmTargets::iterator t = targets.find(tname);
if ( t != targets.end())
{
cmTarget& target = t->second;
// now loop through all the props and set them
unsigned int k;
for (k = 0; k < propertyPairs.size(); k = k + 2)
{
target.SetProperty(propertyPairs[k].c_str(),
propertyPairs[k+1].c_str());
}
}
// if file is not already in the makefile, then add it
else
{
return false;
}
return true;
}

View File

@ -46,6 +46,13 @@ public:
return "Targets can have properties that affect how they are built.";
}
/**
* Used by this command and cmSetPropertiesCommand
*/
static bool SetOneTarget(const char *tname,
std::vector<std::string> &propertyPairs,
cmMakefile *mf);
/**
* Longer documentation.
*/

View File

@ -17,7 +17,7 @@
#include "cmSourceFile.h"
#include "cmSystemTools.h"
#include "cmake.h"
// Set the name of the class and the full path to the file.
// The class must be found in dir and end in name.cxx, name.txx,
@ -179,7 +179,8 @@ void cmSourceFile::SetProperty(const char* prop, const char* value)
{
value = "NOTFOUND";
}
this->Properties[prop] = value;
this->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE);
}
const char *cmSourceFile::GetProperty(const char* prop) const
@ -191,24 +192,14 @@ const char *cmSourceFile::GetProperty(const char* prop) const
return this->FullPath.c_str();
}
std::map<cmStdString,cmStdString>::const_iterator i =
this->Properties.find(prop);
if (i != this->Properties.end())
{
return i->second.c_str();
}
return 0;
bool chain = false;
return this->Properties.GetPropertyValue(prop,cmProperty::SOURCE_FILE,
chain);
}
bool cmSourceFile::GetPropertyAsBool(const char* prop) const
{
std::map<cmStdString,cmStdString>::const_iterator i =
this->Properties.find(prop);
if (i != this->Properties.end())
{
return cmSystemTools::IsOn(i->second.c_str());
}
return false;
return cmSystemTools::IsOn(this->GetProperty(prop));
}
void cmSourceFile::SetCustomCommand(cmCustomCommand* cc)
@ -229,3 +220,115 @@ const std::string& cmSourceFile::GetSourceNameWithoutLastExtension()
}
return this->SourceNameWithoutLastExtension;
}
cmSourceFile::cmSourceFile()
{
this->CustomCommand = 0;
}
// define properties
void cmSourceFile::DefineProperties(cmake *cm)
{
// define properties
cm->DefineProperty
("ABSTRACT", cmProperty::SOURCE_FILE,
"Is this source file an abstract class.",
"A property ona source file that indicates if the source file "
"represents a class that is abstract. This only makes sense for "
"languages that have a notion of an abstract class and it is "
"only used by somw tools that wrap classes into other languages.");
cm->DefineProperty
("COMPILE_FLAGS", cmProperty::SOURCE_FILE,
"Additional flags to be added when compiling this source file.",
"These flags will be added to the list of compile flags when "
"this source file.");
cm->DefineProperty
("EXTERNAL_OBJECT", cmProperty::SOURCE_FILE,
"If set to true then this is an object file.",
"If this property is set to true then the source file "
"is really an object file and should not be compiled. "
"It will still be linked into the target though.");
cm->DefineProperty
("EXTRA_CONTENT", cmProperty::SOURCE_FILE,
"Is this file part of a target's extra content.",
"If this property is set, the source file will be added to the "
"target's list of extra content. This is used by makefile "
"generators for some sort of Mac budle framework support.");
cm->DefineProperty
("GENERATED", cmProperty::SOURCE_FILE,
"Is this source file generated as part of the build process.",
"If a source file is generated by the build process CMake will "
"handle it differently in temrs of dependency checking etc. "
"Otherwise having a non-existent source file could create problems.");
cm->DefineProperty
("HEADER_FILE_ONLY", cmProperty::SOURCE_FILE,
"Is this source file only a header file.",
"A property ona source file that indicates if the source file "
"is a header file with no associated implementation. This is "
"set automatically based on the file extension and is used by "
"CMake to determine is certain dependency information should be "
"computed.");
cm->DefineProperty
("KEEP_EXTENSION", cmProperty::SOURCE_FILE,
"Make th eoutput file have the same extension as the source file.",
"If this property is set then the file extension of the output "
"file will be the same as that of the source file. Normally "
"the output file extension is computed based on the language "
"of the source file, for example .cxx will go to a .o extension.");
cm->DefineProperty
("LANGUAGE", cmProperty::SOURCE_FILE,
"What programming language is the file.",
"A property that can be set to indicate what programming language "
"the source file is. If it is not set the language is determined "
"based on the file extension. Typical values are CXX C etc.");
cm->DefineProperty
("LOCATION", cmProperty::SOURCE_FILE,
"The full path to a source file.",
"A read only property on a SOURCE FILE that contains the full path "
"to the source file.");
cm->DefineProperty
("MACOSX_PACKAGE_LOCATION", cmProperty::SOURCE_FILE,
"Location for MACOSX bundles and frameworks.",
"MACOSX_PACKAGE_LOCATION is the property of a file within a mac osx "
"bundle or framework that specifies where this file should be "
"copied. This makes sense for things like icons and other "
"resources.");
cm->DefineProperty
("MACOSX_CONTENT", cmProperty::SOURCE_FILE,
"If true then this is part of a MACOSX bundle or framework.",
"MACOSX_CONTENT is a flag that if true this file will be copied "
"to the bundle or framework.");
cm->DefineProperty
("OBJECT_DEPENDS", cmProperty::SOURCE_FILE,
"Additional dependencies.",
"Additional dependencies that should be checked as part of "
"building this source file.");
cm->DefineProperty
("SYMBOLIC", cmProperty::SOURCE_FILE,
"Is this just a name for a rule.",
"If SYMBOLIC (boolean) is set to true the build system will be "
"informed that the source file is not actually created on disk but "
"instead used as a symbolic name for a build rule.");
cm->DefineProperty
("WRAP_EXCLUDE", cmProperty::SOURCE_FILE,
"Exclude this source file from any code wrapping techniques.",
"Some packages can wrap source files into alternate languages "
"to provide additional functionality. For example, C++ code "
"can be wrapped into Java or Python etc using SWIG etc. "
"If WRAP_EXCLUDE is set to true (1 etc) that indicates then "
"this source file should not be wrapped.");
}

View File

@ -18,6 +18,9 @@
#define cmSourceFile_h
#include "cmCustomCommand.h"
#include "cmPropertyMap.h"
class cmake;
/** \class cmSourceFile
* \brief Represent a class loaded from a makefile.
@ -32,10 +35,7 @@ public:
* Construct instance as a concrete class with both a
* .h and .cxx file.
*/
cmSourceFile()
{
this->CustomCommand = 0;
}
cmSourceFile();
~cmSourceFile()
{
this->SetCustomCommand(0);
@ -108,8 +108,14 @@ public:
*/
const std::string& GetSourceNameWithoutLastExtension();
// Get the properties
cmPropertyMap &GetProperties() { return this->Properties; };
// Define the properties
static void DefineProperties(cmake *cm);
private:
std::map<cmStdString,cmStdString> Properties;
cmPropertyMap Properties;
cmCustomCommand *CustomCommand;
std::string FullPath;
std::string SourceName;

View File

@ -15,6 +15,7 @@
=========================================================================*/
#include "cmTarget.h"
#include "cmake.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmLocalGenerator.h"
@ -36,6 +37,230 @@ cmTarget::cmTarget()
this->LinkLibrariesAnalyzed = false;
this->LinkDirectoriesComputed = false;
this->HaveInstallRule = false;
}
// define properties
void cmTarget::DefineProperties(cmake *cm)
{
cm->DefineProperty
("BUILD_WITH_INSTALL_RPATH", cmProperty::TARGET,
"Should build tree targets have install tree rpaths.",
"BUILD_WITH_INSTALL_RPATH is a boolean specifying whether to link "
"the target in the build tree with the INSTALL_RPATH. This takes "
"precedence over SKIP_BUILD_RPATH and avoids the need for relinking "
"before installation.");
cm->DefineProperty
("CLEAN_DIRECT_OUTPUT", cmProperty::TARGET,
"Do not delete other varients of this target.",
"When a library is built CMake by default generates code to remove "
"any existing library using all possible names. This is needed "
"to support libraries that switch between STATIC and SHARED by "
"a user option. However when using OUTPUT_NAME to build a static "
"and shared library of the same name using different logical target "
"names the two targets will remove each other's files. This can be "
"prevented by setting the CLEAN_DIRECT_OUTPUT property to 1.");
cm->DefineProperty
("COMPILE_FLAGS", cmProperty::TARGET,
"Additional flags to yse when compiling this target's sources.",
"The COMPILE_FLAGS property sets additional compiler flags used "
"to build sources within the target. It may also be used to pass "
"additional preprocessor definitions.");
cm->DefineProperty
("DEFINE_SYMBOL", cmProperty::TARGET,
"Define a symbol when compiling this target's sources.",
"DEFINE_SYMBOL sets the name of the preprocessor symbol defined when "
"compiling sources in a shared library. "
"If not set here then it is set to target_EXPORTS by default "
"(with some substitutions if the target is not a valid C "
"identifier). This is useful for headers to know whether they are "
"being included from inside their library our outside to properly "
"setup dllexport/dllimport decorations. ");
cm->DefineProperty
("DEBUG_POSTFIX", cmProperty::TARGET,
"A postfix that will be applied to this target when build debug.",
"A property on a target that sepcifies a postfix to add to the "
"target name when built in debug mode. For example foo.dll "
"versus fooD.dll");
cm->DefineProperty
("EchoString", cmProperty::TARGET,
"A message to be displayed when the target it built.",
"A message to display on some generaters (such as makefiles) when "
"the target is built.");
cm->DefineProperty
("HAS_CXX", cmProperty::TARGET,
"Force a target to use the CXX linker.",
"Setting HAS_CXX on a target will force the target to use the "
"C++ linker (and C++ runtime libraries) for linking even if the "
"target has no C++ code in it.");
cm->DefineProperty
("IMPORT_PREFIX", cmProperty::TARGET,
"What comes before the import library name.",
"Similar to the target property PREFIX, but used for import libraries "
"(typically corresponding to a DLL) instead of regular libraries. "
"A target property that can be set to override the prefix "
"(such as \"lib\") on an import library name.");
cm->DefineProperty
("IMPORT_SUFFIX", cmProperty::TARGET,
"What comes after the import library name.",
"Similar to the target property SUFFIX, but used for import libraries "
"(typically corresponding to a DLL) instead of regular libraries. "
"A target property that can be set to override the suffix "
"(such as \".lib\") on an import library name.");
cm->DefineProperty
("IN_ALL", cmProperty::TARGET,
"Is this target part of the all target.",
"A property on a target that indicates if the target is included as "
"part of the default build target. If it is, then with a Makefile "
"for example typing make will couse this target to be built as well. "
"The same concept applies to the default build of other generators.");
cm->DefineProperty
("INSTALL_NAME_DIR", cmProperty::TARGET,
"Mac OSX directory name for installed targets.",
"INSTALL_NAME_DIR is a string specifying the "
"directory portion of the \"install_name\" field of shared libraries "
"on Mac OSX to use in the installed targets. ");
cm->DefineProperty
("INSTALL_RPATH", cmProperty::TARGET,
"The rpath to use for installed targets.",
"A semicolon-separated list specifying the rpath "
"to use in installed targets (for platforms that support it).");
cm->DefineProperty
("INSTALL_RPATH_USE_LINK_PATH", cmProperty::TARGET,
"Add paths to linker search and installed rpath.",
"INSTALL_RPATH_USE_LINK_PATH is a boolean that if set to true will "
"append directories in the linker search path and outside the "
"project to the INSTALL_RPATH. ");
cm->DefineProperty
("LINK_FLAGS", cmProperty::TARGET,
"Additional flags to use when linking this target.",
"The LINK_FLAGS property can be used to add extra flags to the "
"link step of a target. LINK_FLAGS_<CONFIG> will add to the "
"configuration <CONFIG>, "
"for example, DEBUG, RELEASE, MINSIZEREL, RELWITHDEBINFO. ");
cm->DefineProperty
("LINKER_LANGUAGE", cmProperty::TARGET,
"What tool to use for linking, based on language.",
"The LINKER_LANGUAGE property is used to change the tool "
"used to link an executable or shared library. The default is "
"set the language to match the files in the library. CXX and C "
"are common values for this property.");
cm->DefineProperty
("LOCATION", cmProperty::TARGET,
"Where a target will be written on disk.",
"A read only property on a target that indicates where that target "
"will be written. For libraries and execuatables this will be where "
"the file is written on disk. This property is computed based on a "
"number of other settings.");
cm->DefineProperty
("OUTPUT_NAME", cmProperty::TARGET,
"Sets the real name of a target when it is built.",
"Sets the real name of a target when it is built and "
"can be used to help create two targets of the same name even though "
"CMake requires unique logical target names. There is also a "
"<CONFIG>_OUTPUT_NAME that can set the output name on a "
"per-configuration basis.");
cm->DefineProperty
("PRE_INSTALL_SCRIPT", cmProperty::TARGET,
"Deprecated install support.",
"The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the "
"old way to specify CMake scripts to run before and after "
"installing a target. They are used only when the old "
"INSTALL_TARGETS command is used to install the target. Use the "
"INSTALL command instead.");
cm->DefineProperty
("PREFIX", cmProperty::TARGET,
"What comes before the library name.",
"A target property that can be set to override the prefix "
"(such as \"lib\") on a library name.");
cm->DefineProperty
("POST_INSTALL_SCRIPT", cmProperty::TARGET,
"Deprecated install support.",
"The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the "
"old way to specify CMake scripts to run before and after "
"installing a target. They are used only when the old "
"INSTALL_TARGETS command is used to install the target. Use the "
"INSTALL command instead.");
cm->DefineProperty
("SKIP_BUILD_RPATH", cmProperty::TARGET,
"Should rpaths be used for the build tree.",
"SKIP_BUILD_RPATH is a boolean specifying whether to skip automatic "
"generation of an rpath allowing the target to run from the "
"build tree. ");
cm->DefineProperty
("SOVERSION", cmProperty::TARGET,
"What version number is this target.",
"For shared libraries VERSION and SOVERSION can be used to specify "
"the build version and api version respectively. When building or "
"installing appropriate symlinks are created if the platform "
"supports symlinks and the linker supports so-names. "
"If only one of both is specified the missing is assumed to have "
"the same version number. "
"For shared libraries and executables on Windows the VERSION "
"attribute is parsed to extract a \"major.minor\" version number. "
"These numbers are used as the image version of the binary. ");
cm->DefineProperty
("STATIC_LIBRARY_FLAGS", cmProperty::TARGET,
"Extra flags to use when linking static libraries.",
"Extra flags to use when linking a static library.");
cm->DefineProperty
("SUFFIX", cmProperty::TARGET,
"What comes after the library name.",
"A target property that can be set to override the suffix "
"(such as \".so\") on a library name.");
cm->DefineProperty
("VERSION", cmProperty::TARGET,
"What version number is this target.",
"For shared libraries VERSION and SOVERSION can be used to specify "
"the build version and api version respectively. When building or "
"installing appropriate symlinks are created if the platform "
"supports symlinks and the linker supports so-names. "
"If only one of both is specified the missing is assumed to have "
"the same version number. "
"For executables VERSION can be used to specify the build version. "
"When building or installing appropriate symlinks are created if "
"the platform supports symlinks. "
"For shared libraries and executables on Windows the VERSION "
"attribute is parsed to extract a \"major.minor\" version number. "
"These numbers are used as the image version of the binary. ");
cm->DefineProperty
("WIN32_EXECUTABLE", cmProperty::TARGET,
"Used to specify Windows executable with a WinMain entry point.",
"This can be set to indicate that a target is a Windows executable "
"in contrast to a console application for example. This changes "
"how the executable will be linked.");
// define some properties without documentation
cm->DefineProperty("DEBUG_OUTPUT_NAME", cmProperty::TARGET,0,0);
cm->DefineProperty("RELEASE_OUTPUT_NAME", cmProperty::TARGET,0,0);
cm->DefineProperty("LINK_FLAGS_DEBUG", cmProperty::TARGET,0,0);
}
void cmTarget::SetType(TargetType type, const char* name)
@ -60,6 +285,9 @@ void cmTarget::SetMakefile(cmMakefile* mf)
// Set our makefile.
this->Makefile = mf;
// set the cmake instance of the properties
this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
// Setup default property values.
this->SetPropertyDefault("INSTALL_NAME_DIR", "");
this->SetPropertyDefault("INSTALL_RPATH", "");
@ -332,6 +560,8 @@ void cmTarget::GenerateSourceFilesFromSourceLists( cmMakefile &mf)
if (!done)
{
cmSourceFile file;
file.GetProperties().
SetCMakeInstance(this->Makefile->GetCMakeInstance());
file.SetProperty("ABSTRACT","0");
file.SetName(temps.c_str(), mf.GetCurrentDirectory(),
mf.GetSourceExtensions(),
@ -841,7 +1071,8 @@ void cmTarget::SetProperty(const char* prop, const char* value)
{
value = "NOTFOUND";
}
this->Properties[prop] = value;
this->Properties.SetProperty(prop, value, cmProperty::TARGET);
}
const char* cmTarget::GetDirectory(const char* config)
@ -924,6 +1155,12 @@ void cmTarget::GetTargetVersion(int& major, int& minor)
}
const char *cmTarget::GetProperty(const char* prop)
{
return this->GetProperty(prop, cmProperty::TARGET);
}
const char *cmTarget::GetProperty(const char* prop,
cmProperty::ScopeType scope)
{
// watch for special "computed" properties that are dependent on other
// properties or variables, always recompute them
@ -985,24 +1222,20 @@ const char *cmTarget::GetProperty(const char* prop)
return 0;
}
std::map<cmStdString,cmStdString>::const_iterator i =
this->Properties.find(prop);
if (i != this->Properties.end())
bool chain = false;
const char *retVal =
this->Properties.GetPropertyValue(prop, scope, chain);
if (chain)
{
return i->second.c_str();
return this->Makefile->GetProperty(prop,scope);
}
return 0;
return retVal;
}
bool cmTarget::GetPropertyAsBool(const char* prop)
{
std::map<cmStdString,cmStdString>::const_iterator i =
this->Properties.find(prop);
if (i != this->Properties.end())
{
return cmSystemTools::IsOn(i->second.c_str());
}
return false;
return cmSystemTools::IsOn(this->GetProperty(prop));
}
const char* cmTarget::GetLinkerLanguage(cmGlobalGenerator* gg)

View File

@ -18,7 +18,9 @@
#define cmTarget_h
#include "cmCustomCommand.h"
#include "cmPropertyMap.h"
class cmake;
class cmMakefile;
class cmSourceFile;
class cmGlobalGenerator;
@ -165,6 +167,7 @@ public:
///! Set/Get a property of this target file
void SetProperty(const char *prop, const char *value);
const char *GetProperty(const char *prop);
const char *GetProperty(const char *prop, cmProperty::ScopeType scope);
bool GetPropertyAsBool(const char *prop);
/** Get the directory in which this target will be built. If the
@ -249,6 +252,12 @@ public:
std::string GetInstallNameDirForBuildTree(const char* config);
std::string GetInstallNameDirForInstallTree(const char* config);
// Get the properties
cmPropertyMap &GetProperties() { return this->Properties; };
// Define the properties
static void DefineProperties(cmake *cm);
private:
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.
@ -320,6 +329,7 @@ private:
// Use a makefile variable to set a default for the given property.
// If the variable is not defined use the given default instead.
void SetPropertyDefault(const char* property, const char* default_value);
private:
std::string Name;
std::vector<cmCustomCommand> PreBuildCommands;
@ -342,7 +352,7 @@ private:
std::string Location;
std::set<cmStdString> Utilities;
bool RecordDependencies;
std::map<cmStdString,cmStdString> Properties;
cmPropertyMap Properties;
LinkLibraryVectorType OriginalLinkLibraries;
// The cmMakefile instance that owns this target. This should

View File

@ -17,9 +17,12 @@
#include "cmTest.h"
#include "cmSystemTools.h"
#include "cmake.h"
#include "cmMakefile.h"
cmTest::cmTest()
{
this->Makefile = 0;
}
cmTest::~cmTest()
@ -52,24 +55,18 @@ void cmTest::SetArguments(const std::vector<cmStdString>& args)
const char *cmTest::GetProperty(const char* prop) const
{
std::map<cmStdString,cmStdString>::const_iterator i =
this->Properties.find(prop);
if (i != this->Properties.end())
bool chain = false;
const char *retVal =
this->Properties.GetPropertyValue(prop, cmProperty::TEST, chain);
if (chain)
{
return i->second.c_str();
return this->Makefile->GetProperty(prop,cmProperty::TEST);
}
return 0;
}
bool cmTest::GetPropertyAsBool(const char* prop) const
{
std::map<cmStdString,cmStdString>::const_iterator i =
this->Properties.find(prop);
if (i != this->Properties.end())
{
return cmSystemTools::IsOn(i->second.c_str());
}
return false;
return cmSystemTools::IsOn(this->GetProperty(prop));
}
void cmTest::SetProperty(const char* prop, const char* value)
@ -82,6 +79,46 @@ void cmTest::SetProperty(const char* prop, const char* value)
{
value = "NOTFOUND";
}
this->Properties[prop] = value;
this->Properties.SetProperty(prop, value, cmProperty::TEST);
}
//----------------------------------------------------------------------------
void cmTest::SetMakefile(cmMakefile* mf)
{
// Set our makefile.
this->Makefile = mf;
this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
}
// define properties
void cmTest::DefineProperties(cmake *cm)
{
// define properties
cm->DefineProperty
("FAIL_REGULAR_EXPRESSION", cmProperty::TEST,
"If the output matches this regular expression tes test will fail.",
"If set, if the output matches one of "
"specified regular expressions, the test will fail."
"For example: PASS_REGULAR_EXPRESSION \"[^a-z]Error;ERROR;Failed\"");
cm->DefineProperty
("MEASUREMENT", cmProperty::TEST,
"Specify a DART meansurement and value to be reported for a test.",
"If set to a name then that name will be reported to DART as a "
"named measurement with a value of 1. You may also specify a value "
"by setting MEASUREMENT to \"measurement=value\".");
cm->DefineProperty
("PASS_REGULAR_EXPRESSION", cmProperty::TEST,
"The output must match this regular expression for the test to pass.",
"If set, the test output will be checked "
"against the specified regular expressions and at least one of the"
" regular expressions has to match, otherwise the test will fail.");
cm->DefineProperty
("WILL_FAIL", cmProperty::TEST,
"If set to true, this will invert the pass/fail flag of the test.",
"This property can be used for tests that are expected to fail and "
"return a non zero return code.");
}

View File

@ -18,6 +18,8 @@
#define cmTest_h
#include "cmCustomCommand.h"
#include "cmPropertyMap.h"
class cmMakefile;
/** \class cmTest
* \brief Represent a test
@ -52,16 +54,24 @@ public:
void SetProperty(const char *prop, const char *value);
const char *GetProperty(const char *prop) const;
bool GetPropertyAsBool(const char *prop) const;
const std::map<cmStdString,cmStdString>& GetProperties() const
{
return this->Properties;
}
cmPropertyMap &GetProperties() { return this->Properties; };
// Define the properties
static void DefineProperties(cmake *cm);
///! Set the cmMakefile that owns this test
void SetMakefile(cmMakefile *mf);
cmMakefile *GetMakefile() { return this->Makefile;};
private:
std::map<cmStdString,cmStdString> Properties;
cmPropertyMap Properties;
cmStdString Name;
cmStdString Command;
std::vector<cmStdString> Args;
// The cmMakefile instance that owns this target. This should
// always be set.
cmMakefile* Makefile;
};
#endif

View File

@ -164,6 +164,8 @@ cmVTKMakeInstantiatorCommand
// Add the generated source file into the source list.
cmSourceFile file;
file.GetProperties().SetCMakeInstance
(this->Makefile->GetCMakeInstance());
file.SetProperty("WRAP_EXCLUDE","1");
file.SetProperty("ABSTRACT","0");
file.SetName(fileName.c_str(), filePath.c_str(),
@ -204,6 +206,8 @@ cmVTKMakeInstantiatorCommand
// Add the generated source file into the source list.
cmSourceFile file;
file.GetProperties().SetCMakeInstance
(this->Makefile->GetCMakeInstance());
file.SetProperty("WRAP_EXCLUDE","1");
file.SetProperty("ABSTRACT","0");
file.SetName(fileName.c_str(), filePath.c_str(),

View File

@ -70,6 +70,8 @@ bool cmVTKWrapJavaCommand::InitialPass(std::vector<std::string> const& argsIn)
if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE"))
{
cmSourceFile file;
file.GetProperties().SetCMakeInstance
(this->Makefile->GetCMakeInstance());
if (curr)
{
file.SetProperty("ABSTRACT",curr->GetProperty("ABSTRACT"));

View File

@ -70,6 +70,8 @@ bool cmVTKWrapPythonCommand::InitialPass(std::vector<std::string> const&
if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE"))
{
cmSourceFile file;
file.GetProperties().SetCMakeInstance
(this->Makefile->GetCMakeInstance());
if (curr)
{
file.SetProperty("ABSTRACT",curr->GetProperty("ABSTRACT"));
@ -90,6 +92,8 @@ bool cmVTKWrapPythonCommand::InitialPass(std::vector<std::string> const&
}
cmSourceFile cfile;
cfile.GetProperties().SetCMakeInstance
(this->Makefile->GetCMakeInstance());
cfile.SetProperty("ABSTRACT","0");
this->CreateInitFile(res);
cfile.SetName(initName.c_str(), this->Makefile->GetCurrentOutputDirectory(),

View File

@ -106,6 +106,8 @@ bool cmVTKWrapTclCommand::InitialPass(std::vector<std::string> const& argsIn)
if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE"))
{
cmSourceFile file;
file.GetProperties().SetCMakeInstance
(this->Makefile->GetCMakeInstance());
std::string srcDir = cdir;
if (curr)
{
@ -128,6 +130,8 @@ bool cmVTKWrapTclCommand::InitialPass(std::vector<std::string> const& argsIn)
}
// add the init file
cmSourceFile cfile;
cfile.GetProperties().SetCMakeInstance
(this->Makefile->GetCMakeInstance());
cfile.SetProperty("ABSTRACT","0");
std::string newName = this->LibraryName;
newName += "Init";

View File

@ -81,7 +81,8 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf)
if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endwhile"))
{
if (lff.Arguments == this->Args
|| mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS"))
|| cmSystemTools::IsOn
(mf.GetPropertyOrDefinition("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS")))
{
return true;
}

View File

@ -23,7 +23,9 @@
#include "cmCommand.h"
#include "cmFileTimeComparison.h"
#include "cmGeneratedFileStream.h"
#include "cmSourceFile.h"
#include "cmVersion.h"
#include "cmTest.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
# include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
@ -116,6 +118,14 @@ cmake::cmake()
this->ClearBuildSystem = false;
this->FileComparison = new cmFileTimeComparison;
this->Properties.SetCMakeInstance(this);
// initialize properties
cmSourceFile::DefineProperties(this);
cmTarget::DefineProperties(this);
cmMakefile::DefineProperties(this);
cmTest::DefineProperties(this);
#ifdef __APPLE__
struct rlimit rlp;
if(!getrlimit(RLIMIT_STACK, &rlp))
@ -1990,6 +2000,28 @@ void cmake::GetCommandDocumentation(
v.push_back(empty);
}
void cmake::GetPropertiesDocumentation(std::vector<cmDocumentationEntry>& v)
{
// get the properties for cmake
// get them for any generators
// get them for Directories
this->DirectoryProperties.GetPropertiesDocumentation(v);
// get them for targets
this->TargetProperties.GetPropertiesDocumentation(v);
// get them for source files
this->SourceFileProperties.GetPropertiesDocumentation(v);
// get them for tests
this->TestProperties.GetPropertiesDocumentation(v);
cmDocumentationEntry empty = {0,0,0};
v.push_back(empty);
}
void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
{
for(RegisteredGeneratorsMap::const_iterator i = this->Generators.begin();
@ -2766,3 +2798,111 @@ int cmake::ExecuteLinkScript(std::vector<std::string>& args)
// Return the final resulting return value.
return result;
}
void cmake::DefineProperty(const char *name, cmProperty::ScopeType scope,
const char *ShortDescription,
const char *FullDescription,
bool chained)
{
switch (scope)
{
case cmProperty::GLOBAL:
this->GlobalProperties.DefineProperty(name,scope,ShortDescription,
FullDescription, chained);
break;
case cmProperty::TARGET:
this->TargetProperties.DefineProperty(name,scope,ShortDescription,
FullDescription, chained);
break;
case cmProperty::SOURCE_FILE:
this->SourceFileProperties.DefineProperty(name,scope,ShortDescription,
FullDescription, chained);
break;
case cmProperty::DIRECTORY:
this->DirectoryProperties.DefineProperty(name,scope,ShortDescription,
FullDescription, chained);
break;
case cmProperty::TEST:
this->TestProperties.DefineProperty(name,scope,ShortDescription,
FullDescription, chained);
break;
}
}
bool cmake::IsPropertyDefined(const char *name, cmProperty::ScopeType scope)
{
switch (scope)
{
case cmProperty::GLOBAL:
return this->GlobalProperties.IsPropertyDefined(name);
break;
case cmProperty::TARGET:
return this->TargetProperties.IsPropertyDefined(name);
break;
case cmProperty::SOURCE_FILE:
return this->SourceFileProperties.IsPropertyDefined(name);
break;
case cmProperty::DIRECTORY:
return this->DirectoryProperties.IsPropertyDefined(name);
break;
case cmProperty::TEST:
return this->TestProperties.IsPropertyDefined(name);
break;
}
return false;
}
bool cmake::IsPropertyChained(const char *name, cmProperty::ScopeType scope)
{
switch (scope)
{
case cmProperty::GLOBAL:
return this->GlobalProperties.IsPropertyChained(name);
break;
case cmProperty::TARGET:
return this->TargetProperties.IsPropertyChained(name);
break;
case cmProperty::SOURCE_FILE:
return this->SourceFileProperties.IsPropertyChained(name);
break;
case cmProperty::DIRECTORY:
return this->DirectoryProperties.IsPropertyChained(name);
break;
case cmProperty::TEST:
return this->DirectoryProperties.IsPropertyChained(name);
break;
}
return false;
}
void cmake::SetProperty(const char* prop, const char* value)
{
if (!prop)
{
return;
}
if (!value)
{
value = "NOTFOUND";
}
this->Properties.SetProperty(prop, value, cmProperty::TARGET);
}
const char *cmake::GetProperty(const char* prop)
{
return this->GetProperty(prop, cmProperty::GLOBAL);
}
const char *cmake::GetProperty(const char* prop, cmProperty::ScopeType scope)
{
bool chain = false;
return this->Properties.GetPropertyValue(prop, scope, chain);
}
bool cmake::GetPropertyAsBool(const char* prop)
{
return cmSystemTools::IsOn(this->GetProperty(prop));
}

View File

@ -41,6 +41,8 @@
#define cmake_h
#include "cmSystemTools.h"
#include "cmPropertyDefinitionMap.h"
#include "cmPropertyMap.h"
class cmGlobalGenerator;
class cmLocalGenerator;
@ -235,8 +237,18 @@ class cmake
cmVariableWatch* GetVariableWatch() { return this->VariableWatch; }
void GetCommandDocumentation(std::vector<cmDocumentationEntry>&) const;
void GetPropertiesDocumentation(std::vector<cmDocumentationEntry>&);
void GetGeneratorDocumentation(std::vector<cmDocumentationEntry>&);
///! Set/Get a property of this target file
void SetProperty(const char *prop, const char *value);
const char *GetProperty(const char *prop);
const char *GetProperty(const char *prop, cmProperty::ScopeType scope);
bool GetPropertyAsBool(const char *prop);
// Get the properties
cmPropertyMap &GetProperties() { return this->Properties; };
///! Do all the checks before running configure
int DoPreConfigureChecks();
@ -278,7 +290,24 @@ class cmake
bool GetDebugOutput() { return this->DebugOutput; }
void DebugOutputOn() { this->DebugOutput = true;}
// Define a property
void DefineProperty(const char *name, cmProperty::ScopeType scope,
const char *ShortDescription,
const char *FullDescription,
bool chain = false);
// Is a property defined?
bool IsPropertyDefined(const char *name, cmProperty::ScopeType scope);
bool IsPropertyChained(const char *name, cmProperty::ScopeType scope);
protected:
cmPropertyMap Properties;
cmPropertyDefinitionMap TargetProperties;
cmPropertyDefinitionMap SourceFileProperties;
cmPropertyDefinitionMap DirectoryProperties;
cmPropertyDefinitionMap TestProperties;
cmPropertyDefinitionMap GlobalProperties;
typedef cmGlobalGenerator* (*CreateGeneratorFunctionType)();
typedef std::map<cmStdString,
CreateGeneratorFunctionType> RegisteredGeneratorsMap;

View File

@ -18,6 +18,7 @@
#include "cmCacheManager.h"
#include "cmListFileCache.h"
#include "cmakewizard.h"
#include "cmSourceFile.h"
#ifdef CMAKE_BUILD_WITH_CMAKE
#include "cmDynamicLoader.h"
@ -100,6 +101,13 @@ static const cmDocumentationEntry cmDocumentationOptions[] =
"The list contains all modules for which help may be obtained by using "
"the --help-module argument followed by a module name. If a file is "
"specified, the help is written into it."},
{"--help-property prop [file]",
"Print help for a single property and exit.",
"Full documentation specific to the given module is displayed."},
{"--help-property-list [file]", "List available properties and exit.",
"The list contains all properties for which help may be obtained by using "
"the --help-property argument followed by a property name. If a file is "
"specified, the help is written into it."},
{0,0,0}
};
@ -157,8 +165,10 @@ int do_cmake(int ac, char** av)
hcm.AddCMakePaths(av[0]);
doc.SetCMakeRoot(hcm.GetCacheDefinition("CMAKE_ROOT"));
std::vector<cmDocumentationEntry> commands;
std::vector<cmDocumentationEntry> properties;
std::vector<cmDocumentationEntry> generators;
hcm.GetCommandDocumentation(commands);
hcm.GetPropertiesDocumentation(properties);
hcm.GetGeneratorDocumentation(generators);
doc.SetName("cmake");
doc.SetNameSection(cmDocumentationName);
@ -167,6 +177,7 @@ int do_cmake(int ac, char** av)
doc.SetGeneratorsSection(&generators[0]);
doc.SetOptionsSection(cmDocumentationOptions);
doc.SetCommandsSection(&commands[0]);
doc.SetPropertiesSection(&properties[0]);
doc.SetSeeAlsoList(cmDocumentationSeeAlso);
int result = doc.PrintRequestedDocumentation(std::cout)? 0:1;

View File

@ -45,6 +45,8 @@ ADD_LIBRARY(CMakeTestLibraryShared SHARED ${SharedLibrarySources})
ADD_LIBRARY(CMakeTestModule MODULE moduleFile.c)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DTEST_C_FLAGS")
ADD_LIBRARY(CMakeTestCLibraryShared SHARED testConly.c)
DEFINE_PROPERTY(FOO TARGET "a test property"
"A simple etst proerty that means nothign and is used for nothing" 0)
SET_TARGET_PROPERTIES(CMakeTestCLibraryShared PROPERTIES FOO BAR)
IF(NOT BEOS) # No libm on BeOS.
SET_TARGET_PROPERTIES(CMakeTestCLibraryShared PROPERTIES LINK_FLAGS "-lm")

View File

@ -45,6 +45,8 @@ ADD_LIBRARY(CMakeTestLibraryShared SHARED ${SharedLibrarySources})
ADD_LIBRARY(CMakeTestModule MODULE moduleFile.c)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DTEST_C_FLAGS")
ADD_LIBRARY(CMakeTestCLibraryShared SHARED testConly.c)
DEFINE_PROPERTY(FOO TARGET "a test property"
"A simple etst proerty that means nothign and is used for nothing" 0)
SET_TARGET_PROPERTIES(CMakeTestCLibraryShared PROPERTIES FOO BAR)
IF(NOT BEOS) # No libm on BeOS.
SET_TARGET_PROPERTIES(CMakeTestCLibraryShared PROPERTIES LINK_FLAGS "-lm")

View File

@ -45,6 +45,8 @@ ADD_LIBRARY(CMakeTestLibraryShared SHARED ${SharedLibrarySources})
ADD_LIBRARY(CMakeTestModule MODULE moduleFile.c)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DTEST_C_FLAGS")
ADD_LIBRARY(CMakeTestCLibraryShared SHARED testConly.c)
DEFINE_PROPERTY(FOO TARGET "a test property"
"A simple etst proerty that means nothign and is used for nothing" 0)
SET_TARGET_PROPERTIES(CMakeTestCLibraryShared PROPERTIES FOO BAR)
IF(NOT BEOS) # No libm on BeOS.
SET_TARGET_PROPERTIES(CMakeTestCLibraryShared PROPERTIES LINK_FLAGS "-lm")

View File

@ -99,18 +99,24 @@ static int CCONV InitialPass(void *inf, void *mf, int argc, char *argv[])
}
info->CAPI->AddDefineFlag(mf, "-DADDED_DEFINITION");
source_file = info->CAPI->CreateSourceFile();
source_file = info->CAPI->CreateNewSourceFile(mf);
cstr = info->CAPI->SourceFileGetSourceName(source_file);
sprintf(buffer, "Shold be empty (source file name): [%s]", cstr);
info->CAPI->DisplaySatus(mf, buffer);
cstr = info->CAPI->SourceFileGetFullPath(source_file);
sprintf(buffer, "Shold be empty (source file full path): [%s]", cstr);
sprintf(buffer, "Should be empty (source file full path): [%s]", cstr);
info->CAPI->DisplaySatus(mf, buffer);
info->CAPI->DefineSourceFileProperty(mf,"SOME_PROPERTY","unused old prop",
"This property is no longer used",
0);
if ( info->CAPI->SourceFileGetPropertyAsBool(source_file, "SOME_PROPERTY") )
{
info->CAPI->SetError(mf, "Property SOME_PROPERTY should not be defined");
return 0;
}
info->CAPI->DefineSourceFileProperty(mf,"SOME_PROPERTY2","nice prop",
"This property is for testing.",
0);
info->CAPI->SourceFileSetProperty(source_file, "SOME_PROPERTY2", "HERE");
cstr = info->CAPI->SourceFileGetProperty(source_file, "ABSTRACT");
sprintf(buffer, "Should be 0 (source file abstract property): [%p]", cstr);

View File

@ -99,18 +99,24 @@ static int CCONV InitialPass(void *inf, void *mf, int argc, char *argv[])
}
info->CAPI->AddDefineFlag(mf, "-DADDED_DEFINITION");
source_file = info->CAPI->CreateSourceFile();
source_file = info->CAPI->CreateNewSourceFile(mf);
cstr = info->CAPI->SourceFileGetSourceName(source_file);
sprintf(buffer, "Shold be empty (source file name): [%s]", cstr);
info->CAPI->DisplaySatus(mf, buffer);
cstr = info->CAPI->SourceFileGetFullPath(source_file);
sprintf(buffer, "Shold be empty (source file full path): [%s]", cstr);
sprintf(buffer, "Should be empty (source file full path): [%s]", cstr);
info->CAPI->DisplaySatus(mf, buffer);
info->CAPI->DefineSourceFileProperty(mf,"SOME_PROPERTY","unused old prop",
"This property is no longer used",
0);
if ( info->CAPI->SourceFileGetPropertyAsBool(source_file, "SOME_PROPERTY") )
{
info->CAPI->SetError(mf, "Property SOME_PROPERTY should not be defined");
return 0;
}
info->CAPI->DefineSourceFileProperty(mf,"SOME_PROPERTY2","nice prop",
"This property is for testing.",
0);
info->CAPI->SourceFileSetProperty(source_file, "SOME_PROPERTY2", "HERE");
cstr = info->CAPI->SourceFileGetProperty(source_file, "ABSTRACT");
sprintf(buffer, "Should be 0 (source file abstract property): [%p]", cstr);