Merge branch 'master' of git://public.kitware.com/cmake into 12128_FindProtobuf_module_behavior_under_Windows_is_annoying

This commit is contained in:
Philip Lowman 2011-05-25 22:10:19 -04:00
commit 162f3fb413
37 changed files with 632 additions and 172 deletions

View File

@ -64,7 +64,7 @@ IF(NOT CMAKE_Fortran_COMPILER)
# then 77 or older compilers, gnu is always last in the group,
# so if you paid for a compiler it is picked by default.
SET(CMAKE_Fortran_COMPILER_LIST
ifort ifc efc f95 pathf2003 pathf95 pgf95 lf95 xlf95 fort
ifort ifc af95 af90 efc f95 pathf2003 pathf95 pgf95 lf95 xlf95 fort
gfortran gfortran-4 g95 f90 pathf90 pgf90 xlf90 epcf90 fort77
frt pgf77 xlf fl32 af77 g77 f77
)
@ -72,6 +72,7 @@ IF(NOT CMAKE_Fortran_COMPILER)
# Vendor-specific compiler names.
SET(_Fortran_COMPILER_NAMES_GNU gfortran gfortran-4 g95 g77)
SET(_Fortran_COMPILER_NAMES_Intel ifort ifc efc)
SET(_Fortran_COMPILER_NAMES_Absoft af95 af90 af77)
SET(_Fortran_COMPILER_NAMES_PGI pgf95 pgf90 pgf77)
SET(_Fortran_COMPILER_NAMES_PathScale pathf2003 pathf95 pathf90)
SET(_Fortran_COMPILER_NAMES_XL xlf)

View File

@ -50,14 +50,17 @@ IF(CMAKE_HOST_UNIX)
IF(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*")
EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
RETURN_VALUE val)
ELSE(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*")
ELSEIF(CMAKE_HOST_SYSTEM_NAME MATCHES "OpenBSD")
EXEC_PROGRAM(arch ARGS -s OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
RETURN_VALUE val)
ELSE()
EXEC_PROGRAM(uname ARGS -p OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
RETURN_VALUE val)
IF("${val}" GREATER 0)
EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
RETURN_VALUE val)
ENDIF("${val}" GREATER 0)
ENDIF(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*")
ENDIF()
# check the return of the last uname -m or -p
IF("${val}" GREATER 0)
SET(CMAKE_HOST_SYSTEM_PROCESSOR "unknown")

View File

@ -12,6 +12,8 @@
PRINT *, 'INFO:compiler[G95]'
#elif defined(__PATHSCALE__)
PRINT *, 'INFO:compiler[PathScale]'
#elif defined(__ABSOFT__)
PRINT *, 'INFO:compiler[Absoft]'
#elif defined(__GNUC__)
PRINT *, 'INFO:compiler[GNU]'
#elif defined(__IBMC__)

View File

@ -50,6 +50,12 @@ IF(CMAKE_GENERATOR MATCHES "Makefiles")
IF(DEFINED CMAKE_RULE_MESSAGES)
SET_PROPERTY(GLOBAL PROPERTY RULE_MESSAGES ${CMAKE_RULE_MESSAGES})
ENDIF(DEFINED CMAKE_RULE_MESSAGES)
IF(CMAKE_GENERATOR MATCHES "Unix Makefiles")
SET(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL
"Enable/Disable output of compile commands during generation."
)
MARK_AS_ADVANCED(CMAKE_EXPORT_COMPILE_COMMANDS)
ENDIF(CMAKE_GENERATOR MATCHES "Unix Makefiles")
ENDIF(CMAKE_GENERATOR MATCHES "Makefiles")

View File

@ -29,11 +29,13 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex)
# Construct a regex to match linker lines. It must match both the
# whole line and just the command (argv[0]).
set(linker_regex "^( *|.*[/\\])(${linker}|ld|collect2)[^/\\]*( |$)")
set(linker_exclude_regex "collect2 version ")
set(log "${log} link line regex: [${linker_regex}]\n")
string(REGEX REPLACE "\r?\n" ";" output_lines "${text}")
foreach(line IN LISTS output_lines)
set(cmd)
if("${line}" MATCHES "${linker_regex}")
if("${line}" MATCHES "${linker_regex}" AND
NOT "${line}" MATCHES "${linker_exclude_regex}")
if(UNIX)
separate_arguments(args UNIX_COMMAND "${line}")
else()
@ -64,8 +66,8 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex)
# Object file full path.
list(APPEND implicit_libs_tmp ${arg})
set(log "${log} arg [${arg}] ==> obj [${arg}]\n")
elseif("${arg}" MATCHES "^-Y(P,)?")
# Sun search path.
elseif("${arg}" MATCHES "^-Y(P,)?[^0-9]")
# Sun search path ([^0-9] avoids conflict with Mac -Y<num>).
string(REGEX REPLACE "^-Y(P,)?" "" dirs "${arg}")
string(REPLACE ":" ";" dirs "${dirs}")
list(APPEND implicit_dirs_tmp ${dirs})

View File

@ -489,9 +489,9 @@ ENDIF(CPACK_RPM_PACKAGE_COMPONENT)
# file name by enclosing it between double quotes (thus the sed)
# Then we must authorize any man pages extension (adding * at the end)
# because rpmbuild may automatically compress those files
EXECUTE_PROCESS(COMMAND find -type f -o -type l
COMMAND sed {s:.*/man.*/.*:&*:}
COMMAND sed {s/\\.\\\(.*\\\)/\"\\1\"/}
EXECUTE_PROCESS(COMMAND find . -type f -o -type l
COMMAND sed s:.*/man.*/.*:&*:
COMMAND sed s/\\.\\\(.*\\\)/\"\\1\"/
WORKING_DIRECTORY "${WDIR}"
OUTPUT_VARIABLE CPACK_RPM_INSTALL_FILES)

View File

@ -0,0 +1,8 @@
SET(CMAKE_Fortran_FLAGS_INIT "")
SET(CMAKE_Fortran_FLAGS_DEBUG_INIT "-g")
SET(CMAKE_Fortran_FLAGS_MINSIZEREL_INIT "")
SET(CMAKE_Fortran_FLAGS_RELEASE_INIT "-O3")
SET(CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")
SET(CMAKE_Fortran_MODDIR_FLAG "-YMOD_OUT_DIR=")
SET(CMAKE_Fortran_MODPATH_FLAG "-p")
SET(CMAKE_Fortran_VERBOSE_FLAG "-v")

View File

@ -0,0 +1 @@
set(CMAKE_Fortran_VERBOSE_FLAG "-X -v") # Runs gcc under the hood.

View File

@ -0,0 +1 @@
set(CMAKE_Fortran_VERBOSE_FLAG "-X -v") # Runs gcc under the hood.

View File

@ -21,6 +21,7 @@
#include <cmsys/SystemTools.hxx>
#include <cmsys/Glob.hxx>
#include <sys/stat.h>
//----------------------------------------------------------------------
cmCPackOSXX11Generator::cmCPackOSXX11Generator()
@ -135,6 +136,32 @@ int cmCPackOSXX11Generator::PackageFiles()
return 0;
}
// Two of the files need to have execute permission, so ensure they do:
std::string runTimeScript = dir;
runTimeScript += "/";
runTimeScript += "RuntimeScript";
std::string appScriptName = appdir;
appScriptName += "/";
appScriptName += this->GetOption("CPACK_PACKAGE_FILE_NAME");
mode_t mode;
if (cmsys::SystemTools::GetPermissions(runTimeScript.c_str(), mode))
{
mode |= (S_IXUSR | S_IXGRP | S_IXOTH);
cmsys::SystemTools::SetPermissions(runTimeScript.c_str(), mode);
cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Setting: " << runTimeScript
<< " to permission: " << mode << std::endl);
}
if (cmsys::SystemTools::GetPermissions(appScriptName.c_str(), mode))
{
mode |= (S_IXUSR | S_IXGRP | S_IXOTH);
cmsys::SystemTools::SetPermissions(appScriptName.c_str(), mode);
cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Setting: " << appScriptName
<< " to permission: " << mode << std::endl);
}
std::string output;
std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
tmpFile += "/hdiutilOutput.log";

View File

@ -546,7 +546,7 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
"make based generators. If this variable is supported, "
"then CMake will also provide initial values for the "
"variables with the name "
" CMAKE_C_FLAGS_[Debug|Release|RelWithDebInfo|MinSizeRel]."
" CMAKE_C_FLAGS_[DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL]."
" For example, if CMAKE_BUILD_TYPE is Debug, then "
"CMAKE_C_FLAGS_DEBUG will be added to the CMAKE_C_FLAGS.",false,
"Variables That Change Behavior");

View File

@ -403,7 +403,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
// for each sub project create a linked resource to the source dir
// - only if it is an out-of-source build
this->AppendLinkedResource(fout, "[Subprojects]",
"virtual:/virtual");
"virtual:/virtual", true);
for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
it = this->GlobalGenerator->GetProjectMap().begin();
@ -1082,17 +1082,24 @@ void cmExtraEclipseCDT4Generator
void cmExtraEclipseCDT4Generator
::AppendLinkedResource (cmGeneratedFileStream& fout,
const std::string& name,
const std::string& path)
const std::string& path,
bool isVirtualFolder)
{
const char* locationTag = "location";
if (isVirtualFolder) // ... and not a linked folder
{
locationTag = "locationURI";
}
fout <<
"\t\t<link>\n"
"\t\t\t<name>"
<< cmExtraEclipseCDT4Generator::EscapeForXML(name)
<< "</name>\n"
"\t\t\t<type>2</type>\n"
"\t\t\t<locationURI>"
"\t\t\t<" << locationTag << ">"
<< cmExtraEclipseCDT4Generator::EscapeForXML(path)
<< "</locationURI>\n"
<< "</" << locationTag << ">\n"
"\t\t</link>\n"
;
}

View File

@ -87,7 +87,8 @@ private:
static void AppendLinkedResource (cmGeneratedFileStream& fout,
const std::string& name,
const std::string& path);
const std::string& path,
bool isVirtualFolder = false);
bool AppendOutLinkedResource(cmGeneratedFileStream& fout,
const std::string& defname,

View File

@ -24,13 +24,13 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
this->ForceUnixPaths = true;
this->FindMakeProgramFile = "CMakeUnixFindMake.cmake";
this->ToolSupportsColor = true;
this->NoRuleMessages = false;
#if defined(_WIN32) || defined(__VMS)
this->UseLinkScript = false;
#else
this->UseLinkScript = true;
#endif
this->CommandDatabase = NULL;
}
void cmGlobalUnixMakefileGenerator3
@ -139,56 +139,87 @@ void cmGlobalUnixMakefileGenerator3
}
//----------------------------------------------------------------------------
std::string EscapeJSON(const std::string& s) {
std::string result;
for (std::string::size_type i = 0; i < s.size(); ++i) {
if (s[i] == '"' || s[i] == '\\') {
result += '\\';
}
result += s[i];
}
return result;
}
void cmGlobalUnixMakefileGenerator3::Generate()
{
// first do superclass method
this->cmGlobalGenerator::Generate();
cmake* cm = this->GetCMakeInstance();
if(const char* ruleStatus = cm->GetProperty("RULE_MESSAGES"))
// initialize progress
unsigned long total = 0;
for(ProgressMapType::const_iterator pmi = this->ProgressMap.begin();
pmi != this->ProgressMap.end(); ++pmi)
{
this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus);
total += pmi->second.NumberOfActions;
}
if(!this->NoRuleMessages)
// write each target's progress.make this loop is done twice. Bascially the
// Generate pass counts all the actions, the first loop below determines
// how many actions have progress updates for each target and writes to
// corrrect variable values for everything except the all targets. The
// second loop actually writes out correct values for the all targets as
// well. This is because the all targets require more information that is
// computed in the first loop.
unsigned long current = 0;
for(ProgressMapType::iterator pmi = this->ProgressMap.begin();
pmi != this->ProgressMap.end(); ++pmi)
{
// initialize progress
unsigned long total = 0;
for(ProgressMapType::const_iterator pmi = this->ProgressMap.begin();
pmi != this->ProgressMap.end(); ++pmi)
{
total += pmi->second.NumberOfActions;
}
// write each target's progress.make this loop is done twice. Bascially the
// Generate pass counts all the actions, the first loop below determines
// how many actions have progress updates for each target and writes to
// corrrect variable values for everything except the all targets. The
// second loop actually writes out correct values for the all targets as
// well. This is because the all targets require more information that is
// computed in the first loop.
unsigned long current = 0;
for(ProgressMapType::iterator pmi = this->ProgressMap.begin();
pmi != this->ProgressMap.end(); ++pmi)
{
pmi->second.WriteProgressVariables(total, current);
}
for(unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
{
cmLocalUnixMakefileGenerator3 *lg =
static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
std::string markFileName = lg->GetMakefile()->GetStartOutputDirectory();
markFileName += "/";
markFileName += cmake::GetCMakeFilesDirectory();
markFileName += "/progress.marks";
cmGeneratedFileStream markFile(markFileName.c_str());
markFile << this->CountProgressMarksInAll(lg) << "\n";
}
pmi->second.WriteProgressVariables(total, current);
}
for(unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
{
cmLocalUnixMakefileGenerator3 *lg =
static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
std::string markFileName = lg->GetMakefile()->GetStartOutputDirectory();
markFileName += "/";
markFileName += cmake::GetCMakeFilesDirectory();
markFileName += "/progress.marks";
cmGeneratedFileStream markFile(markFileName.c_str());
markFile << this->CountProgressMarksInAll(lg) << "\n";
}
// write the main makefile
this->WriteMainMakefile2();
this->WriteMainCMakefile();
if (this->CommandDatabase != NULL) {
*this->CommandDatabase << std::endl << "]";
delete this->CommandDatabase;
this->CommandDatabase = NULL;
}
}
void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
const std::string &sourceFile, const std::string &workingDirectory,
const std::string &compileCommand) {
if (this->CommandDatabase == NULL)
{
std::string commandDatabaseName =
std::string(this->GetCMakeInstance()->GetHomeOutputDirectory())
+ "/compile_commands.json";
this->CommandDatabase =
new cmGeneratedFileStream(commandDatabaseName.c_str());
*this->CommandDatabase << "[" << std::endl;
} else {
*this->CommandDatabase << "," << std::endl;
}
*this->CommandDatabase << "{" << std::endl
<< " \"directory\": \"" << EscapeJSON(workingDirectory) << "\","
<< std::endl
<< " \"command\": \"" << EscapeJSON(compileCommand) << "\","
<< std::endl
<< " \"file\": \"" << EscapeJSON(sourceFile) << "\""
<< std::endl << "}";
}
void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
@ -747,34 +778,30 @@ cmGlobalUnixMakefileGenerator3
// Write the rule.
localName += "/all";
depends.clear();
std::string progressDir;
if(!this->NoRuleMessages)
std::string progressDir =
lg->GetMakefile()->GetHomeOutputDirectory();
progressDir += cmake::GetCMakeFilesDirectory();
{
progressDir =
lg->GetMakefile()->GetHomeOutputDirectory();
progressDir += cmake::GetCMakeFilesDirectory();
cmOStringStream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report ";
// all target counts
progCmd << lg->Convert(progressDir.c_str(),
cmLocalGenerator::FULL,
cmLocalGenerator::SHELL);
progCmd << " ";
std::vector<unsigned long>& progFiles =
this->ProgressMap[&t->second].Marks;
for (std::vector<unsigned long>::iterator i = progFiles.begin();
i != progFiles.end(); ++i)
{
cmOStringStream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report ";
// all target counts
progCmd << lg->Convert(progressDir.c_str(),
cmLocalGenerator::FULL,
cmLocalGenerator::SHELL);
progCmd << " ";
std::vector<unsigned long>& progFiles =
this->ProgressMap[&t->second].Marks;
for (std::vector<unsigned long>::iterator i = progFiles.begin();
i != progFiles.end(); ++i)
{
progCmd << " " << *i;
}
commands.push_back(progCmd.str());
progCmd << " " << *i;
}
progressDir = "Built target ";
progressDir += t->first;
lg->AppendEcho(commands,progressDir.c_str());
commands.push_back(progCmd.str());
}
progressDir = "Built target ";
progressDir += t->first;
lg->AppendEcho(commands,progressDir.c_str());
this->AppendGlobalTargetDepends(depends,t->second);
lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
@ -790,42 +817,38 @@ cmGlobalUnixMakefileGenerator3
"all", depends, commands, true);
}
if(!this->NoRuleMessages)
{
// Write the rule.
commands.clear();
progressDir = lg->GetMakefile()->GetHomeOutputDirectory();
progressDir += cmake::GetCMakeFilesDirectory();
// Write the rule.
commands.clear();
progressDir = lg->GetMakefile()->GetHomeOutputDirectory();
progressDir += cmake::GetCMakeFilesDirectory();
{
// TODO: Convert the total progress count to a make variable.
cmOStringStream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
// # in target
progCmd << lg->Convert(progressDir.c_str(),
cmLocalGenerator::FULL,
cmLocalGenerator::SHELL);
//
std::set<cmTarget *> emitted;
progCmd << " "
<< this->CountProgressMarksInTarget(&t->second, emitted);
commands.push_back(progCmd.str());
}
}
{
// TODO: Convert the total progress count to a make variable.
cmOStringStream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
// # in target
progCmd << lg->Convert(progressDir.c_str(),
cmLocalGenerator::FULL,
cmLocalGenerator::SHELL);
//
std::set<cmTarget *> emitted;
progCmd << " "
<< this->CountProgressMarksInTarget(&t->second, emitted);
commands.push_back(progCmd.str());
}
std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash();
tmp += "Makefile2";
commands.push_back(lg->GetRecursiveMakeCall
(tmp.c_str(),localName.c_str()));
if(!this->NoRuleMessages)
{
cmOStringStream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
progCmd << lg->Convert(progressDir.c_str(),
cmLocalGenerator::FULL,
cmLocalGenerator::SHELL);
progCmd << " 0";
commands.push_back(progCmd.str());
}
{
cmOStringStream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
progCmd << lg->Convert(progressDir.c_str(),
cmLocalGenerator::FULL,
cmLocalGenerator::SHELL);
progCmd << " 0";
commands.push_back(progCmd.str());
}
depends.clear();
depends.push_back("cmake_check_build_system");
localName = lg->GetRelativeTargetDirectory(t->second);

View File

@ -112,6 +112,10 @@ public:
/** Record per-target progress information. */
void RecordTargetProgress(cmMakefileTargetGenerator* tg);
void AddCXXCompileCommand(const std::string &sourceFile,
const std::string &workingDirectory,
const std::string &compileCommand);
protected:
void WriteMainMakefile2();
void WriteMainCMakefile();
@ -159,8 +163,6 @@ protected:
// in the rule to satisfy the make program.
std::string EmptyRuleHackCommand;
bool NoRuleMessages;
// Store per-target progress counters.
struct TargetProgress
{
@ -178,6 +180,8 @@ protected:
size_t CountProgressMarksInTarget(cmTarget* target,
std::set<cmTarget*>& emitted);
size_t CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg);
cmGeneratedFileStream *CommandDatabase;
};
#endif

View File

@ -1770,10 +1770,14 @@ cmLocalVisualStudio7Generator
vskey += "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion";
cmSystemTools::ReadRegistryValue(vskey.c_str(), intelVersion,
cmSystemTools::KeyWOW64_32);
// Version 10.1 actually uses 9.10 in project files!
if(intelVersion == "10.1")
if (intelVersion == "12.0")
{
// Version 12 actually uses 11.0 in project files!
intelVersion = "11.0" ;
}
else if(intelVersion == "10.1")
{
// Version 10.1 actually uses 9.10 in project files!
intelVersion = "9.10";
}

View File

@ -249,32 +249,56 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
}
//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
std::string cmMakefileTargetGenerator::GetFlags(const std::string &l)
{
// write language flags for target
std::set<cmStdString> languages;
this->Target->GetLanguages(languages);
// put the compiler in the rules.make file so that if it changes
// things rebuild
for(std::set<cmStdString>::const_iterator l = languages.begin();
l != languages.end(); ++l)
ByLanguageMap::iterator i = this->FlagsByLanguage.find(l);
if (i == this->FlagsByLanguage.end())
{
cmStdString compiler = "CMAKE_";
compiler += *l;
compiler += "_COMPILER";
*this->FlagFileStream << "# compile " << l->c_str() << " with " <<
this->Makefile->GetSafeDefinition(compiler.c_str()) << "\n";
}
for(std::set<cmStdString>::const_iterator l = languages.begin();
l != languages.end(); ++l)
{
const char *lang = l->c_str();
std::string flags;
std::string defines;
const char *lang = l.c_str();
bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) ||
(this->Target->GetType() == cmTarget::MODULE_LIBRARY));
// Add language feature flags.
this->AddFeatureFlags(flags, lang);
this->LocalGenerator->AddArchitectureFlags(flags, this->Target,
lang, this->ConfigName);
// Fortran-specific flags computed for this target.
if(l == "Fortran")
{
this->AddFortranFlags(flags);
}
// Add shared-library flags if needed.
this->LocalGenerator->AddSharedFlags(flags, lang, shared);
// Add include directory flags.
this->AddIncludeFlags(flags, lang);
// Append old-style preprocessor definition flags.
this->LocalGenerator->
AppendFlags(flags, this->Makefile->GetDefineFlags());
// Add include directory flags.
this->LocalGenerator->
AppendFlags(flags,this->GetFrameworkFlags().c_str());
ByLanguageMap::value_type entry(l, flags);
i = this->FlagsByLanguage.insert(entry).first;
}
return i->second;
}
std::string cmMakefileTargetGenerator::GetDefines(const std::string &l)
{
ByLanguageMap::iterator i = this->DefinesByLanguage.find(l);
if (i == this->DefinesByLanguage.end())
{
std::string defines;
const char *lang = l.c_str();
// Add the export symbol definition for shared library objects.
if(const char* exportMacro = this->Target->GetExportMacro())
{
@ -294,40 +318,41 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
this->LocalGenerator->AppendDefines
(defines, this->Target->GetProperty(defPropName.c_str()), lang);
// Add language feature flags.
this->AddFeatureFlags(flags, lang);
ByLanguageMap::value_type entry(l, defines);
i = this->DefinesByLanguage.insert(entry).first;
}
return i->second;
}
this->LocalGenerator->AddArchitectureFlags(flags, this->Target,
lang, this->ConfigName);
void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
{
// write language flags for target
std::set<cmStdString> languages;
this->Target->GetLanguages(languages);
// put the compiler in the rules.make file so that if it changes
// things rebuild
for(std::set<cmStdString>::const_iterator l = languages.begin();
l != languages.end(); ++l)
{
cmStdString compiler = "CMAKE_";
compiler += *l;
compiler += "_COMPILER";
*this->FlagFileStream << "# compile " << l->c_str() << " with " <<
this->Makefile->GetSafeDefinition(compiler.c_str()) << "\n";
}
// Fortran-specific flags computed for this target.
if(*l == "Fortran")
{
this->AddFortranFlags(flags);
}
// Add shared-library flags if needed.
this->LocalGenerator->AddSharedFlags(flags, lang, shared);
// Add include directory flags.
this->AddIncludeFlags(flags, lang);
// Append old-style preprocessor definition flags.
this->LocalGenerator->
AppendFlags(flags, this->Makefile->GetDefineFlags());
// Add include directory flags.
this->LocalGenerator->
AppendFlags(flags,this->GetFrameworkFlags().c_str());
*this->FlagFileStream << lang << "_FLAGS = " << flags << "\n\n";
*this->FlagFileStream << lang << "_DEFINES = " << defines << "\n\n";
for(std::set<cmStdString>::const_iterator l = languages.begin();
l != languages.end(); ++l)
{
*this->FlagFileStream << *l << "_FLAGS = " << this->GetFlags(*l) << "\n\n";
*this->FlagFileStream << *l << "_DEFINES = " << this->GetDefines(*l) <<
"\n\n";
}
// Add target-specific flags.
if(this->Target->GetProperty("COMPILE_FLAGS"))
{
std::string flags;
std::string flags;
this->LocalGenerator->AppendFlags
(flags, this->Target->GetProperty("COMPILE_FLAGS"));
*this->FlagFileStream << "# TARGET_FLAGS = " << flags << "\n\n";
@ -641,6 +666,9 @@ cmMakefileTargetGenerator
vars.Flags = flags.c_str();
vars.Defines = defines.c_str();
bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) ||
(strcmp(lang, "CXX") == 0));
// Construct the compile rules.
{
std::string compileRuleVar = "CMAKE_";
@ -651,6 +679,23 @@ cmMakefileTargetGenerator
std::vector<std::string> compileCommands;
cmSystemTools::ExpandListArgument(compileRule, compileCommands);
if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") &&
lang_is_c_or_cxx && compileCommands.size() == 1)
{
std::string compileCommand = compileCommands[0];
this->LocalGenerator->ExpandRuleVariables(compileCommand, vars);
std::string workingDirectory =
this->LocalGenerator->Convert(
this->Makefile->GetStartOutputDirectory(), cmLocalGenerator::FULL);
compileCommand.replace(compileCommand.find(langFlags),
langFlags.size(), this->GetFlags(lang));
std::string langDefines = std::string("$(") + lang + "_DEFINES)";
compileCommand.replace(compileCommand.find(langDefines),
langDefines.size(), this->GetDefines(lang));
this->GlobalGenerator->AddCXXCompileCommand(
source.GetFullPath(), workingDirectory, compileCommand);
}
// Expand placeholders in the commands.
for(std::vector<std::string>::iterator i = compileCommands.begin();
i != compileCommands.end(); ++i)
@ -691,8 +736,6 @@ cmMakefileTargetGenerator
}
}
bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) ||
(strcmp(lang, "CXX") == 0));
bool do_preprocess_rules = lang_is_c_or_cxx &&
this->LocalGenerator->GetCreatePreprocessedSourceRules();
bool do_assembly_rules = lang_is_c_or_cxx &&

View File

@ -216,6 +216,12 @@ protected:
std::string MacContentDirectory;
std::set<cmStdString> MacContentFolders;
typedef std::map<cmStdString, cmStdString> ByLanguageMap;
std::string GetFlags(const std::string &l);
ByLanguageMap FlagsByLanguage;
std::string GetDefines(const std::string &l);
ByLanguageMap DefinesByLanguage;
// Target-wide Fortran module output directory.
bool FortranModuleDirectoryComputed;
std::string FortranModuleDirectory;

View File

@ -47,8 +47,7 @@ public:
*/
virtual const char* GetTerseDocumentation()
{
return
"Output a list of required source files for a specified source file.";
return "Deprecated. Approximate C preprocessor dependency scanning.";
}
/**
@ -57,12 +56,22 @@ public:
virtual const char* GetFullDocumentation()
{
return
"This command exists only because ancient CMake versions provided it. "
"CMake handles preprocessor dependency scanning automatically using a "
"more advanced scanner.\n"
" output_required_files(srcfile outputfile)\n"
"Outputs a list of all the source files that are required by the "
"specified srcfile. This list is written into outputfile. This is "
"similar to writing out the dependencies for srcfile except that it "
"jumps from .h files into .cxx, .c and .cpp files if possible.";
}
/** This command is kept for compatibility with older CMake versions. */
virtual bool IsDiscouraged()
{
return true;
}
cmTypeMacro(cmOutputRequiredFilesCommand, cmCommand);
void ListDependencies(cmDependInformation const *info,

View File

@ -770,7 +770,7 @@ bool cmStringCommand
static bool seeded = false;
bool force_seed = false;
int seed = (int) time(NULL);
unsigned int seed = 0;
int length = 5;
const char cmStringCommandDefaultAlphabet[] = "qwertyuiopasdfghjklzxcvbnm"
"QWERTYUIOPASDFGHJKLZXCVBNM"
@ -797,7 +797,7 @@ bool cmStringCommand
else if ( args[i] == "RANDOM_SEED" )
{
++i;
seed = atoi(args[i].c_str());
seed = static_cast<unsigned int>(atoi(args[i].c_str()));
force_seed = true;
}
}
@ -825,7 +825,7 @@ bool cmStringCommand
if (!seeded || force_seed)
{
seeded = true;
srand(seed);
srand(force_seed? seed : cmSystemTools::RandomSeed());
}
const char* alphaPtr = alphabet.c_str();

View File

@ -9,6 +9,9 @@
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#if defined(_MSC_VER) && _MSC_VER < 1300
# define _WIN32_WINNT 0x0400 /* for wincrypt.h */
#endif
#include "cmSystemTools.h"
#include <ctype.h>
#include <errno.h>
@ -31,7 +34,9 @@
#if defined(_WIN32)
# include <windows.h>
# include <wincrypt.h>
#else
# include <sys/time.h>
# include <sys/types.h>
# include <unistd.h>
# include <utime.h>
@ -440,6 +445,13 @@ public:
args.push_back(*arg);
}
}
void Store(std::vector<cmStdString>& args) const
{
for(char** arg = this->ArgV; arg && *arg; ++arg)
{
args.push_back(*arg);
}
}
};
//----------------------------------------------------------------------------
@ -451,6 +463,15 @@ void cmSystemTools::ParseUnixCommandLine(const char* command,
argv.Store(args);
}
//----------------------------------------------------------------------------
void cmSystemTools::ParseUnixCommandLine(const char* command,
std::vector<cmStdString>& args)
{
// Invoke the underlying parser.
cmSystemToolsArgV argv = cmsysSystem_Parse_CommandForUnix(command, 0);
argv.Store(args);
}
std::string cmSystemTools::EscapeWindowsShellArgument(const char* arg,
int shell_flags)
{
@ -2232,6 +2253,71 @@ bool cmSystemTools::FileTimeSet(const char* fname, cmSystemToolsFileTime* t)
return true;
}
//----------------------------------------------------------------------------
#ifdef _WIN32
# ifndef CRYPT_SILENT
# define CRYPT_SILENT 0x40 /* Not defined by VS 6 version of header. */
# endif
static int WinCryptRandom(void* data, size_t size)
{
int result = 0;
HCRYPTPROV hProvider = 0;
if(CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
{
result = CryptGenRandom(hProvider, (DWORD)size, (BYTE*)data)? 1:0;
CryptReleaseContext(hProvider, 0);
}
return result;
}
#endif
//----------------------------------------------------------------------------
unsigned int cmSystemTools::RandomSeed()
{
#if defined(_WIN32) && !defined(__CYGWIN__)
unsigned int seed = 0;
// Try using a real random source.
if(WinCryptRandom(&seed, sizeof(seed)))
{
return seed;
}
// Fall back to the time and pid.
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
unsigned int t1 = static_cast<unsigned int>(ft.dwHighDateTime);
unsigned int t2 = static_cast<unsigned int>(ft.dwLowDateTime);
unsigned int pid = static_cast<unsigned int>(GetCurrentProcessId());
return t1 ^ t2 ^ pid;
#else
union
{
unsigned int integer;
char bytes[sizeof(unsigned int)];
} seed;
// Try using a real random source.
std::ifstream fin("/dev/urandom");
if(fin && fin.read(seed.bytes, sizeof(seed)) &&
fin.gcount() == sizeof(seed))
{
return seed.integer;
}
// Fall back to the time and pid.
struct timeval t;
gettimeofday(&t, 0);
unsigned int pid = static_cast<unsigned int>(getpid());
unsigned int tv_sec = static_cast<unsigned int>(t.tv_sec);
unsigned int tv_usec = static_cast<unsigned int>(t.tv_usec);
// Since tv_usec never fills more than 11 bits we shift it to fill
// in the slow-changing high-order bits of tv_sec.
return tv_sec ^ (tv_usec << 21) ^ pid;
#endif
}
//----------------------------------------------------------------------------
static std::string cmSystemToolsExecutableDirectory;
void cmSystemTools::FindExecutableDirectory(const char* argv0)

View File

@ -237,6 +237,8 @@ public:
/** Parse arguments out of a unix command line string. */
static void ParseUnixCommandLine(const char* command,
std::vector<std::string>& args);
static void ParseUnixCommandLine(const char* command,
std::vector<cmStdString>& args);
/** Compute an escaped version of the given argument for use in a
windows shell. See kwsys/System.h.in for details. */
@ -402,6 +404,9 @@ public:
static bool FileTimeGet(const char* fname, cmSystemToolsFileTime* t);
static bool FileTimeSet(const char* fname, cmSystemToolsFileTime* t);
/** Random seed generation. */
static unsigned int RandomSeed();
/** Find the directory containing the running executable. Save it
in a global location to be queried by GetExecutableDirectory
later. */

View File

@ -455,7 +455,11 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
{
lang = "None";
}
if(lang[0] == 'C')
if(header)
{
headers.push_back(sf);
}
else if(lang[0] == 'C')
{
clCompile.push_back(sf);
}
@ -467,10 +471,6 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
{
customBuild.push_back(sf);
}
else if(header)
{
headers.push_back(sf);
}
else if(ext == "idl")
{
idls.push_back(sf);

View File

@ -41,6 +41,7 @@ int main(int argc, char* argv[])
if(!ofp)
{
fprintf(stderr, "Cannot open output file: \"%s\"\n", argv[2]);
fclose(ifp);
return 2;
}

View File

@ -18,4 +18,4 @@ SET(KWSYS_DATE_STAMP_YEAR 2011)
SET(KWSYS_DATE_STAMP_MONTH 05)
# KWSys version date day component. Format is DD.
SET(KWSYS_DATE_STAMP_DAY 01)
SET(KWSYS_DATE_STAMP_DAY 25)

View File

@ -30,3 +30,8 @@ endif()
foreach(test ${CMakeLib_TESTS})
add_test(CMakeLib.${test} CMakeLibTests ${test})
endforeach()
if(TEST_CompileCommandOutput)
add_executable(runcompilecommands run_compile_commands.cxx)
target_link_libraries(runcompilecommands CMakeLib)
endif()

View File

@ -0,0 +1,141 @@
#include "cmSystemTools.h"
class CompileCommandParser {
public:
class CommandType: public std::map<cmStdString, cmStdString>
{
public:
cmStdString const& at(cmStdString const& k) const
{
const_iterator i = this->find(k);
if(i != this->end()) { return i->second; }
static cmStdString emptyString;
return emptyString;
}
};
typedef std::vector<CommandType> TranslationUnitsType;
CompileCommandParser(std::ifstream *input)
{
this->Input = input;
}
void Parse()
{
NextNonWhitespace();
ParseTranslationUnits();
}
const TranslationUnitsType& GetTranslationUnits()
{
return this->TranslationUnits;
}
private:
void ParseTranslationUnits()
{
this->TranslationUnits = TranslationUnitsType();
ExpectOrDie('[', "at start of compile command file");
do
{
ParseTranslationUnit();
this->TranslationUnits.push_back(this->Command);
} while(Expect(','));
ExpectOrDie(']', "at end of array");
}
void ParseTranslationUnit()
{
this->Command = CommandType();
if(!Expect('{')) return;
if(Expect('}')) return;
do
{
ParseString();
std::string name = this->String;
ExpectOrDie(':', "between name and value");
ParseString();
std::string value = this->String;
this->Command[name] = value;
} while(Expect(','));
ExpectOrDie('}', "at end of object");
}
void ParseString()
{
this->String.clear();
if(!Expect('"')) return;
while (!Expect('"'))
{
Expect('\\');
this->String.push_back(C);
Next();
}
}
bool Expect(char c)
{
if(this->C == c)
{
NextNonWhitespace();
return true;
}
return false;
}
void ExpectOrDie(char c, const std::string & message)
{
if (!Expect(c))
ErrorExit(std::string("'") + c + "' expected " + message + ".");
}
void NextNonWhitespace()
{
do { Next(); } while (IsWhitespace());
}
void Next()
{
this->C = char(Input->get());
if (this->Input->bad()) ErrorExit("Unexpected end of file.");
}
void ErrorExit(const std::string &message) {
std::cout << "ERROR: " << message;
exit(1);
}
bool IsWhitespace()
{
return (this->C == ' ' || this->C == '\t' ||
this->C == '\n' || this->C == '\r');
}
char C;
TranslationUnitsType TranslationUnits;
CommandType Command;
std::string String;
std::ifstream *Input;
};
int main ()
{
std::ifstream file("compile_commands.json");
CompileCommandParser parser(&file);
parser.Parse();
for(CompileCommandParser::TranslationUnitsType::const_iterator
it = parser.GetTranslationUnits().begin(),
end = parser.GetTranslationUnits().end(); it != end; ++it)
{
std::vector<cmStdString> command;
cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), command);
if (!cmSystemTools::RunSingleCommand(
command, 0, 0, it->at("directory").c_str()))
{
std::cout << "ERROR: Failed to run command \""
<< command[0] << "\"" << std::endl;
exit(1);
}
}
return 0;
}

View File

@ -11,6 +11,7 @@ MACRO(ADD_TEST_MACRO NAME COMMAND)
--build-generator ${CMAKE_TEST_GENERATOR}
--build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
--build-project ${proj}
${${NAME}_EXTRA_OPTIONS}
--test-command ${COMMAND} ${ARGN})
LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${dir}")
ENDMACRO(ADD_TEST_MACRO)
@ -39,6 +40,10 @@ CONFIGURE_FILE(${CMake_SOURCE_DIR}/Tests/EnforceConfig.cmake.in
# Testing
IF(BUILD_TESTING)
IF("${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
SET(TEST_CompileCommandOutput 1)
ENDIF()
ADD_SUBDIRECTORY(CMakeLib)
# Collect a list of all test build directories.
@ -2031,6 +2036,13 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
ENDIF()
SET_TESTS_PROPERTIES(Contracts.${project} PROPERTIES TIMEOUT ${timeout})
ENDFOREACH()
IF(TEST_CompileCommandOutput)
SET(CompileCommandOutput_EXTRA_OPTIONS
--build-options -DMAKE_SUPPORTS_SPACES=${MAKE_IS_GNU})
ADD_TEST_MACRO(CompileCommandOutput
"${CMake_BINARY_DIR}/Tests/CMakeLib/runcompilecommands")
ENDIF()
ENDIF(BUILD_TESTING)
SUBDIRS(CMakeTests)

View File

@ -84,6 +84,13 @@ set(linux64_nagfor_dirs "/usr/lib/gcc/x86_64-redhat-linux/4.4.5;/usr/lib64;/lib6
set(linux64_nagfor_obj_regex "^/usr/local/NAG/lib")
list(APPEND platforms linux64_nagfor)
# absoft dummy.f -X -v
set(linux64_absoft_text "collect2 version 4.4.5 (x86-64 Linux/ELF)
/usr/bin/ld --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtbegin.o -L/opt/absoft11.1/lib64 -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5 -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5 -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../.. /tmp/E3Bii1/dummy.o -v -laf90math -lafio -lamisc -labsoftmain -laf77math -lm -lmv -lpthread -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crtn.o")
set(linux64_absoft_libs "af90math;afio;amisc;absoftmain;af77math;m;mv;pthread;c")
set(linux64_absoft_dirs "/opt/absoft11.1/lib64;/usr/lib/gcc/x86_64-linux-gnu/4.4.5;/usr/lib;/lib")
list(APPEND platforms linux64_absoft)
# gcc dummy.c -v # in strange path
set(linux64_test1_text "
/this/might/match/as/a/linker/ld/but/it/is/not because the ld is not the last path component
@ -125,6 +132,14 @@ set(mac_ppc_g++_libs "stdc++")
set(mac_ppc_g++_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib")
list(APPEND platforms mac_ppc_g++)
# absoft dummy.f -X -v
set(mac_absoft_text "collect2 version 4.2.1 (Apple Inc. build 5664) (i686 Darwin)
/usr/libexec/gcc/i686-apple-darwin10/4.2.1/ld -dynamic -arch i386 -macosx_version_min 10.6.6 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/Applications/Absoft11.1/lib -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/folders/04/04+Djjm8GZWBmuEdp2Gsw++++TM/-Tmp-//bTAoJc/dummy.o -v -Y 10 -laf90math -lafio -lamisc -labsoftmain -laf77math -lm -lmv -lSystem -lgcc -lSystem
")
set(mac_absoft_libs "af90math;afio;amisc;absoftmain;af77math;m;mv")
set(mac_absoft_dirs "/Applications/Absoft11.1/lib;/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib")
list(APPEND platforms mac_absoft)
#-----------------------------------------------------------------------------
# Sun

View File

@ -0,0 +1,16 @@
# a simple C only test case
cmake_minimum_required (VERSION 2.6)
project (CompileCommandOutput CXX)
SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_DEBUG_POSTFIX "_test_debug_postfix")
IF(MAKE_SUPPORTS_SPACES)
SET(test1_srcs "file with spaces.cxx")
ELSE()
SET(test1_srcs "file_with_underscores.cxx")
ENDIF()
ADD_LIBRARY(test1 STATIC ${test1_srcs})
ADD_LIBRARY(test2 SHARED "../CompileCommandOutput/relative.cxx")
INCLUDE_DIRECTORIES(${CompileCommandOutput_SOURCE_DIR}/../../Source)
ADD_EXECUTABLE(CompileCommandOutput compile_command_output.cxx)
TARGET_LINK_LIBRARIES(CompileCommandOutput test1 test2)

View File

@ -0,0 +1,9 @@
#include "file_with_underscores.h"
#include "relative.h"
int main (int argc, char** argv)
{
file_with_underscores();
relative();
return 0;
}

View File

@ -0,0 +1 @@
#include "file_with_underscores.cxx"

View File

@ -0,0 +1,3 @@
#include "file_with_underscores.h"
void file_with_underscores() {}

View File

@ -0,0 +1 @@
void file_with_underscores();

View File

@ -0,0 +1,3 @@
#include "relative.h"
void relative() {}

View File

@ -0,0 +1,11 @@
#if defined(_WIN32)
# ifdef test2_EXPORTS
# define TEST2_EXPORT __declspec(dllexport)
# else
# define TEST2_EXPORT __declspec(dllimport)
# endif
#else
# define TEST2_EXPORT
#endif
TEST2_EXPORT void relative();

View File

@ -45,7 +45,7 @@ function(test_fortran_c_interface_module)
FortranCInterface_VERIFY()
FortranCInterface_VERIFY(CXX)
if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "SunPro|MIPSpro|PathScale")
if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "SunPro|MIPSpro|PathScale|Absoft")
set(module_expected 1)
endif()
if(FortranCInterface_MODULE_FOUND OR module_expected)
@ -119,6 +119,9 @@ if(("${CMAKE_Fortran_COMPILER_ID}" MATCHES "Intel")
)
set(COMPATABLE_COMPILERS TRUE)
endif()
if("${CMAKE_Fortran_COMPILER_ID}:${CMAKE_C_COMPILER_ID}" MATCHES "Absoft:GNU")
set(COMPATABLE_COMPILERS TRUE)
endif()
if(COMPATABLE_COMPILERS
OR ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "${CMAKE_C_COMPILER_ID}" ))
test_fortran_c_interface_module()