Commit b8357db1 authored by Brad King's avatar Brad King
Browse files

ENH: Rename SET_PROPERITES command to SET_PROPERTY and give it a more powerful signature.

parent 45663122
...@@ -21,7 +21,7 @@ SET(CMAKE_FIND_LIBRARY_PREFIXES "lib") ...@@ -21,7 +21,7 @@ SET(CMAKE_FIND_LIBRARY_PREFIXES "lib")
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a") SET(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
# basically all general purpose OSs support shared libs # basically all general purpose OSs support shared libs
SET_PROPERTIES(GLOBAL PROPERTIES TARGET_SUPPORTS_SHARED_LIBS TRUE) SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
SET (CMAKE_SKIP_RPATH "NO" CACHE BOOL SET (CMAKE_SKIP_RPATH "NO" CACHE BOOL
"If set, runtime paths are not added when using shared libraries.") "If set, runtime paths are not added when using shared libraries.")
......
...@@ -21,12 +21,12 @@ ...@@ -21,12 +21,12 @@
MACRO(SET_FEATURE_INFO _name _desc) MACRO(SET_FEATURE_INFO _name _desc)
SET(_url "${ARGV2}") SET(_url "${ARGV2}")
SET(_comment "${ARGV3}") SET(_comment "${ARGV3}")
SET_PROPERTIES(GLOBAL PROPERTIES ${_name}_DESCRIPTION "${_desc}" ) SET_PROPERTY(GLOBAL PROPERTY ${_name}_DESCRIPTION "${_desc}" )
IF(_url MATCHES ".+") IF(_url MATCHES ".+")
SET_PROPERTIES(GLOBAL PROPERTIES ${_name}_URL "${_url}" ) SET_PROPERTY(GLOBAL PROPERTY ${_name}_URL "${_url}" )
ENDIF(_url MATCHES ".+") ENDIF(_url MATCHES ".+")
IF(_comment MATCHES ".+") IF(_comment MATCHES ".+")
SET_PROPERTIES(GLOBAL PROPERTIES ${_name}_COMMENT "${_comment}" ) SET_PROPERTY(GLOBAL PROPERTY ${_name}_COMMENT "${_comment}" )
ENDIF(_comment MATCHES ".+") ENDIF(_comment MATCHES ".+")
ENDMACRO(SET_FEATURE_INFO) ENDMACRO(SET_FEATURE_INFO)
......
#the compute nodes on BlueGene/L don't support shared libs #the compute nodes on BlueGene/L don't support shared libs
SET_PROPERTIES(GLOBAL PROPERTIES TARGET_SUPPORTS_SHARED_LIBS FALSE) SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
SET(CMAKE_SHARED_LIBRARY_C_FLAGS "") # -pic SET(CMAKE_SHARED_LIBRARY_C_FLAGS "") # -pic
SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "") # -shared SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "") # -shared
......
#Catamount, which runs on the compute nodes of Cray machines, e.g. RedStorm, doesn't support shared libs #Catamount, which runs on the compute nodes of Cray machines, e.g. RedStorm, doesn't support shared libs
SET_PROPERTIES(GLOBAL PROPERTIES TARGET_SUPPORTS_SHARED_LIBS FALSE) SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
SET(CMAKE_SHARED_LIBRARY_C_FLAGS "") # -pic SET(CMAKE_SHARED_LIBRARY_C_FLAGS "") # -pic
SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "") # -shared SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "") # -shared
......
...@@ -8,5 +8,4 @@ ...@@ -8,5 +8,4 @@
# and/or ${CMAKE_SYSTEM_NAME}-<compiler_basename>-${CMAKE_SYSTEM_PROCESSOR}.cmake # and/or ${CMAKE_SYSTEM_NAME}-<compiler_basename>-${CMAKE_SYSTEM_PROCESSOR}.cmake
# (embedded) targets without operating system usually don't support shared libraries # (embedded) targets without operating system usually don't support shared libraries
SET_PROPERTIES(GLOBAL PROPERTIES TARGET_SUPPORTS_SHARED_LIBS FALSE) SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
...@@ -52,5 +52,5 @@ INCLUDE(Platform/UnixPaths) ...@@ -52,5 +52,5 @@ INCLUDE(Platform/UnixPaths)
# Debian has lib64 paths only for compatibility so they should not be # Debian has lib64 paths only for compatibility so they should not be
# searched. # searched.
IF(EXISTS "/etc/debian_version") IF(EXISTS "/etc/debian_version")
SET_PROPERTIES(GLOBAL PROPERTIES FIND_LIBRARY_USE_LIB64_PATHS FALSE) SET_PROPERTY(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS FALSE)
ENDIF(EXISTS "/etc/debian_version") ENDIF(EXISTS "/etc/debian_version")
...@@ -54,4 +54,4 @@ LIST(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES ...@@ -54,4 +54,4 @@ LIST(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
) )
# Enable use of lib64 search path variants by default. # Enable use of lib64 search path variants by default.
SET_PROPERTIES(GLOBAL PROPERTIES FIND_LIBRARY_USE_LIB64_PATHS TRUE) SET_PROPERTY(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE)
...@@ -47,7 +47,7 @@ SET(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLA ...@@ -47,7 +47,7 @@ SET(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLA
SET(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostdlib -nostartfiles -L${ECOS_LIBTARGET_DIRECTORY} -Ttarget.ld <LINK_LIBRARIES>") SET(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostdlib -nostartfiles -L${ECOS_LIBTARGET_DIRECTORY} -Ttarget.ld <LINK_LIBRARIES>")
# eCos doesn't support shared libs # eCos doesn't support shared libs
SET_PROPERTIES(GLOBAL PROPERTIES TARGET_SUPPORTS_SHARED_LIBS FALSE) SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
SET(CMAKE_CXX_LINK_SHARED_LIBRARY ) SET(CMAKE_CXX_LINK_SHARED_LIBRARY )
SET(CMAKE_CXX_LINK_MODULE_LIBRARY ) SET(CMAKE_CXX_LINK_MODULE_LIBRARY )
......
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
#include "cmProjectCommand.cxx" #include "cmProjectCommand.cxx"
#include "cmRaiseScopeCommand.cxx" #include "cmRaiseScopeCommand.cxx"
#include "cmSetCommand.cxx" #include "cmSetCommand.cxx"
#include "cmSetPropertiesCommand.cxx" #include "cmSetPropertyCommand.cxx"
#include "cmSetSourceFilesPropertiesCommand.cxx" #include "cmSetSourceFilesPropertiesCommand.cxx"
#include "cmSetTargetPropertiesCommand.cxx" #include "cmSetTargetPropertiesCommand.cxx"
#include "cmSetTestsPropertiesCommand.cxx" #include "cmSetTestsPropertiesCommand.cxx"
...@@ -132,7 +132,7 @@ void GetBootstrapCommands(std::list<cmCommand*>& commands) ...@@ -132,7 +132,7 @@ void GetBootstrapCommands(std::list<cmCommand*>& commands)
commands.push_back(new cmProjectCommand); commands.push_back(new cmProjectCommand);
commands.push_back(new cmRaiseScopeCommand); commands.push_back(new cmRaiseScopeCommand);
commands.push_back(new cmSetCommand); commands.push_back(new cmSetCommand);
commands.push_back(new cmSetPropertiesCommand); commands.push_back(new cmSetPropertyCommand);
commands.push_back(new cmSetSourceFilesPropertiesCommand); commands.push_back(new cmSetSourceFilesPropertiesCommand);
commands.push_back(new cmSetTargetPropertiesCommand); commands.push_back(new cmSetTargetPropertiesCommand);
commands.push_back(new cmSetTestsPropertiesCommand); commands.push_back(new cmSetTestsPropertiesCommand);
......
/*=========================================================================
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 "cmSetPropertiesCommand.h"
#include "cmSetTargetPropertiesCommand.h"
#include "cmSetTestsPropertiesCommand.h"
#include "cmSetSourceFilesPropertiesCommand.h"
// cmSetPropertiesCommand
bool cmSetPropertiesCommand::InitialPass(
std::vector<std::string> const& args)
{
if(args.size() < 2 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
// first collect up the list of files
std::vector<std::string> propertyPairs;
bool doingFiles = true;
int numFiles = 0;
std::vector<std::string>::const_iterator j;
for(j= args.begin(); j != args.end();++j)
{
if(*j == "PROPERTIES")
{
doingFiles = false;
// now loop through the rest of the arguments, new style
++j;
while (j != args.end())
{
propertyPairs.push_back(*j);
++j;
if(j == args.end())
{
this->SetError("called with incorrect number of arguments.");
return false;
}
propertyPairs.push_back(*j);
++j;
}
// break out of the loop because j is already == end
break;
}
else if (doingFiles)
{
numFiles++;
}
else
{
this->SetError("called with illegal arguments, maybe missing "
"a PROPERTIES specifier?");
return false;
}
}
if(propertyPairs.size() == 0)
{
this->SetError("called with illegal arguments, maybe missing "
"a PROPERTIES specifier?");
return false;
}
cmProperty::ScopeType scope;
const char *scopeName = 0;
if (args[0] == "GLOBAL" && numFiles == 1)
{
scope = cmProperty::GLOBAL;
}
else if (args[0] == "DIRECTORY" && numFiles >= 1)
{
scope = cmProperty::DIRECTORY;
if (numFiles == 2)
{
scopeName = args[1].c_str();
}
}
else if (args[0] == "TARGET" && numFiles == 2)
{
scope = cmProperty::TARGET;
scopeName = args[1].c_str();
}
else if (args[0] == "TEST" && numFiles == 2)
{
scope = cmProperty::TEST;
scopeName = args[1].c_str();
}
else if (args[0] == "SOURCE_FILE" && numFiles == 2)
{
scope = cmProperty::SOURCE_FILE;
scopeName = args[1].c_str();
}
else
{
this->SetError("called with illegal arguments.");
return false;
}
switch (scope)
{
case cmProperty::TARGET:
{
bool ret = cmSetTargetPropertiesCommand::
SetOneTarget(scopeName,propertyPairs, this->Makefile);
if (!ret)
{
std::string message = "Can not find target to add properties to: ";
message += scopeName;
this->SetError(message.c_str());
return ret;
}
}
break;
case cmProperty::DIRECTORY:
{
// lookup the makefile from the directory name
cmLocalGenerator *lg = this->Makefile->GetLocalGenerator();
if (numFiles == 2)
{
std::string sd = scopeName;
// make sure the start dir is a full path
if (!cmSystemTools::FileIsFullPath(sd.c_str()))
{
sd = this->Makefile->GetStartDirectory();
sd += "/";
sd += scopeName;
}
// The local generators are associated with collapsed paths.
sd = cmSystemTools::CollapseFullPath(sd.c_str());
lg = this->Makefile->GetLocalGenerator()->GetGlobalGenerator()->
FindLocalGenerator(sd.c_str());
}
if (!lg)
{
this->SetError
("DIRECTORY argument provided but requested directory not found. "
"This could be because the directory argument was invalid or, "
"it is valid but has not been processed yet.");
return false;
}
for(j= propertyPairs.begin(); j != propertyPairs.end(); ++j)
{
const char *pn = j->c_str();
++j;
lg->GetMakefile()->SetProperty(pn,j->c_str());
}
}
break;
case cmProperty::GLOBAL:
{
for(j= propertyPairs.begin(); j != propertyPairs.end(); ++j)
{
const char *pn = j->c_str();
++j;
this->Makefile->GetCMakeInstance()->SetProperty(pn, j->c_str());
}
}
break;
case cmProperty::TEST:
{
std::string errors;
bool ret = cmSetTestsPropertiesCommand::
SetOneTest(scopeName,propertyPairs, this->Makefile, errors);
if (!ret)
{
this->SetError(errors.c_str());
return ret;
}
}
break;
case cmProperty::SOURCE_FILE:
{
std::string errors;
bool ret = cmSetSourceFilesPropertiesCommand::
RunCommand(this->Makefile,
args.begin()+1, args.begin()+2,
args.begin() + 2, args.end(),
errors);
if (!ret)
{
this->SetError(errors.c_str());
return ret;
}
}
break;
case cmProperty::VARIABLE:
case cmProperty::CACHED_VARIABLE:
// not handled by SetProperty
break;
}
return true;
}
/*=========================================================================
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 "cmSetPropertyCommand.h"
#include "cmSetTargetPropertiesCommand.h"
#include "cmSetTestsPropertiesCommand.h"
#include "cmSetSourceFilesPropertiesCommand.h"
//----------------------------------------------------------------------------
cmSetPropertyCommand::cmSetPropertyCommand()
{
this->AppendMode = false;
}
//----------------------------------------------------------------------------
bool cmSetPropertyCommand::InitialPass(std::vector<std::string> const& args)
{
if(args.size() < 2 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
// Get the scope on which to set the property.
std::vector<std::string>::const_iterator arg = args.begin();
cmProperty::ScopeType scope;
if(*arg == "GLOBAL")
{
scope = cmProperty::GLOBAL;
}
else if(*arg == "DIRECTORY")
{
scope = cmProperty::DIRECTORY;
}
else if(*arg == "TARGET")
{
scope = cmProperty::TARGET;
}
else if(*arg == "SOURCE")
{
scope = cmProperty::SOURCE_FILE;
}
else if(*arg == "TEST")
{
scope = cmProperty::TEST;
}
else
{
cmOStringStream e;
e << "given invalid scope " << *arg << ". "
<< "Valid scopes are GLOBAL, DIRECTORY, TARGET, SOURCE, TEST.";
this->SetError(e.str().c_str());
return false;
}
// Parse the rest of the arguments up to the values.
enum Doing { DoingNone, DoingNames, DoingProperty, DoingValues };
Doing doing = DoingNames;
const char* sep = "";
for(++arg; arg != args.end(); ++arg)
{
if(*arg == "PROPERTY")
{
doing = DoingProperty;
}
else if(*arg == "APPEND")
{
doing = DoingNone;
this->AppendMode = true;
}
else if(doing == DoingNames)
{
this->Names.insert(*arg);
}
else if(doing == DoingProperty)
{
this->PropertyName = *arg;
doing = DoingValues;
}
else if(doing == DoingValues)
{
this->PropertyValue += sep;
sep = ";";
this->PropertyValue += *arg;
}
else
{
cmOStringStream e;
e << "given invalid argument \"" << *arg << "\".";
this->SetError(e.str().c_str());
return false;
}
}
// Make sure a property name was found.
if(this->PropertyName.empty())
{
this->SetError("not given a PROPERTY <name> argument.");
return false;
}
// Dispatch property setting.
switch(scope)
{
case cmProperty::GLOBAL: return this->HandleGlobalMode();
case cmProperty::DIRECTORY: return this->HandleDirectoryMode();
case cmProperty::TARGET: return this->HandleTargetMode();
case cmProperty::SOURCE_FILE: return this->HandleSourceMode();
case cmProperty::TEST: return this->HandleTestMode();
case cmProperty::VARIABLE:
case cmProperty::CACHED_VARIABLE:
break; // should never happen
}
return true;
}
//----------------------------------------------------------------------------
bool cmSetPropertyCommand::ConstructValue(std::string& value,
const char* old)
{
if(this->AppendMode)
{
// This is an append. Start with the original value.
if(old)
{
value = old;
}
}
else if(this->PropertyValue.empty())
{
// This is a set to no values. Remove the property.
return false;
}
// Add the new value.
if(!this->PropertyValue.empty())
{
if(!value.empty())
{
value += ";";
}
value += this->PropertyValue;
}
return true;
}
//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleGlobalMode()
{
if(!this->Names.empty())
{
this->SetError("given names for GLOBAL scope.");
return false;
}
// Set or append the property.
cmake* cm = this->Makefile->GetCMakeInstance();
const char* name = this->PropertyName.c_str();
std::string value;
if(this->ConstructValue(value, cm->GetProperty(name)))
{
// Set the new property.
cm->SetProperty(name, value.c_str());
}
else
{
// Remove the property.
cm->SetProperty(name, 0);
}
return true;
}
//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleDirectoryMode()
{
if(this->Names.size() > 1)
{
this->SetError("allows at most one name for DIRECTORY scope.");
return false;
}
// Default to the current directory.
cmMakefile* mf = this->Makefile;
// Lookup the directory if given.
if(!this->Names.empty())
{
// Construct the directory name. Interpret relative paths with
// respect to the current directory.
std::string dir = *this->Names.begin();
if(!cmSystemTools::FileIsFullPath(dir.c_str()))
{
dir = this->Makefile->GetCurrentDirectory();
dir += "/";
dir += *this->Names.begin();
}
// The local generators are associated with collapsed paths.
dir = cmSystemTools::CollapseFullPath(dir.c_str());
// Lookup the generator.
if(cmLocalGenerator* lg =
(this->Makefile->GetLocalGenerator()
->GetGlobalGenerator()->FindLocalGenerator(dir.c_str())))
{
// Use the makefile for the directory found.
mf = lg->GetMakefile();
}
else
{
// Could not find the directory.
this->SetError
("DIRECTORY scope provided but requested directory was not found. "
"This could be because the directory argument was invalid or, "
"it is valid but has not been processed yet.");
return false;
}
}
// Set or append the property.
const char* name = this->PropertyName.c_str();
std::string value;
if(this->ConstructValue(value, mf->GetProperty(name)))
{
// Set the new property.
mf->SetProperty(name, value.c_str());
}
else
{
// Remove the property.
mf->SetProperty(name, 0);
}
return true;
}
//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleTargetMode()
{
for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
ni != this->Names.end(); ++ni)
{
if(cmTarget* target =
this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
->FindTarget(0, ni->c_str(), true))
{
// Handle the current target.
if(!this->HandleTarget(target))
{
return false;
}
}
else
{
cmOStringStream e;
e << "could not find TARGET " << *ni