From 52eb0ccac76b0f4066af11d9ed4537204633548a Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 7 Jan 2008 16:12:37 -0500 Subject: BUG: Restore old interface of "make foo.o" and "make foo.i" even though object file names now include source extensions. For Java we also need to always remove the source extension (.java -> .class). This fixes the re-opening of bug #6169. --- Modules/CMakeJavaCompiler.cmake.in | 1 + Source/cmLocalGenerator.cxx | 25 ++++++++++-- Source/cmLocalGenerator.h | 3 +- Source/cmLocalUnixMakefileGenerator3.cxx | 70 ++++++++++++++++++++++++++++---- Source/cmLocalUnixMakefileGenerator3.h | 10 +++-- Source/cmMakefileTargetGenerator.cxx | 14 ++++--- 6 files changed, 104 insertions(+), 19 deletions(-) diff --git a/Modules/CMakeJavaCompiler.cmake.in b/Modules/CMakeJavaCompiler.cmake.in index 83c1ee4..79c9288 100644 --- a/Modules/CMakeJavaCompiler.cmake.in +++ b/Modules/CMakeJavaCompiler.cmake.in @@ -7,6 +7,7 @@ SET(CMAKE_Java_COMPILER_LOADED 1) SET(CMAKE_Java_SOURCE_FILE_EXTENSIONS java) SET(CMAKE_Java_LINKER_PREFERENCE 40) SET(CMAKE_Java_OUTPUT_EXTENSION .class) +SET(CMAKE_Java_OUTPUT_EXTENSION_REPLACE 1) SET(CMAKE_STATIC_LIBRARY_PREFIX_Java "") SET(CMAKE_STATIC_LIBRARY_SUFFIX_Java ".jar") SET(CMAKE_Java_COMPILER_ENV_VAR "JAVA_COMPILER") diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index d22a2ef..f91ed10 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2700,7 +2700,8 @@ cmLocalGenerator std::string cmLocalGenerator ::GetObjectFileNameWithoutTarget(const cmSourceFile& source, - std::string::size_type dir_len) + std::string::size_type dir_len, + bool* hasSourceExtension) { // Construct the object file name using the full path to the source // file which is its only unique identification. @@ -2751,11 +2752,25 @@ cmLocalGenerator // Replace the original source file extension with the object file // extension. + bool keptSourceExtension = true; if(!source.GetPropertyAsBool("KEEP_EXTENSION")) { - // Remove the original extension for CMake 2.4 compatibility. - if(this->NeedBackwardsCompatibility(2, 4)) + // Decide whether this language wants to replace the source + // extension with the object extension. For CMake 2.4 + // compatibility do this by default. + bool replaceExt = this->NeedBackwardsCompatibility(2, 4); + if(!replaceExt) + { + std::string repVar = "CMAKE_"; + repVar += source.GetLanguage(); + repVar += "_OUTPUT_EXTENSION_REPLACE"; + replaceExt = this->Makefile->IsOn(repVar.c_str()); + } + + // Remove the source extension if it is to be replaced. + if(replaceExt) { + keptSourceExtension = false; std::string::size_type dot_pos = objectName.rfind("."); if(dot_pos != std::string::npos) { @@ -2767,6 +2782,10 @@ cmLocalGenerator objectName += this->GlobalGenerator->GetLanguageOutputExtension(source); } + if(hasSourceExtension) + { + *hasSourceExtension = keptSourceExtension; + } // Convert to a safe name. return this->CreateSafeUniqueObjectFileName(objectName.c_str(), dir_len); diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 7c61ced..ac520b0 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -314,7 +314,8 @@ protected: // Compute object file names. std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source, - std::string::size_type dir_len); + std::string::size_type dir_len, + bool* hasSourceExtension = 0); std::string& CreateSafeUniqueObjectFileName(const char* sin, std::string::size_type dir_len); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 44307c7..0976e17 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -38,6 +38,25 @@ #include //---------------------------------------------------------------------------- +// Helper function used below. +static std::string cmSplitExtension(std::string const& in, std::string& base) +{ + std::string ext; + std::string::size_type dot_pos = in.rfind("."); + if(dot_pos != std::string::npos) + { + // Remove the extension first in case &base == &in. + ext = in.substr(dot_pos, std::string::npos); + base = in.substr(0, dot_pos); + } + else + { + base = in; + } + return ext; +} + +//---------------------------------------------------------------------------- cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3() { this->SilentNoColon = false; @@ -298,12 +317,45 @@ void cmLocalUnixMakefileGenerator3 ::WriteObjectConvenienceRule(std::ostream& ruleFileStream, const char* comment, const char* output, - LocalObjectInfo const& targets) + LocalObjectInfo const& info) { + // If the rule includes the source file extension then create a + // version that has the extension removed. The help should include + // only the version without source extension. + bool inHelp = true; + if(info.HasSourceExtension) + { + // Remove the last extension. This should be kept. + std::string outBase1 = output; + std::string outExt1 = cmSplitExtension(outBase1, outBase1); + + // Now remove the source extension and put back the last + // extension. + std::string outNoExt; + cmSplitExtension(outBase1, outNoExt); + outNoExt += outExt1; + + // Add a rule to drive the rule below. + std::vector depends; + depends.push_back(output); + std::vector commands; + cmGlobalUnixMakefileGenerator3* gg = + static_cast(this->GlobalGenerator); + std::string emptyCommand = gg->GetEmptyRuleHackCommand(); + if(!emptyCommand.empty()) + { + commands.push_back(emptyCommand); + } + + this->WriteMakeRule(ruleFileStream, 0, + outNoExt.c_str(), depends, commands, true, true); + inHelp = false; + } + // Recursively make the rule for each target using the object file. std::vector commands; - for(std::vector::const_iterator t = targets.begin(); - t != targets.end(); ++t) + for(std::vector::const_iterator t = info.begin(); + t != info.end(); ++t) { std::string tgtMakefileName = this->GetRelativeTargetDirectory(*(t->Target)); @@ -322,7 +374,7 @@ cmLocalUnixMakefileGenerator3 // Write the rule to the makefile. std::vector no_depends; this->WriteMakeRule(ruleFileStream, comment, - output, no_depends, commands, true, true); + output, no_depends, commands, true, inHelp); } //---------------------------------------------------------------------------- @@ -1800,13 +1852,16 @@ std::string cmLocalUnixMakefileGenerator3 ::GetObjectFileName(cmTarget& target, const cmSourceFile& source, - std::string* nameWithoutTargetDir) + std::string* nameWithoutTargetDir, + bool* hasSourceExtension) { if(const char* fileTargetDirectory = source.GetProperty("MACOSX_PACKAGE_LOCATION")) { // Special handling for OSX package files. - std::string objectName = this->GetObjectFileNameWithoutTarget(source, 0); + std::string objectName = + this->GetObjectFileNameWithoutTarget(source, 0, + hasSourceExtension); if(nameWithoutTargetDir) { *nameWithoutTargetDir = objectName; @@ -1857,7 +1912,8 @@ cmLocalUnixMakefileGenerator3 dir_len += 1; dir_len += obj.size(); std::string objectName = - this->GetObjectFileNameWithoutTarget(source, dir_len); + this->GetObjectFileNameWithoutTarget(source, dir_len, + hasSourceExtension); if(nameWithoutTargetDir) { *nameWithoutTargetDir = objectName; diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index c41d0d8..c6fcb99 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -238,7 +238,10 @@ public: LocalObjectEntry(cmTarget* t, const char* lang): Target(t), Language(lang) {} }; - class LocalObjectInfo: public std::vector {}; + struct LocalObjectInfo: public std::vector + { + bool HasSourceExtension; + }; std::map const& GetLocalObjectFiles() { return this->LocalObjectFiles;} @@ -299,11 +302,12 @@ protected: const std::vector& objects); void WriteObjectConvenienceRule(std::ostream& ruleFileStream, const char* comment, const char* output, - LocalObjectInfo const& targets); + LocalObjectInfo const& info); std::string GetObjectFileName(cmTarget& target, const cmSourceFile& source, - std::string* nameWithoutTargetDir = 0); + std::string* nameWithoutTargetDir = 0, + bool* hasSourceExtension = 0); void AppendRuleDepend(std::vector& depends, const char* ruleFileName); diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 0e9ccc5..6c3002e 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -310,10 +310,12 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source) } // Get the full path name of the object file. + bool hasSourceExtension; std::string objNoTargetDir; std::string obj = this->LocalGenerator->GetObjectFileName(*this->Target, source, - &objNoTargetDir); + &objNoTargetDir, + &hasSourceExtension); // Avoid generating duplicate rules. if(this->ObjectFiles.find(obj) == this->ObjectFiles.end()) @@ -377,10 +379,12 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source) { objNoTargetDir = cmSystemTools::GetFilenameName(objNoTargetDir); } - this->LocalGenerator->LocalObjectFiles[objNoTargetDir]. - push_back( - cmLocalUnixMakefileGenerator3::LocalObjectEntry(this->Target, lang) - ); + cmLocalUnixMakefileGenerator3::LocalObjectInfo& info = + this->LocalGenerator->LocalObjectFiles[objNoTargetDir]; + info.HasSourceExtension = hasSourceExtension; + info.push_back( + cmLocalUnixMakefileGenerator3::LocalObjectEntry(this->Target, lang) + ); } //---------------------------------------------------------------------------- -- cgit v0.12