ENH: different way of testing properties

This commit is contained in:
Ken Martin 2007-11-06 14:16:00 -05:00
parent 8eae7fddf2
commit 433a914910
5 changed files with 154 additions and 74 deletions

View File

@ -936,4 +936,46 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
cm->DefineProperty("CMAKE_MATCH_7", cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_MATCH_7", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_MATCH_8", cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_MATCH_8", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_MATCH_9", cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_MATCH_9", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_COMPILER_ARG1", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_COMPILER_ENV_VAR", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_COMPILER_ID_RUN", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_COMPILER_LOADED", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_CREATE_ASSEMBLY_SOURCE", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_CREATE_PREPROCESSED_SOURCE", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_FLAGS", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_FLAGS_DEBUG_INIT", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_FLAGS_INIT", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_FLAGS_MINSIZEREL_INIT", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_FLAGS_RELEASE_INIT", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_FLAGS_RELWITHDEBINFO_INIT", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_INFORMATION_LOADED", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_LINK_EXECUTABLE", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_LINK_FLAGS", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_STANDARD_LIBRARIES", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_STANDARD_LIBRARIES_INIT", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_EXECUTABLE_SUFFIX_<LANG>", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_EXE_LINK_DYNAMIC_<LANG>_FLAGS", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_EXE_LINK_STATIC_<LANG>_FLAGS", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_GENERATOR_<LANG>", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_IMPORT_LIBRARY_PREFIX_<LANG>", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_IMPORT_LIBRARY_SUFFIX_<LANG>", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_INCLUDE_FLAG_<LANG>", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_INCLUDE_FLAG_SEP_<LANG>", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_INCLUDE_SYSTEM_FLAG_<LANG>", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_NEEDS_REQUIRES_STEP_<LANG>_FLAG", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_SHARED_LIBRARY_CREATE_<LANG>_FLAGS", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_SHARED_LIBRARY_<LANG>_FLAGS", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_SHARED_LIBRARY_LINK_<LANG>_FLAGS", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_SHARED_LIBRARY_LINK_DYNAMIC_<LANG>_FLAGS", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_SHARED_LIBRARY_LINK_STATIC_<LANG>_FLAGS", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_SHARED_LIBRARY_RUNTIME_<LANG>_FLAG", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_SHARED_LIBRARY_RUNTIME_<LANG>_FLAG_SEP", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_SHARED_MODULE_CREATE_<LANG>_FLAGS", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_SHARED_MODULE_<LANG>_FLAGS", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_SHARED_MODULE_LINK_DYNAMIC_<LANG>_FLAGS", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_SHARED_MODULE_LINK_STATIC_<LANG>_FLAGS", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_SHARED_MODULE_RUNTIME_<LANG>_FLAG", cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_SHARED_MODULE_RUNTIME_<LANG>_FLAG_SEP", cmProperty::VARIABLE,0,0);
} }

View File

@ -1217,13 +1217,10 @@ void cmMakefile::AddDefinition(const char* name, const char* value)
} }
#ifdef CMAKE_STRICT #ifdef CMAKE_STRICT
if (this->GetCMakeInstance() && if (this->GetCMakeInstance())
!this->GetCMakeInstance()->IsPropertyDefined(name,cmProperty::VARIABLE))
{ {
std::string msg = "Variable "; this->GetCMakeInstance()->
msg += name; RecordPropertyAccess(name,cmProperty::VARIABLE);
msg += " set yet not defined!";
cmSystemTools::Error(msg.c_str());
} }
#endif #endif
@ -1682,13 +1679,10 @@ bool cmMakefile::IsDefinitionSet(const char* name) const
const char* cmMakefile::GetDefinition(const char* name) const const char* cmMakefile::GetDefinition(const char* name) const
{ {
#ifdef CMAKE_STRICT #ifdef CMAKE_STRICT
if (this->GetCMakeInstance() && if (this->GetCMakeInstance())
!this->GetCMakeInstance()->IsPropertyDefined(name,cmProperty::VARIABLE))
{ {
std::string msg = "Variable "; this->GetCMakeInstance()->
msg += name; RecordPropertyAccess(name,cmProperty::VARIABLE);
msg += " queried yet undefined!";
cmSystemTools::Error(msg.c_str());
} }
#endif #endif
const char* def = 0; const char* def = 0;

View File

@ -51,38 +51,9 @@ void cmPropertyMap::SetProperty(const char *name, const char *value,
cmSystemTools::Error("CMakeInstance not set on a property map!"); cmSystemTools::Error("CMakeInstance not set on a property map!");
abort(); abort();
} }
else if (!this->CMakeInstance->IsPropertyDefined(name,scope)) else
{ {
// is a property being queried without being defined first? If so then this->CMakeInstance->RecordPropertyAccess(name,scope);
// report it as we probably need to document it
std::string msg = "Property ";
msg += name;
msg += " set yet undefined on ";
switch (scope)
{
case cmProperty::TARGET:
msg += "target.";
break;
case cmProperty::SOURCE_FILE:
msg += "source file.";
break;
case cmProperty::DIRECTORY:
msg += "directory.";
break;
case cmProperty::TEST:
msg += "test.";
break;
case cmProperty::VARIABLE:
msg += "variable.";
break;
case cmProperty::CACHED_VARIABLE:
msg += "cached variable.";
break;
default:
msg += "unknown.";
break;
}
cmSystemTools::Error(msg.c_str());
} }
#else #else
(void)scope; (void)scope;
@ -110,38 +81,9 @@ const char *cmPropertyMap
cmSystemTools::Error("CMakeInstance not set on a property map!"); cmSystemTools::Error("CMakeInstance not set on a property map!");
abort(); abort();
} }
else if (!this->CMakeInstance->IsPropertyDefined(name,scope)) else
{ {
// is a property being queried without being defined first? If so then this->CMakeInstance->RecordPropertyAccess(name,scope);
// report it as we probably need to document it
std::string msg = "Property ";
msg += name;
msg += " queried yet undefined on ";
switch (scope)
{
case cmProperty::TARGET:
msg += "target.";
break;
case cmProperty::SOURCE_FILE:
msg += "source file.";
break;
case cmProperty::DIRECTORY:
msg += "directory.";
break;
case cmProperty::TEST:
msg += "test.";
break;
case cmProperty::VARIABLE:
msg += "variable.";
break;
case cmProperty::CACHED_VARIABLE:
msg += "cached variable.";
break;
default:
msg += "unknown.";
break;
}
cmSystemTools::Error(msg.c_str());
} }
#endif #endif

View File

@ -2084,6 +2084,11 @@ int cmake::Generate()
{ {
return -1; return -1;
} }
if (this->GetProperty("REPORT_UNDEFINED_PROPERTIES"))
{
this->ReportUndefinedPropertyAccesses
(this->GetProperty("REPORT_UNDEFINED_PROPERTIES"));
}
return 0; return 0;
} }
@ -3033,6 +3038,14 @@ int cmake::ExecuteLinkScript(std::vector<std::string>& args)
void cmake::DefineProperties(cmake *cm) void cmake::DefineProperties(cmake *cm)
{ {
cm->DefineProperty
("REPORT_UNDEFINED_PROPERTIES", cmProperty::GLOBAL,
"If set, report any undefined properties to this file.",
"If this property is set to a filename then when CMake runs "
"it will report any properties or variables that were accessed "
"but not defined into the filename specified in this property."
);
cm->DefineProperty cm->DefineProperty
("TARGET_SUPPORTS_SHARED_LIBS", cmProperty::GLOBAL, ("TARGET_SUPPORTS_SHARED_LIBS", cmProperty::GLOBAL,
"Does the target platform support shared libraries.", "Does the target platform support shared libraries.",
@ -3104,6 +3117,90 @@ cmPropertyDefinition *cmake
return 0; return 0;
} }
void cmake::RecordPropertyAccess(const char *name,
cmProperty::ScopeType scope)
{
this->AccessedProperties.insert
(std::pair<cmStdString,cmProperty::ScopeType>(name,scope));
}
void cmake::ReportUndefinedPropertyAccesses(const char *filename)
{
FILE *progFile = fopen(filename,"w");
if (!progFile || !this->GlobalGenerator)
{
return;
}
// what are the enabled languages?
std::vector<std::string> enLangs;
this->GlobalGenerator->GetEnabledLanguages(enLangs);
// take all the defined properties and add definitions for all the enabled
// languages
std::set<std::pair<cmStdString,cmProperty::ScopeType> > aliasedProperties;
std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::iterator i;
i = this->PropertyDefinitions.begin();
for (;i != this->PropertyDefinitions.end(); ++i)
{
cmPropertyDefinitionMap::iterator j;
for (j = i->second.begin(); j != i->second.end(); ++j)
{
if (j->first.find("<LANG>"))
{
std::vector<std::string>::const_iterator k;
for (k = enLangs.begin(); k != enLangs.end(); ++k)
{
std::string tmp = j->first;
cmSystemTools::ReplaceString(tmp, "<LANG>", k->c_str());
// add alias
aliasedProperties.insert
(std::pair<cmStdString,cmProperty::ScopeType>(tmp,i->first));
}
}
}
}
std::set<std::pair<cmStdString,cmProperty::ScopeType> >::const_iterator ap;
ap = this->AccessedProperties.begin();
for (;ap != this->AccessedProperties.end(); ++ap)
{
if (!this->IsPropertyDefined(ap->first.c_str(),ap->second) &&
aliasedProperties.find(std::pair<cmStdString,cmProperty::ScopeType>
(ap->first,ap->second)) ==
aliasedProperties.end())
{
const char *scopeStr = "";
switch (ap->second)
{
case cmProperty::TARGET:
scopeStr = "TARGET";
break;
case cmProperty::SOURCE_FILE:
scopeStr = "SOURCE_FILE";
break;
case cmProperty::DIRECTORY:
scopeStr = "DIRECTORY";
break;
case cmProperty::TEST:
scopeStr = "TEST";
break;
case cmProperty::VARIABLE:
scopeStr = "VARIABLE";
break;
case cmProperty::CACHED_VARIABLE:
scopeStr = "CACHED_VARIABLE";
break;
default:
scopeStr = "unknown";
break;
}
fprintf(progFile,"%s with scope %s\n",ap->first.c_str(),scopeStr);
}
}
fclose(progFile);
}
bool cmake::IsPropertyDefined(const char *name, cmProperty::ScopeType scope) bool cmake::IsPropertyDefined(const char *name, cmProperty::ScopeType scope)
{ {
return this->PropertyDefinitions[scope].IsPropertyDefined(name); return this->PropertyDefinitions[scope].IsPropertyDefined(name);

View File

@ -320,11 +320,16 @@ class cmake
bool IsPropertyDefined(const char *name, cmProperty::ScopeType scope); bool IsPropertyDefined(const char *name, cmProperty::ScopeType scope);
bool IsPropertyChained(const char *name, cmProperty::ScopeType scope); bool IsPropertyChained(const char *name, cmProperty::ScopeType scope);
// record accesses of properties and variables
void RecordPropertyAccess(const char *name, cmProperty::ScopeType scope);
void ReportUndefinedPropertyAccesses(const char *filename);
// Define the properties // Define the properties
static void DefineProperties(cmake *cm); static void DefineProperties(cmake *cm);
protected: protected:
cmPropertyMap Properties; cmPropertyMap Properties;
std::set<std::pair<cmStdString,cmProperty::ScopeType> > AccessedProperties;
std::map<cmProperty::ScopeType, cmPropertyDefinitionMap> std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>
PropertyDefinitions; PropertyDefinitions;