Repository navigation
[core] circumvent call to rmkdepend #23492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 12 commits
7eb1f72
9495138
17ad775
72d74be
4d9a281
307c67c
5958676
c4e39f8
56e746c
e602185
9e680ac
7de514e
5b61a6c
4c887c3
a248727
5f6b8ad
29d1cf7
347d5df
78d64e2
3b8d5af
93cf0d6
f2a8fe0
e3e4e3d
28fd0e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -58,6 +58,7 @@ allows a simple partial implementation for new OS'es. | |
| #include <set> | ||
|
|
||
| #ifdef WIN32 | ||
| #include <algorithm> | ||
| #include <io.h> | ||
| #include "Windows4Root.h" | ||
| #endif | ||
|
|
@@ -2587,107 +2588,99 @@ static void R__AddPath(TString &target, const TString &path) { | |
| } | ||
| #endif | ||
|
|
||
| static void R__WriteDependencyFile(const TString & build_loc, const TString &depfilename, const TString &filename, const TString &library, const TString &libname, | ||
| const TString &extension, const char *version_var_prefix, const TString &includes, const TString &defines, const TString &incPath) | ||
| static bool R__GenerateCompilerDependencies(const TString &depfilename, const TString &filename, const TString &targetname, | ||
| const TString &includes, const TString &defines) | ||
| { | ||
| // Generate the dependency via standard output, not searching the | ||
| // standard include directories, | ||
| TString compiler = COMPILER; | ||
|
|
||
| bool needToUnlinkTempFile = false; | ||
| TString devnullfile = "/dev/null"; | ||
| TString cmd = compiler; | ||
| cmd += " " CXXOPT; | ||
| cmd += " " ROOT_CXX_STANDARD_OPTION; | ||
| #ifdef WIN32 | ||
| // Determine the null device based on the shell in use. | ||
| // COMSPEC unset or pointing to cmd.exe -> NUL | ||
| // COMSPEC pointing to powershell -> $null | ||
| // Anything else (e.g. bash/sh on Windows) -> `depfilename`.stderr.tmp | ||
| const char *comspec = gSystem->Getenv("COMSPEC"); | ||
| if (!comspec || !comspec[0]) { | ||
| devnullfile = "NUL"; | ||
| } else { | ||
| TString comspecStr(comspec); | ||
| comspecStr.ToLower(); | ||
| if (comspecStr.EndsWith("cmd.exe")) { | ||
| devnullfile = "NUL"; | ||
| } else if (comspecStr.Contains("powershell.exe")) { | ||
| devnullfile = "$null"; | ||
| } else { | ||
| needToUnlinkTempFile = true; | ||
| devnullfile = depfilename + ".stderr.tmp"; | ||
| gSystem->PrependPathName(build_loc, devnullfile); | ||
| } | ||
| } | ||
| cmd += " /nologo /E /showIncludes"; | ||
| cmd += " \"/I"; | ||
| #else | ||
| cmd += " -MM"; | ||
| cmd += " -MF \"" + depfilename + "\""; | ||
| cmd += " -MT \""; | ||
| R__AddPath(cmd, targetname); | ||
| cmd += "\" "; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The design of ACLiC here was to delegate this whole command line build (for the most part) to the build system and insert it in For example we have: So I would imagine we would add a new line in
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this PR is a bit complicated, now that the CI is green, I'd prefer doing this optimization in a subsequent one. On the other hand, only TSystem would be using this, so I do not see that it simplifies things. The ifdefs in the Cxx would be just moved to the CMake code, so similar if not larger number of lines and more abstraction. If there would be more places being used, then I would see that more clearly.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it sortof can wait for a further PR. Yes, the complexity is essentially the same. There is 2 major distinctions One is to have the same pattern for all the cases rather than 2 different ways. Additionally, going through the indirection of having one command line pattern allows the user to manipulate and customizing as they need. |
||
| cmd += " \"-I"; | ||
| #endif | ||
| TString bakdepfilename = depfilename + ".bak"; | ||
|
|
||
| struct Defer { | ||
| bool fNeedToUnlinkTempFile; | ||
| const TString &fDevNullFile, &fBakdepfilename; | ||
| ~Defer() | ||
| { | ||
| if (fNeedToUnlinkTempFile) { | ||
| // Remove the temporary stderr file if it was created. | ||
| gSystem->Unlink(fDevNullFile); | ||
| } | ||
| gSystem->Unlink(fBakdepfilename); | ||
| } | ||
| } deferGuard{needToUnlinkTempFile, devnullfile, bakdepfilename}; | ||
|
|
||
| TString builddep = "rmkdepend"; | ||
| gSystem->PrependPathName(TROOT::GetBinDir(), builddep); | ||
| builddep += " \"-f"; | ||
| builddep += depfilename; | ||
| builddep += "\" -o_" + extension + "." + gSystem->GetSoExt() + " "; | ||
| if (build_loc.BeginsWith(gSystem->WorkingDirectory())) { | ||
| Int_t len = strlen(gSystem->WorkingDirectory()); | ||
| if ( build_loc.Length() > (len+1) ) { | ||
| builddep += " \"-p"; | ||
| if (build_loc[len] == '/' || build_loc[len+1] != '\\' ) { | ||
| // Since the path is now ran through TSystem::ExpandPathName the single \ is also possible. | ||
| R__AddPath(builddep, build_loc.Data() + len + 1 ); | ||
| } else { | ||
| // Case of dir\\name | ||
| R__AddPath(builddep, build_loc.Data() + len + 2 ); | ||
| } | ||
| builddep += "/\" "; | ||
| } | ||
| } else { | ||
| builddep += " \"-p"; | ||
| R__AddPath(builddep, build_loc); | ||
| builddep += "/\" "; | ||
| } | ||
| builddep += " -Y -- "; | ||
| TString rootsysInclude = TROOT::GetIncludeDir(); | ||
| builddep += " \"-I"+rootsysInclude+"\" "; // cflags | ||
| builddep += includes; | ||
| builddep += defines; | ||
| builddep += " -- \""; | ||
| builddep += filename; | ||
| builddep += "\" "; | ||
| TString targetname; | ||
| if (library.BeginsWith(gSystem->WorkingDirectory())) { | ||
| Int_t len = strlen(gSystem->WorkingDirectory()); | ||
| if ( library.Length() > (len+1) ) { | ||
| if (library[len] == '/' || library[len+1] != '\\' ) { | ||
| targetname = library.Data() + len + 1; | ||
| } else { | ||
| targetname = library.Data() + len + 2; | ||
| R__AddPath(cmd, rootsysInclude); | ||
| cmd += "\" "; | ||
|
|
||
| cmd += includes; | ||
| cmd += defines; | ||
|
|
||
| #ifdef WIN32 | ||
| cmd += " /TP"; // avoid warning when header is .h but is C++ code | ||
| #else | ||
| cmd += " -x c++-header"; // avoid warning when header is .h but is C++ code | ||
| #endif | ||
| cmd += " \""; | ||
| R__AddPath(cmd, filename); | ||
| cmd += "\""; | ||
|
|
||
| if (gDebug > 4) | ||
| ::Info("ACLiC", "%s", cmd.Data()); | ||
|
|
||
| #ifdef WIN32 | ||
| TString wrapperCmd = "cmd.exe /c \"" + cmd + "\""; | ||
| FILE *pipe = gSystem->OpenPipe(wrapperCmd, "r"); | ||
| if (!pipe) { | ||
| ::Warning("ACLiC", "Failed to open pipe dependencies for %s", filename.Data()); | ||
| return false; | ||
| } | ||
| std::ofstream depFile(depfilename, std::ios::out | std::ios::trunc); | ||
|
ferdymercury marked this conversation as resolved.
Resolved
|
||
| if (depFile) { | ||
| depFile << targetname << ": \\\n"; | ||
| char buffer[4096]; | ||
| const char *prefix = "Note: including file:"; | ||
| size_t prefixLen = strlen(prefix); | ||
|
|
||
| while (fgets(buffer, sizeof(buffer), pipe) != nullptr) { | ||
| std::string line(buffer); | ||
| // Find and strip "Note: including file:" | ||
|
ferdymercury marked this conversation as resolved.
Resolved
|
||
| size_t pos = line.find(prefix); | ||
| if (pos != std::string::npos) { | ||
| std::string path = line.substr(pos + prefixLen); | ||
| // Trim leading/trailing spaces or newlines | ||
| path.erase(0, path.find_first_not_of(" \t")); | ||
| path.erase(path.find_last_not_of(" \r\n\t") + 1); | ||
| // Convert Windows backslashes to forward slashes for Makefile compatibility | ||
| std::replace(path.begin(), path.end(), '\\', '/'); | ||
| if (!path.empty()) { | ||
| depFile << " \"" << path << "\" \\\n"; | ||
| } | ||
| } | ||
| } else { | ||
| targetname = library; | ||
| } | ||
| } else { | ||
| targetname = library; | ||
| depFile << "\n"; // End the dependency rule cleanly | ||
| depFile.close(); | ||
| } | ||
| int retVal = gSystem->ClosePipe(pipe); | ||
| if (retVal != 0) { | ||
|
ferdymercury marked this conversation as resolved.
Resolved
|
||
| ::Warning("ACLiC", "Failed to close pipe dependencies for %s", filename.Data()); | ||
| return false; | ||
| } | ||
| #else | ||
| if (gSystem->Exec(cmd)) { | ||
| ::Warning("ACLiC", "Failed to generate dependencies for %s", filename.Data()); | ||
| return false; | ||
| } | ||
| builddep += " \""; | ||
| builddep += "-t"; | ||
| R__AddPath(builddep, targetname); | ||
| builddep += "\" > "; | ||
| builddep += devnullfile; | ||
| builddep += " 2>&1 "; | ||
| #endif | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| static TString R__GetRootDictionaryDependencies(const TString &targetname, const TString &incPath) | ||
| { | ||
| TString adddictdep; | ||
| R__AddPath(adddictdep,targetname); | ||
| adddictdep += ": "; | ||
| TString rootsysInclude = TROOT::GetIncludeDir(); | ||
|
|
||
| #if defined(R__HAS_CLING_DICTVERSION) | ||
| { | ||
| char *clingdictversion = gSystem->Which(incPath,"clingdictversion.h"); | ||
|
|
@@ -2734,27 +2727,33 @@ static void R__WriteDependencyFile(const TString & build_loc, const TString &dep | |
| delete [] rootCling; | ||
| } | ||
| } | ||
| return adddictdep; | ||
| } | ||
|
|
||
| { | ||
| std::ofstream depFile(depfilename, std::ios::out | std::ios::trunc); | ||
| if (!depFile) { | ||
| ::Warning("ACLiC", "Failed to open dependency file %s for %s", depfilename.Data(), library.Data()); | ||
| return; | ||
| static void R__WriteDependencyFile(const TString & build_loc, const TString &depfilename, const TString &filename, const TString &library, const TString &libname, | ||
| const TString &extension, const char *version_var_prefix, const TString &includes, const TString &defines, const TString &incPath) | ||
| { | ||
| (void)build_loc; | ||
| (void)extension; | ||
| TString targetname; | ||
| if (library.BeginsWith(gSystem->WorkingDirectory())) { | ||
| Int_t len = strlen(gSystem->WorkingDirectory()); | ||
| if ( library.Length() > (len+1) ) { | ||
| if (library[len] == '/' || library[len+1] != '\\' ) { | ||
| targetname = library.Data() + len + 1; | ||
| } else { | ||
| targetname = library.Data() + len + 2; | ||
| } | ||
| } else { | ||
| targetname = library; | ||
| } | ||
| #ifdef WIN32 | ||
| depFile << "#\n"; | ||
| #endif | ||
| } | ||
|
|
||
| if (gDebug > 4) { | ||
| ::Info("ACLiC", "%s", builddep.Data()); | ||
| ::Info("ACLiC", "%s", adddictdep.Data()); | ||
| } else { | ||
| targetname = library; | ||
| } | ||
| bool depbuiltOk = !gSystem->Exec(builddep); | ||
| if (!depbuiltOk) { | ||
| ::Warning("ACLiC", "Failed to run rmkdepend for %s", library.Data()); | ||
| if (!R__GenerateCompilerDependencies(depfilename, filename, targetname, includes, defines)) | ||
| return; | ||
| } | ||
|
|
||
| TString adddictdep = R__GetRootDictionaryDependencies(targetname, incPath); | ||
|
|
||
| std::ofstream depFile(depfilename, std::ios::out | std::ios::app); | ||
| if (!depFile) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.