andrewjcg created this revision. Herald added a subscriber: cfe-commits. Currently, modules built using module map files embed the path to the directory that houses their inputs (e.g. headers and module map file) into the output module file. This path is embedded as an absolute path and the various input files are either relativized to this path (if they are underneath it) or also embedded as an absolute path.
This adds a flag which disables use of this absolute module directory path and instead writes out paths into the module unmodified (e.g. if they were specified on the command line as relative paths to the CWD, then they remain relative to the CWD). This allows building modules without any absolute paths, allowing them to be built and shared between different working directories. Repository: rC Clang https://reviews.llvm.org/D51568 Files: include/clang/Driver/CC1Options.td include/clang/Lex/HeaderSearchOptions.h lib/Frontend/CompilerInvocation.cpp lib/Serialization/ASTWriter.cpp test/Modules/relocatable-modules.modulemap
Index: test/Modules/relocatable-modules.modulemap =================================================================== --- /dev/null +++ test/Modules/relocatable-modules.modulemap @@ -0,0 +1,29 @@ +// Build two otherwise identical modules in two different directories and +// verify that using `-fdisable-module-directory` makes them identical. +// +// RUN: rm -rf %t +// +// RUN: mkdir -p %t/p1 +// RUN: cd %t/p1 +// RUN: mkdir -p main other +// RUN: grep "<AM>" %s > main/a.modulemap +// RUN: grep "<AH>" %s > main/a.h +// RUN: grep "<BH>" %s > other/b.h +// RUN: %clang_cc1 -x c++ -fmodules -emit-module -fdisable-module-directory \ +// RUN: -fmodule-name="a" -Imain -I. -o - main/a.modulemap > a.pcm +// +// RUN: mkdir -p %t/p2 +// RUN: cd %t/p2 +// RUN: mkdir -p main other +// RUN: grep "<AM>" %s > main/a.modulemap +// RUN: grep "<AH>" %s > main/a.h +// RUN: grep "<BH>" %s > other/b.h +// RUN: %clang_cc1 -x c++ -fmodules -emit-module -fdisable-module-directory \ +// RUN: -fmodule-name="a" -Imain -I. -o - main/a.modulemap > a.pcm +// +// RUN: diff %t/p1/a.pcm %t/p2/a.pcm + +module "a" { // <AM> +} // <AM> + +#include "b.h" // <AH> Index: lib/Serialization/ASTWriter.cpp =================================================================== --- lib/Serialization/ASTWriter.cpp +++ lib/Serialization/ASTWriter.cpp @@ -1339,9 +1339,14 @@ /// /// \return \c true if the path was changed. static bool cleanPathForOutput(FileManager &FileMgr, - SmallVectorImpl<char> &Path) { - bool Changed = FileMgr.makeAbsolutePath(Path); - return Changed | llvm::sys::path::remove_dots(Path); + SmallVectorImpl<char> &Path, + bool MakeAbsolute = true) { + bool Changed = false; + if (MakeAbsolute) { + Changed |= FileMgr.makeAbsolutePath(Path); + } + Changed |= llvm::sys::path::remove_dots(Path); + return Changed; } /// Adjusts the given filename to only write out the portion of the @@ -1503,7 +1508,11 @@ Stream.EmitRecordWithBlob(AbbrevCode, Record, WritingModule->Name); } - if (WritingModule && WritingModule->Directory) { + if (WritingModule && + WritingModule->Directory && + !PP.getHeaderSearchInfo() + .getHeaderSearchOpts() + .DisableModuleDirectory) { SmallString<128> BaseDir(WritingModule->Directory->getName()); cleanPathForOutput(Context.getSourceManager().getFileManager(), BaseDir); @@ -2952,12 +2961,20 @@ // Emit the umbrella header, if there is one. if (auto UmbrellaHeader = Mod->getUmbrellaHeader()) { RecordData::value_type Record[] = {SUBMODULE_UMBRELLA_HEADER}; - Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record, - UmbrellaHeader.NameAsWritten); + SmallString<128> Buffer; + llvm::sys::path::append(Buffer, + Mod->Directory->getName(), + UmbrellaHeader.NameAsWritten); + llvm::sys::path::remove_dots(Buffer); + Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record, Buffer); } else if (auto UmbrellaDir = Mod->getUmbrellaDir()) { RecordData::value_type Record[] = {SUBMODULE_UMBRELLA_DIR}; - Stream.EmitRecordWithBlob(UmbrellaDirAbbrev, Record, - UmbrellaDir.NameAsWritten); + SmallString<128> Buffer; + llvm::sys::path::append(Buffer, + Mod->Directory->getName(), + UmbrellaDir.NameAsWritten); + llvm::sys::path::remove_dots(Buffer); + Stream.EmitRecordWithBlob(UmbrellaDirAbbrev, Record, Buffer); } // Emit the headers. @@ -4515,7 +4532,11 @@ assert(Context && "should have context when outputting path"); bool Changed = - cleanPathForOutput(Context->getSourceManager().getFileManager(), Path); + cleanPathForOutput(Context->getSourceManager().getFileManager(), + Path, + !PP->getHeaderSearchInfo() + .getHeaderSearchOpts() + .DisableModuleDirectory); // Remove a prefix to make the path relative, if relevant. const char *PathBegin = Path.data(); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1746,6 +1746,7 @@ Opts.AddPrebuiltModulePath(A->getValue()); Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash); Opts.ModulesHashContent = Args.hasArg(OPT_fmodules_hash_content); + Opts.DisableModuleDirectory = Args.hasArg(OPT_fdisable_module_directory); Opts.ModulesValidateDiagnosticOptions = !Args.hasArg(OPT_fmodules_disable_diagnostic_validation); Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps); Index: include/clang/Lex/HeaderSearchOptions.h =================================================================== --- include/clang/Lex/HeaderSearchOptions.h +++ include/clang/Lex/HeaderSearchOptions.h @@ -203,14 +203,19 @@ unsigned ModulesHashContent : 1; + /// Do not relativize paths to the module directory or absolutify non-module- + /// directory-relative paths. + unsigned DisableModuleDirectory : 1; + HeaderSearchOptions(StringRef _Sysroot = "/") : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false), ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false), UseBuiltinIncludes(true), UseStandardSystemIncludes(true), UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false), ModulesValidateOncePerBuildSession(false), ModulesValidateSystemHeaders(false), UseDebugInfo(false), - ModulesValidateDiagnosticOptions(true), ModulesHashContent(false) {} + ModulesValidateDiagnosticOptions(true), ModulesHashContent(false), + DisableModuleDirectory(true) {} /// AddPath - Add the \p Path path to the specified \p Group list. void AddPath(StringRef Path, frontend::IncludeDirGroup Group, Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -751,6 +751,9 @@ HelpText<"Disable the module hash">; def fmodules_hash_content : Flag<["-"], "fmodules-hash-content">, HelpText<"Enable hashing the content of a module file">; +def fdisable_module_directory : Flag<["-"], "fdisable-module-directory">, + HelpText<"Do not relativize paths to the module home directory or absolutify " + "paths that are not relative to the module home directory.">; def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"<directory>">, HelpText<"Add directory to the C SYSTEM include search path">; def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits