Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmake/modules/RootNewMacros.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ macro(REFLEX_GENERATE_DICTIONARY dictionary)
endmacro()

#---------------------------------------------------------------------------------------------------
#---ROOT_GENERATE_DICTIONARY( result_var )
#---ROOT_GET_LIBRARY_OUTPUT_DIR( result_var )
# Returns the path to the .so file or .dll file. In the latter case Windows defines the dll files as
# executables and puts them in the $ROOTSYS/bin folder.
function(ROOT_GET_LIBRARY_OUTPUT_DIR result)
Expand Down
45 changes: 35 additions & 10 deletions core/base/src/TSystem.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Author: Fons Rademakers 15/09/95

/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
* Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
Expand All @@ -29,6 +29,7 @@ allows a simple partial implementation for new OS'es.
#include <algorithm>
#include <sys/stat.h>

#include <ROOT/FoundationUtils.hxx>
#include "Riostream.h"
#include "TSystem.h"
#include "TApplication.h"
Expand Down Expand Up @@ -3523,21 +3524,45 @@ int TSystem::CompileMacro(const char *filename, Option_t *opt,
rcling += "\" -f \"";
rcling.Append(dict).Append("\" ");

if (useCxxModules)
rcling += " -cxxmodule ";

if (produceRootmap) {
if (produceRootmap && !useCxxModules) {
rcling += " -rml " + libname + " -rmf \"" + libmapfilename + "\" ";
}
rcling.Append(GetIncludePath()).Append(" -D__ACLIC__ ");
if (produceRootmap) {
rcling.Append("-DR__ACLIC_ROOTMAP ");
}
rcling.Append(GetIncludePath()).Append(" -D__ACLIC__ ");
if (gEnv) {
TString fromConfig = gEnv->GetValue("ACLiC.IncludePaths","");
rcling.Append(fromConfig).Append(" \"");
rcling.Append(fromConfig);
}
rcling.Append(filename_fullpath).Append("\" \"").Append(linkdef).Append("\"");;

// Create a modulemap
// FIXME: Merge the modulemap generation from cmake and here in rootcling.
if (useCxxModules && produceRootmap) {
rcling += " -cxxmodule ";
// TString moduleMapFileName = file_dirname + "/" + libname + ".modulemap";
TString moduleName = libname + "_ACLiC_dict";
if (moduleName.BeginsWith("lib"))
moduleName = moduleName.Remove(0, 3);
TString moduleMapName = moduleName + ".modulemap";
TString moduleMapFullPath = build_loc + "/" + moduleMapName;
// A modulemap may exist from previous runs, overwrite it.
if (verboseLevel > 3 && !AccessPathName(moduleMapFullPath))
::Info("ACLiC", "File %s already exists!", moduleMapFullPath.Data());

std::string curDir = ROOT::FoundationUtils::GetCurrentDir();
std::string relative_path = ROOT::FoundationUtils::MakePathRelative(filename_fullpath.Data(), curDir);
std::ofstream moduleMapFile(moduleMapFullPath, std::ios::out);
moduleMapFile << "module \"" << moduleName << "\" {" << std::endl;
moduleMapFile << " header \"" << relative_path << "\"" << std::endl;
moduleMapFile << " export *" << std::endl;
moduleMapFile << " link \"" << libname_ext << "\"" << std::endl;
moduleMapFile << "}" << std::endl;
moduleMapFile.close();
gInterpreter->RegisterPrebuiltModulePath(build_loc.Data(), moduleMapName.Data());
rcling.Append(" \"-fmodule-map-file=" + moduleMapFullPath + "\" ");
}

rcling.Append(" \"").Append(filename_fullpath).Append("\" ");
rcling.Append("\"").Append(linkdef).Append("\"");

// ======= Run rootcling
if (withInfo) {
Expand Down
106 changes: 31 additions & 75 deletions core/dictgen/src/rootcling_impl.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const char *shortHelp =

#include "RConfigure.h"
#include <ROOT/RConfig.hxx>
#include <ROOT/FoundationUtils.hxx>

#include <iostream>
#include <iomanip>
Expand Down Expand Up @@ -186,42 +187,6 @@ static void EmitEnums(const std::vector<const clang::EnumDecl *> &enumvec)
}
}

////////////////////////////////////////////////////////////////////////////////

static void GetCurrentDirectory(std::string &output)
{
char fixedLength[1024];
char *currWorkDir = fixedLength;
size_t len = 1024;
char *result = currWorkDir;

do {
if (result == 0) {
len = 2 * len;
if (fixedLength != currWorkDir) {
delete [] currWorkDir;
}
currWorkDir = new char[len];
}
#ifdef WIN32
result = ::_getcwd(currWorkDir, len);
#else
result = getcwd(currWorkDir, len);
#endif
} while (result == 0 && errno == ERANGE);

output = currWorkDir;
output += '/';
#ifdef WIN32
// convert backslashes into forward slashes
std::replace(output.begin(), output.end(), '\\', '/');
#endif

if (fixedLength != currWorkDir) {
delete [] currWorkDir;
}
}

////////////////////////////////////////////////////////////////////////////////
/// Returns the executable path name, used e.g. by SetRootSys().

Expand Down Expand Up @@ -259,35 +224,6 @@ const char *GetExePath()
return exepath.c_str();
}



////////////////////////////////////////////////////////////////////////////////
/// Convert to path relative to $PWD
/// If that's not what the caller wants, she should pass -I to rootcling and a
/// different relative path to the header files.

static std::string GetRelocatableHeaderName(const std::string &header, const std::string &currentDirectory)
{
std::string result(header);

const char *currWorkDir = currentDirectory.c_str();
size_t lenCurrWorkDir = strlen(currWorkDir);
if (result.substr(0, lenCurrWorkDir) == currWorkDir) {
// Convert to path relative to $PWD.
// If that's not what the caller wants, she should pass -I to rootcling and a
// different relative path to the header files.
result.erase(0, lenCurrWorkDir);
}
if (gBuildingROOT) {
// For ROOT, convert module directories like core/base/inc/ to include/
int posInc = result.find("/inc/");
if (posInc != -1) {
result = /*std::string("include") +*/ result.substr(posInc + 5, -1);
}
}
return result;
}

////////////////////////////////////////////////////////////////////////////////

bool Namespace__HasMethod(const clang::NamespaceDecl *cl, const char *name,
Expand Down Expand Up @@ -3664,6 +3600,29 @@ class TRootClingCallbacks : public cling::InterpreterCallbacks {
}
}
}

// rootcling pre-includes things such as Rtypes.h. This means that ACLiC can
// call rootcling asking it to create a module for a file with no #includes
// but relying on things from Rtypes.h such as the ClassDef macro.
//
// When rootcling starts building a module, it becomes resilient to the
// outside environment and pre-included files have no effect. This hook
// informs rootcling when a new submodule is being built so that it can
// make Core.Rtypes.h visible.
virtual void EnteredSubmodule(clang::Module* M,
clang::SourceLocation ImportLoc,
bool ForPragma) {
assert(M);
using namespace clang;
if (llvm::StringRef(M->Name).endswith("ACLiC_dict")) {
Preprocessor& PP = m_Interpreter->getCI()->getPreprocessor();
HeaderSearch& HS = PP.getHeaderSearchInfo();
// FIXME: Reduce to Core.Rtypes.h.
Module* CoreModule = HS.lookupModule("Core", /*AllowSearch*/false);
assert(M && "Must have module Core");
PP.makeModuleVisible(CoreModule, ImportLoc);
}
}
};

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -3810,9 +3769,6 @@ int RootClingMain(int argc,
bool ignoreExistingDict = false;
bool requestAllSymbols = isDeep;

std::string currentDirectory;
GetCurrentDirectory(currentDirectory);

ic = 1;
if (!gDriverConfig->fBuildingROOTStage1) {
if (strcmp("-rootbuild", argv[ic]) == 0) {
Expand Down Expand Up @@ -3991,7 +3947,6 @@ int RootClingMain(int argc,
bool selSyntaxOnly = false;
bool noIncludePaths = false;
bool cxxmodule = false;
bool isAclic = false;

// Collect the diagnostic pragmas linked to the usage of -W
// Workaround for ROOT-5656
Expand Down Expand Up @@ -4137,8 +4092,6 @@ int RootClingMain(int argc,
}
ic++;
}
if (liblistPrefix.length())
isAclic = true;

// Check if we have a multi dict request but no target library
if (multiDict && sharedLibraryPathName.empty()) {
Expand Down Expand Up @@ -4372,6 +4325,8 @@ int RootClingMain(int argc,

AddPlatformDefines(clingArgs);

std::string currentDirectory = ROOT::FoundationUtils::GetCurrentDir();

std::string interpPragmaSource;
std::string includeForSource;
std::string interpreterDeclarations;
Expand Down Expand Up @@ -4418,7 +4373,9 @@ int RootClingMain(int argc,
if (fullheader[fullheader.length() - 1] == '+') {
fullheader.erase(fullheader.length() - 1);
}
std::string header(isSelectionFile ? fullheader : GetRelocatableHeaderName(fullheader, currentDirectory));
std::string header(
isSelectionFile ? fullheader
: ROOT::FoundationUtils::MakePathRelative(fullheader, currentDirectory, gBuildingROOT));

interpPragmaSource += std::string("#include \"") + header + "\"\n";
if (!isSelectionFile) {
Expand Down Expand Up @@ -4895,14 +4852,14 @@ int RootClingMain(int argc,
}

modGen.WriteRegistrationSource(dictStream, fwdDeclnArgsToKeepString, headersClassesMapString, fwdDeclsString,
extraIncludes, cxxmodule && !isAclic);
extraIncludes, cxxmodule);
// If we just want to inline the input header, we don't need
// to generate any files.
if (!inlineInputHeader) {
// Write the module/PCH depending on what mode we are on
if (modGen.IsPCH()) {
if (!GenerateAllDict(modGen, CI, currentDirectory)) return 1;
} else if (cxxmodule && !isAclic) {
} else if (cxxmodule) {
if (!CheckModuleValid(modGen, resourceDir, interp, linkdefFilename, moduleName.str()))
return 1;
}
Expand Down Expand Up @@ -5017,7 +4974,6 @@ int RootClingMain(int argc,
// Manually call end of translation unit because we never call the
// appropriate deconstructors in the interpreter. This writes out the C++
// module file that we currently generate.
if (!isAclic)
{
cling::Interpreter::PushTransactionRAII RAII(&interp);
CI->getSema().getASTConsumer().HandleTranslationUnit(CI->getSema().getASTContext());
Expand Down
1 change: 1 addition & 0 deletions core/foundation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ set(Foundation_dict_headers
)

set(sources
src/FoundationUtils.cxx
src/RConversionRuleParser.cxx
src/TClassEdit.cxx
)
Expand Down
45 changes: 45 additions & 0 deletions core/foundation/res/ROOT/FoundationUtils.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/// \file FoundationUtils.hxx
///
/// \brief The file contains utilities which are foundational and could be used
/// across the core component of ROOT.
///
///
/// \author Vassil Vassilev <[email protected]>
///
/// \date June, 2019
///
/*************************************************************************
* Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/

#ifndef ROOT_CORE_FOUNDATION_FOUNDATIONUTILS_HXX
#define ROOT_CORE_FOUNDATION_FOUNDATIONUTILS_HXX

#include <string>

namespace ROOT {
namespace FoundationUtils {

///\returns the $PWD.
std::string GetCurrentDir();

///\returns the relative path of \c path with respect to \c base.
/// For instance, for path being "/a/b/c/d" and base "/a/b", returns "c/d".
///
///\param path - the input path
///
///\param base - the base path to be removed from \c path.
///
///\param isBuildingROOT - if true, it converts module directories such as
/// core/base/inc/ to include/
std::string MakePathRelative(const std::string &path, const std::string &base,
bool isBuildingROOT = false);

} // namespace FoundationUtils
} // namespace ROOT

#endif // ROOT_CORE_FOUNDATION_FOUNDATIONUTILS_HXX
Loading