diff --git a/README/README.CXXMODULES.md b/README/README.CXXMODULES.md index 3badc48f7d22d..4ecab1f167dd0 100644 --- a/README/README.CXXMODULES.md +++ b/README/README.CXXMODULES.md @@ -306,7 +306,7 @@ different. There are several differences which can be noticed: specific location. This way we 'mount' `/usr/include/module.modulemap` non-invasively. The reasons why we need to extend the C++ modules support beyond ROOT is described bellow. - * rootcling -cxxmodule creates a single artifact *Name.pcm* after the library + * rootcling --cxxmodule creates a single artifact *Name.pcm* after the library name. At a final stage, ROOT might be able to integrate the Name.pcm with the shared library itself. * Improved correctness in number of cases -- in a few cases ROOT is more @@ -347,7 +347,7 @@ different. There are several differences which can be noticed: This command concatenates `header.h` twice before compiling it to make sure it has proper include protectors. * Enable it in `rootcling` -- rootcling can produce a C++ Modules-aware - dictionary when it is invoked with `-cxxmodule` flag. + dictionary when it is invoked with `--cxxmodule` flag. * Modularization of external dependencies -- if a header file is not explicitly nominated as part of a module and it is transitively included in two modules, both modules contain that header file content. In other words, the header is diff --git a/bindings/pyroot/cppyy/cppyy/doc/source/utilities.rst b/bindings/pyroot/cppyy/cppyy/doc/source/utilities.rst index 77135000b3519..73bfeeb88e231 100644 --- a/bindings/pyroot/cppyy/cppyy/doc/source/utilities.rst +++ b/bindings/pyroot/cppyy/cppyy/doc/source/utilities.rst @@ -243,7 +243,7 @@ With ``genreflex``, the mapping file can be automatically created with ``--rootmap-lib=MyClassDict``, where "MyClassDict" is the name of the shared library (without the extension) build from the dictionary file. With ``rootcling``, create the same mapping file with -``-rmf MyClassDict.rootmap -rml MyClassDict``. +``--rmf MyClassDict.rootmap --rml MyClassDict``. It is necessary to provide the final library name explicitly, since it is only in the separate linking step where these names are fixed and those names may not match the default choice. diff --git a/bindings/pyroot/cppyy/cppyy/test/make_dict_win32.py b/bindings/pyroot/cppyy/cppyy/test/make_dict_win32.py index 6837f6b068c9c..47a942cee678e 100755 --- a/bindings/pyroot/cppyy/cppyy/test/make_dict_win32.py +++ b/bindings/pyroot/cppyy/cppyy/test/make_dict_win32.py @@ -63,7 +63,7 @@ def get_python_lib_dir(): linkdef.write("#pragma link C++ defined_in %s.h;\n" % fn) linkdef.write("\n#endif") -DICTIONARY_CMD = "python -m cppyy_backend._rootcling -f {fn}_rflx.cxx -rmf {fn}Dict.rootmap -rml {fn}Dict.dll {fn}.h {fn}Linkdef.h".format(fn=fn) +DICTIONARY_CMD = "python -m cppyy_backend._rootcling -f {fn}_rflx.cxx --rmf {fn}Dict.rootmap --rml {fn}Dict.dll {fn}.h {fn}Linkdef.h".format(fn=fn) if os.system(DICTIONARY_CMD): sys.exit(1) diff --git a/cmake/modules/RootMacros.cmake b/cmake/modules/RootMacros.cmake index 3ce1d5d5d1162..726c003ff0912 100644 --- a/cmake/modules/RootMacros.cmake +++ b/cmake/modules/RootMacros.cmake @@ -576,7 +576,7 @@ function(ROOT_GENERATE_DICTIONARY dictionary) set(pcm_name ${library_output_dir}/${libprefix}${library_output_name}_rdict.pcm) if(ARG_MODULE) if(ARG_MULTIDICT) - set(newargs ${newargs} -multiDict) + set(newargs ${newargs} --multiDict) set(pcm_name ${library_output_dir}/${libprefix}${library_output_name}_${dictionary}_rdict.pcm) set(rootmap_name ${library_output_dir}/${libprefix}${library_output_name}32.rootmap) else() @@ -617,7 +617,7 @@ function(ROOT_GENERATE_DICTIONARY dictionary) set(rootmap_name) set(rootmapargs) else() - set(rootmapargs -rml ${library_name} -rmf ${rootmap_name}) + set(rootmapargs --rml ${library_name} --rmf ${rootmap_name}) endif() #---Get the library and module dependencies----------------- @@ -643,7 +643,7 @@ function(ROOT_GENERATE_DICTIONARY dictionary) endif() if(cpp_module_file) - set(newargs -cxxmodule ${newargs}) + set(newargs --cxxmodule ${newargs}) endif() #---what rootcling command to use-------------------------- @@ -658,12 +658,12 @@ function(ROOT_GENERATE_DICTIONARY dictionary) else() if(CMAKE_PROJECT_NAME STREQUAL ROOT) if(MSVC AND CMAKE_ROOTTEST_DICT) - set(command ${CMAKE_COMMAND} -E env "ROOTIGNOREPREFIX=1" ${CMAKE_BINARY_DIR}/bin/rootcling.exe -rootbuild) + set(command ${CMAKE_COMMAND} -E env "ROOTIGNOREPREFIX=1" ${CMAKE_BINARY_DIR}/bin/rootcling.exe --rootbuild) else() if(APPLE) - set(command ${CMAKE_COMMAND} -E env "ROOTIGNOREPREFIX=1" SDKROOT=${CMAKE_OSX_SYSROOT} $ -rootbuild) + set(command ${CMAKE_COMMAND} -E env "ROOTIGNOREPREFIX=1" SDKROOT=${CMAKE_OSX_SYSROOT} $ --rootbuild) else() - set(command ${CMAKE_COMMAND} -E env "ROOTIGNOREPREFIX=1" $ -rootbuild) + set(command ${CMAKE_COMMAND} -E env "ROOTIGNOREPREFIX=1" $ --rootbuild) endif() # Modules need RConfigure.h copied into include/. set(ROOTCLINGDEP rootcling rconfigure) @@ -686,7 +686,7 @@ function(ROOT_GENERATE_DICTIONARY dictionary) #---build the path exclusion switches---------------------- set(excludepathsargs "") foreach(excludepath ${excludepaths}) - set(excludepathsargs ${excludepathsargs} -excludePath ${excludepath}) + set(excludepathsargs ${excludepathsargs} --excludePath ${excludepath}) endforeach() #---build the implicit dependencies arguments @@ -724,7 +724,7 @@ function(ROOT_GENERATE_DICTIONARY dictionary) set(compIncPaths) foreach(implinc IN LISTS CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES) - list(APPEND compIncPaths "-compilerI${implinc}") + list(APPEND compIncPaths "--compilerI${implinc}") endforeach() if(cpp_module_file AND TARGET ${ARG_MODULE}) diff --git a/config/Makefile.in b/config/Makefile.in index 25d490d93fb60..4729145f4967e 100644 --- a/config/Makefile.in +++ b/config/Makefile.in @@ -42,7 +42,7 @@ rmfName = $(dir $1)$(subst .$(SOEXT),.rootmap,$(notdir $1)) # generate the rootmap file # $(call rootmapModule, TREELIB) # the argument is the upper case name of the library (see the Module.mk) -rootmapModule = -rml $(notdir $1) -rmf $(call rmfName, $1) +rootmapModule = --rml $(notdir $1) --rmf $(call rmfName, $1) # This macro returns the argument to be passed to rootcling to # properly setup the pcm diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index e2b82baf5d2ab..cc23f7d460b77 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -124,12 +124,12 @@ target_compile_definitions(Core PRIVATE ) if (runtime_cxxmodules) - list(APPEND core_implicit_modules "-mSystemByproducts") + list(APPEND core_implicit_modules "--mSystemByproducts") # Force generation of _Builtin_intrinsics from Core. - list(APPEND core_implicit_modules "-m" "_Builtin_intrinsics" "-mByproduct" "_Builtin_intrinsics") - list(APPEND core_implicit_modules "-mByproduct" "ROOT_Foundation_Stage1_NoRTTI") - list(APPEND core_implicit_modules "-mByproduct" "ROOT_Foundation_C") - list(APPEND core_implicit_modules "-mByproduct" "ROOT_Rtypes") + list(APPEND core_implicit_modules "-m" "_Builtin_intrinsics" "--mByproduct" "_Builtin_intrinsics") + list(APPEND core_implicit_modules "--mByproduct" "ROOT_Foundation_Stage1_NoRTTI") + list(APPEND core_implicit_modules "--mByproduct" "ROOT_Foundation_C") + list(APPEND core_implicit_modules "--mByproduct" "ROOT_Rtypes") endif(runtime_cxxmodules) get_target_property(CORE_DICT_HEADERS Core DICT_HEADERS) diff --git a/core/base/src/TSystem.cxx b/core/base/src/TSystem.cxx index 9eef2c91eaec3..3d4f36a318f3e 100644 --- a/core/base/src/TSystem.cxx +++ b/core/base/src/TSystem.cxx @@ -3582,7 +3582,7 @@ int TSystem::CompileMacro(const char *filename, Option_t *opt, rcling.Append(dict).Append("\" "); if (produceRootmap && !useCxxModules) { - rcling += " -rml " + libname + " -rmf \"" + libmapfilename + "\" "; + rcling += " --rml " + libname + " --rmf \"" + libmapfilename + "\" "; rcling.Append("-DR__ACLIC_ROOTMAP "); } rcling.Append(GetIncludePath()).Append(" -D__ACLIC__ "); @@ -3600,7 +3600,7 @@ int TSystem::CompileMacro(const char *filename, Option_t *opt, // Create a modulemap // FIXME: Merge the modulemap generation from cmake and here in rootcling. if (useCxxModules && produceRootmap) { - rcling += " -cxxmodule "; + rcling += " --cxxmodule "; // TString moduleMapFileName = file_dirname + "/" + libname + ".modulemap"; TString moduleName = libname + "_ACLiC_dict"; if (moduleName.BeginsWith("lib")) @@ -3621,7 +3621,7 @@ int TSystem::CompileMacro(const char *filename, Option_t *opt, moduleMapFile << "}" << std::endl; moduleMapFile.close(); gInterpreter->RegisterPrebuiltModulePath(build_loc.Data(), moduleMapName.Data()); - rcling.Append(" \"-moduleMapFile=" + moduleMapFullPath + "\" "); + rcling.Append(" \"--moduleMapFile=" + moduleMapFullPath + "\" "); } rcling.Append(" \"").Append(filename_fullpath).Append("\" "); diff --git a/core/dictgen/CMakeLists.txt b/core/dictgen/CMakeLists.txt index 3df26f190b2bd..97150a662b8ec 100644 --- a/core/dictgen/CMakeLists.txt +++ b/core/dictgen/CMakeLists.txt @@ -50,6 +50,7 @@ target_include_directories(Dictgen PRIVATE ${CMAKE_SOURCE_DIR}/core/clib/inc ${CMAKE_SOURCE_DIR}/core/meta/inc ${CMAKE_SOURCE_DIR}/core/foundation/inc + ${CMAKE_SOURCE_DIR}/core/utils/inc ${CMAKE_BINARY_DIR}/ginclude ${CLING_INCLUDE_DIRS} ) diff --git a/core/dictgen/src/rootcling-argparse.py b/core/dictgen/src/rootcling-argparse.py index e856bed6b8159..bd57692f12919 100644 --- a/core/dictgen/src/rootcling-argparse.py +++ b/core/dictgen/src/rootcling-argparse.py @@ -99,11 +99,11 @@ def get_argparse(): will not include any of the declarations already included in the pcm files loaded via -m. There can be more than one -m """) - parser.add_argument('-rmf', help="""Rootmap file name + parser.add_argument('--rmf', help="""Rootmap file name Name of the rootmap file. In order to be picked up by ROOT it must have .rootmap extension """) - parser.add_argument('-rml', help="""Rootmap library name + parser.add_argument('--rml', help="""Rootmap library name Specify the name of the library which contains the autoload keys. This switch can be specified multiple times to autoload several libraries in presence of a particular key @@ -124,17 +124,17 @@ def get_argparse(): 3) If this is specified in conjunction with --multiDict, the output is libTARGETLIBRARY_DICTIONARY_rdict.pcm """) - parser.add_argument('-multiDict', help="""Enable support for multiple pcms in one library + parser.add_argument('--multiDict', help="""Enable support for multiple pcms in one library Needs the -s flag. See its documentation. """) - parser.add_argument('-inlineInputHeader', help="""Add the argument header to the code of the dictionary + parser.add_argument('--inlineInputHeader', help="""Add the argument header to the code of the dictionary This allows the header to be inlined within the dictionary """) - parser.add_argument('-interpreteronly', help='No IO information in the dictionary\n') + parser.add_argument('--interpreteronly', help='No IO information in the dictionary\n') parser.add_argument('-noIncludePaths', help="""Do not store the headers' directories in the dictionary Instead, rely on the environment variable $ROOT_INCLUDE_PATH at runtime """) - parser.add_argument('-excludePath', help="""Specify a path to be excluded from the include paths + parser.add_argument('--excludePath', help="""Specify a path to be excluded from the include paths specified for building this dictionary """) parser.add_argument('--lib-list-prefix', help="""Specify libraries needed by the header files parsed diff --git a/core/dictgen/src/rootcling_impl.cxx b/core/dictgen/src/rootcling_impl.cxx index 4d2b03714a358..de3778bb93144 100644 --- a/core/dictgen/src/rootcling_impl.cxx +++ b/core/dictgen/src/rootcling_impl.cxx @@ -88,7 +88,6 @@ #include "llvm/ADT/StringRef.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/Path.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" @@ -106,6 +105,7 @@ #include "strlcpy.h" #include "OptionParser.h" +#include "optparse.hxx" #ifdef WIN32 const std::string gLibraryExtension(".dll"); @@ -145,10 +145,6 @@ namespace genreflex { //////////////////////////////////////////////////////////////////////////////// -static llvm::cl::OptionCategory gRootclingOptions("rootcling common options"); - -//////////////////////////////////////////////////////////////////////////////// - void EmitStreamerInfo(const char *normName) { if (gDriverConfig->fAddStreamerInfoToROOTFile) @@ -3397,19 +3393,61 @@ class TRootClingCallbacks : public cling::InterpreterCallbacks { } }; -static llvm::cl::opt gOptSystemModuleByproducts("mSystemByproducts", llvm::cl::Hidden, - llvm::cl::desc("Allow implicit build of system modules."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::list -gOptModuleByproducts("mByproduct", llvm::cl::ZeroOrMore, - llvm::cl::Hidden, - llvm::cl::desc("The list of the expected implicit modules build as part of building the current module."), - llvm::cl::cat(gRootclingOptions)); -// Really llvm::cl::Required, will be changed in RootClingMain below. -static llvm::cl::opt -gOptDictionaryFileName(llvm::cl::Positional, - llvm::cl::desc(""), - llvm::cl::cat(gRootclingOptions)); +enum VerboseLevel { + v = ROOT::TMetaUtils::kError, + v0 = ROOT::TMetaUtils::kFatal, + v1 = v, + v2 = ROOT::TMetaUtils::kWarning, + v3 = ROOT::TMetaUtils::kNote, + v4 = ROOT::TMetaUtils::kInfo +}; + +// TODO: Maybe move these global variables to a RootClingConfig object +// (keeping this as globals minimizes the diff after llvm::cl removal) + +static VerboseLevel gOptVerboseLevel; + +static bool gOptForce; +static bool gOptRootBuild; +static bool gOptCint; +static bool gOptReflex; +static bool gOptGccXml; +static bool gOptGeneratePCH; +static bool gOptC; +static bool gOptP; +static bool gOptCxxModule; +static bool gOptUmbrellaInput; +static bool gOptMultiDict; +static bool gOptNoGlobalUsingStd; +static bool gOptInterpreterOnly; +static bool gOptSplit; +static bool gOptNoDictSelection; +static bool gOptInlineInput; +static bool gOptWriteEmptyRootPCM; +static bool gOptCheckSelectionSyntax; +static bool gOptFailOnWarnings; +static bool gOptNoIncludePaths; +static bool gOptSystemModuleByproducts; + +static std::string gOptLibListPrefix; +static std::string gOptRootMapFileName; +static std::string gOptSharedLibFileName; +static std::string gOptISysRoot; + +static std::vector gOptRootmapLibNames; +static std::vector gOptModuleMapFiles; +static std::vector gOptModuleDependencies; +static std::vector gOptExcludePaths; +static std::vector gOptSysIncludePaths; +static std::vector gOptIncludePaths; +static std::vector gOptCompDefaultIncludePaths; +static std::vector gOptPPDefines; +static std::vector gOptPPUndefines; +static std::vector gOptWDiags; +static std::vector gOptModuleByproducts; + +static std::string gOptDictionaryFileName; +static std::vector gOptDictionaryHeaderFiles; //////////////////////////////////////////////////////////////////////////////// /// Custom diag client for clang that verifies that each implicitly build module @@ -3473,14 +3511,14 @@ class CheckModuleBuildClient : public clang::DiagnosticConsumer { // an error because rootcling is not able to generate the corresponding // dictionary. // If we build a I/O requiring module implicitly we should display - // an error unless -mSystemByproducts or -mByproduct were specified. + // an error unless --mSystemByproducts or --mByproduct were specified. bool isByproductModule = false; if (module) { - // -mSystemByproducts allows implicit building of any system module. + // --mSystemByproducts allows implicit building of any system module. if (module->IsSystem && gOptSystemModuleByproducts) { isByproductModule = true; } - // -mByproduct lists concrete module names that are allowed. + // --mByproduct lists concrete module names that are allowed. if (std::find(gOptModuleByproducts.begin(), gOptModuleByproducts.end(), moduleName) != gOptModuleByproducts.end()) { isByproductModule = true; @@ -3493,7 +3531,7 @@ class CheckModuleBuildClient : public clang::DiagnosticConsumer { ROOT::TMetaUtils::Error(nullptr, "Building module '%s' implicitly. If '%s' requires a \n" "dictionary please specify build dependency: '%s' depends on '%s'.\n" - "Otherwise, specify '-mByproduct %s' to disable this diagnostic.\n", + "Otherwise, specify '--mByproduct %s' to disable this diagnostic.\n", moduleName.c_str(), moduleName.c_str(), gOptDictionaryFileName.c_str(), moduleName.c_str(), moduleName.c_str()); } @@ -3545,187 +3583,138 @@ static void MaybeSuppressWin32CrashDialogs() { #endif } -static llvm::cl::opt gOptForce("f", llvm::cl::desc("Overwrite s."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt gOptRootBuild("rootbuild", llvm::cl::desc("If we are building ROOT."), - llvm::cl::Hidden, - llvm::cl::cat(gRootclingOptions)); -enum VerboseLevel { - v = ROOT::TMetaUtils::kError, - v0 = ROOT::TMetaUtils::kFatal, - v1 = v, - v2 = ROOT::TMetaUtils::kWarning, - v3 = ROOT::TMetaUtils::kNote, - v4 = ROOT::TMetaUtils::kInfo -}; -static llvm::cl::opt -gOptVerboseLevel(llvm::cl::desc("Choose verbosity level:"), - llvm::cl::values(clEnumVal(v, "Show errors."), - clEnumVal(v0, "Show only fatal errors."), - clEnumVal(v1, "Show errors (the same as -v)."), - clEnumVal(v2, "Show warnings (default)."), - clEnumVal(v3, "Show notes."), - clEnumVal(v4, "Show information.")), - llvm::cl::init(v2), - llvm::cl::cat(gRootclingOptions)); - -static llvm::cl::opt -gOptCint("cint", llvm::cl::desc("Deprecated, legacy flag which is ignored."), - llvm::cl::Hidden, - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptReflex("reflex", llvm::cl::desc("Behave internally like genreflex."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptGccXml("gccxml", llvm::cl::desc("Deprecated, legacy flag which is ignored."), - llvm::cl::Hidden, - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptLibListPrefix("lib-list-prefix", - llvm::cl::desc("An ACLiC feature which exports the list of dependent libraries."), - llvm::cl::Hidden, - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptGeneratePCH("generate-pch", - llvm::cl::desc("Generates a pch file from a predefined set of headers. See makepch.py."), - llvm::cl::Hidden, - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptC("c", llvm::cl::desc("Deprecated, legacy flag which is ignored."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptP("p", llvm::cl::desc("Deprecated, legacy flag which is ignored."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::list -gOptRootmapLibNames("rml", llvm::cl::ZeroOrMore, - llvm::cl::desc("Generate rootmap file."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptRootMapFileName("rmf", - llvm::cl::desc("Generate a rootmap file with the specified name."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptCxxModule("cxxmodule", - llvm::cl::desc("Generate a C++ module."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::list -gOptModuleMapFiles("moduleMapFile", - llvm::cl::desc("Specify a C++ modulemap file."), - llvm::cl::cat(gRootclingOptions)); -// FIXME: Figure out how to combine the code of -umbrellaHeader and inlineInputHeader -static llvm::cl::opt -gOptUmbrellaInput("umbrellaHeader", - llvm::cl::desc("A single header including all headers instead of specifying them on the command line."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptMultiDict("multiDict", - llvm::cl::desc("If this library has multiple separate LinkDef files."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptNoGlobalUsingStd("noGlobalUsingStd", - llvm::cl::desc("Do not declare {using namespace std} in dictionary global scope."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptInterpreterOnly("interpreteronly", - llvm::cl::desc("Generate minimal dictionary for interactivity (without IO information)."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptSplit("split", - llvm::cl::desc("Split the dictionary into two parts: one containing the IO (ClassDef)\ -information and another the interactivity support."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptNoDictSelection("noDictSelection", - llvm::cl::Hidden, - llvm::cl::desc("Do not run the selection rules. Useful when in -onepcm mode."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptSharedLibFileName("s", - llvm::cl::desc("The path to the library of the built dictionary."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::list -gOptModuleDependencies("m", - llvm::cl::desc("The list of dependent modules of the dictionary."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::list -gOptExcludePaths("excludePath", llvm::cl::ZeroOrMore, - llvm::cl::desc("Do not store the in the dictionary."), - llvm::cl::cat(gRootclingOptions)); -// FIXME: This does not seem to work. We have one use of -inlineInputHeader in -// ROOT and it does not produce the expected result. -static llvm::cl::opt -gOptInlineInput("inlineInputHeader", - llvm::cl::desc("Does not generate #include
but expands the header content."), - llvm::cl::cat(gRootclingOptions)); -// FIXME: This is totally the wrong concept. We should not expose an interface -// to be able to tell which component is in the pch and which needs extra -// scaffolding for interactive use. Moreover, some of the ROOT components are -// partially in the pch and this option makes it impossible to express that. -// We should be able to get the list of headers in the pch early and scan -// through them. -static llvm::cl::opt -gOptWriteEmptyRootPCM("writeEmptyRootPCM", - llvm::cl::Hidden, - llvm::cl::desc("Does not include the header files as it assumes they exist in the pch."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptCheckSelectionSyntax("selSyntaxOnly", - llvm::cl::desc("Check the selection syntax only."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptFailOnWarnings("failOnWarnings", - llvm::cl::desc("Fail if there are warnings."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptNoIncludePaths("noIncludePaths", - llvm::cl::desc("Do not store include paths but rely on the env variable ROOT_INCLUDE_PATH."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::opt -gOptISysRoot("isysroot", llvm::cl::Prefix, llvm::cl::Hidden, - llvm::cl::desc("Specify an isysroot."), - llvm::cl::cat(gRootclingOptions), - llvm::cl::init("-")); -static llvm::cl::list -gOptIncludePaths("I", llvm::cl::Prefix, llvm::cl::ZeroOrMore, - llvm::cl::desc("Specify an include path."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::list -gOptCompDefaultIncludePaths("compilerI", llvm::cl::Prefix, llvm::cl::ZeroOrMore, - llvm::cl::desc("Specify a compiler default include path, to suppress unneeded `-isystem` arguments."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::list -gOptSysIncludePaths("isystem", llvm::cl::ZeroOrMore, - llvm::cl::desc("Specify a system include path."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::list -gOptPPDefines("D", llvm::cl::Prefix, llvm::cl::ZeroOrMore, - llvm::cl::desc("Specify defined macros."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::list -gOptPPUndefines("U", llvm::cl::Prefix, llvm::cl::ZeroOrMore, - llvm::cl::desc("Specify undefined macros."), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::list -gOptWDiags("W", llvm::cl::Prefix, llvm::cl::ZeroOrMore, - llvm::cl::desc("Specify compiler diagnostics options."), - llvm::cl::cat(gRootclingOptions)); -// Really OneOrMore, will be changed in RootClingMain below. -static llvm::cl::list -gOptDictionaryHeaderFiles(llvm::cl::Positional, llvm::cl::ZeroOrMore, - llvm::cl::desc(" "), - llvm::cl::cat(gRootclingOptions)); -static llvm::cl::list -gOptSink(llvm::cl::ZeroOrMore, llvm::cl::Sink, - llvm::cl::desc("Consumes all unrecognized options."), - llvm::cl::cat(gRootclingOptions)); - -static llvm::cl::SubCommand -gBareClingSubcommand("bare-cling", "Call directly cling and exit."); - -static llvm::cl::list -gOptBareClingSink(llvm::cl::OneOrMore, llvm::cl::Sink, - llvm::cl::desc("Consumes options and sends them to cling."), - llvm::cl::cat(gRootclingOptions), llvm::cl::sub(gBareClingSubcommand)); +// FIXME: Copied and adapted from previous help menu, would be nice if optparse supports generating this automatically. +static const char *const kShortHelp = "USAGE: rootcling [subcommand] [options] \n"; +static const char *const kLongHelp = R"( +SUBCOMMANDS: + + bare-cling - Call directly cling and exit. + +OPTIONS: + +Generic Options: + + --help - Display available options (--help-hidden for more) + +rootcling common options: + + -D - Specify defined macros. + -I - Specify an include path. + -U - Specify undefined macros. + -W - Specify compiler diagnostics options. + -c - Deprecated, legacy flag which is ignored. + --compilerI= - Specify a compiler default include path, to suppress unneeded `-isystem` arguments. + --cxxmodule - Generate a C++ module. + --excludePath= - Do not store the in the dictionary. + -f - Overwrite s. + --failOnWarnings - Fail if there are warnings. + --inlineInputHeader - Does not generate #include
but expands the header content. + --interpreteronly - Generate minimal dictionary for interactivity (without IO information). + -isystem= - Specify a system include path. + -m - The list of dependent modules of the dictionary. + --moduleMapFile= - Specify a C++ modulemap file. + --multiDict - If this library has multiple separate LinkDef files. + --noGlobalUsingStd - Do not declare {using namespace std} in dictionary global scope. + --noIncludePaths - Do not store include paths but rely on the env variable ROOT_INCLUDE_PATH. + -p - Deprecated, legacy flag which is ignored. + --reflex - Behave internally like genreflex. + --rmf= - Generate a rootmap file with the specified name. + --rml= - Generate rootmap file. + -s - The path to the library of the built dictionary. + --selSyntaxOnly - Check the selection syntax only. + --split - Split the dictionary into two parts: one containing the IO (ClassDef)information and another the interactivity support. + --umbrellaHeader - A single header including all headers instead of specifying them on the command line. + Choose verbosity level: + -v - Show errors. + -v0 - Show only fatal errors. + -v1 - Show errors (the same as -v). + -v2 - Show warnings (default). + -v3 - Show notes. + -v4 - Show information. +)"; + +void DefineRootclingOptions(ROOT::RCmdLineOpts &opts) +{ + using FT = ROOT::RCmdLineOpts::EFlagType; + using FO = ROOT::RCmdLineOpts::EFlagOpt; + + opts.AddFlag({"-h", "--help"}); + + // switches + opts.AddFlag({"-f"}, FT::kSwitch, "Overwrite s."); + opts.AddFlag({"--rootbuild"}, FT::kSwitch, "If we are building ROOT."); + opts.AddFlag({"--cint"}, FT::kSwitch, "Deprecated, legacy flag which is ignored."); + opts.AddFlag({"--reflex"}, FT::kSwitch, "Behave internally like genreflex."); + opts.AddFlag({"--gccxml"}, FT::kSwitch, "Deprecated, legacy flag which is ignored."); + opts.AddFlag({"--generate-pch"}, FT::kSwitch, + "Generates a pch file from a predefined set of headers. See makepch.py."); + opts.AddFlag({"-c"}, FT::kSwitch, "Deprecated, legacy flag which is ignored."); + opts.AddFlag({"-p"}, FT::kSwitch, "Deprecated, legacy flag which is ignored."); + opts.AddFlag({"--cxxmodule"}, FT::kSwitch, "Generate a C++ module."); + // FIXME: Figure out how to combine the code of --umbrellaHeader and inlineInputHeader + opts.AddFlag({"--umbrellaHeader"}, FT::kSwitch, + "A single header including all headers instead of specifying them on the command line."); + opts.AddFlag({"--multiDict"}, FT::kSwitch, "If this library has multiple separate LinkDef files."); + opts.AddFlag({"--noGlobalUsingStd"}, FT::kSwitch, + "Do not declare {using namespace std} in dictionary global scope."); + opts.AddFlag({"--interpreteronly"}, FT::kSwitch, + "Generate minimal dictionary for interactivity (without IO information)."); + opts.AddFlag({"--split"}, FT::kSwitch, + "Split the dictionary into two parts: one containing the IO (ClassDef) information and another the " + "interactivity support."); + opts.AddFlag({"--noDictSelection"}, FT::kSwitch, "Do not run the selection rules. Useful when in -onepcm mode."); + // FIXME: This does not seem to work. We have one use of --inlineInputHeader in + // ROOT and it does not produce the expected result. + opts.AddFlag({"--inlineInputHeader"}, FT::kSwitch, + "Does not generate #include
but expands the header content."); + // FIXME: This is totally the wrong concept. We should not expose an interface + // to be able to tell which component is in the pch and which needs extra + // scaffolding for interactive use. Moreover, some of the ROOT components are + // partially in the pch and this option makes it impossible to express that. + // We should be able to get the list of headers in the pch early and scan + // through them. + // FIXME: Change this to a long-flag, used in a lot of places. + opts.AddFlag({"-writeEmptyRootPCM"}, FT::kSwitch, + "Does not include the header files as it assumes they exist in the pch."); + opts.AddFlag({"--selSyntaxOnly"}, FT::kSwitch, "Check the selection syntax only."); + opts.AddFlag({"--failOnWarnings"}, FT::kSwitch, "Fail if there are warnings."); + opts.AddFlag({"--noIncludePaths"}, FT::kSwitch, + "Do not store include paths but rely on the env variable ROOT_INCLUDE_PATH."); + opts.AddFlag({"--mSystemByproducts"}, FT::kSwitch, "Allow implicit build of system modules."); + + // flags with arguments + opts.AddFlag({"--lib-list-prefix"}, FT::kWithArg, "An ACLiC feature which exports the list of dependent libraries."); + opts.AddFlag({"--rmf"}, FT::kWithArg, "Generate a rootmap file with the specified name."); + opts.AddFlag({"-s"}, FT::kWithArg, "The path to the library of the built dictionary."); + opts.AddFlag({"-isysroot"}, FT::kWithArg, "Specify an isysroot.", FO::kFlagPrefixArg); + + // flags with repeated args + opts.AddFlag({"--rml"}, FT::kWithArg, "Generate rootmap file.", FO::kFlagAllowMultiple); + opts.AddFlag({"--moduleMapFile"}, FT::kWithArg, "Specify a C++ modulemap file.", FO::kFlagAllowMultiple); + opts.AddFlag({"-m"}, FT::kWithArg, "The list of dependent modules of the dictionary.", FO::kFlagAllowMultiple); + opts.AddFlag({"--excludePath"}, FT::kWithArg, "Do not store the in the dictionary.", FO::kFlagAllowMultiple); + opts.AddFlag({"-isystem"}, FT::kWithArg, "Specify a system include path.", FO::kFlagAllowMultiple); + opts.AddFlag({"-I"}, FT::kWithArg, "Specify an include path.", FO::kFlagAllowMultiple | FO::kFlagPrefixArg); + opts.AddFlag({"--compilerI"}, FT::kWithArg, + "Specify a compiler default include path, to suppress unneeded `-isystem` arguments.", + FO::kFlagAllowMultiple | FO::kFlagPrefixArg); + opts.AddFlag({"-D"}, FT::kWithArg, "Specify defined macros.", FO::kFlagAllowMultiple | FO::kFlagPrefixArg); + opts.AddFlag({"-U"}, FT::kWithArg, "Specify undefined macros.", FO::kFlagAllowMultiple | FO::kFlagPrefixArg); + opts.AddFlag({"-W"}, FT::kWithArg, "Specify compiler diagnostics options.", + FO::kFlagAllowMultiple | FO::kFlagPrefixArg); + opts.AddFlag({"--mByproduct"}, FT::kWithArg, + "The list of the expected implicit modules build as part of building the current module.", + FO::kFlagAllowMultiple); + + // verbosity (switch instead of enum) + opts.AddFlag({"-v"}, FT::kSwitch, "Show errors."); + opts.AddFlag({"-v0"}, FT::kSwitch, "Show only fatal errors."); + opts.AddFlag({"-v1"}, FT::kSwitch, "Show errors (same as -v)."); + opts.AddFlag({"-v2"}, FT::kSwitch, "Show warnings (default)."); + opts.AddFlag({"-v3"}, FT::kSwitch, "Show notes."); + opts.AddFlag({"-v4"}, FT::kSwitch, "Show information."); +} //////////////////////////////////////////////////////////////////////////////// /// Returns true iff a given module (and its submodules) contains all headers @@ -3846,8 +3835,7 @@ static bool CheckModuleValid(TModuleGenerator &modGen, const std::string &resour // This way we will make sure the module is properly activated. if (!gOptUmbrellaInput && maybeUmbrella) { ROOT::TMetaUtils::Info("CheckModuleValid, %s. You can silence this message by adding %s to the invocation.", - warningMessage.c_str(), - gOptUmbrellaInput.ArgStr.data()); + warningMessage.c_str(), "umbrellaHeader"); return true; } @@ -3881,11 +3869,6 @@ int RootClingMain(int argc, char **argv, bool isGenreflex = false) { - // Set number of required arguments. We cannot do this globally since it - // would interfere with LLVM's option parsing. - gOptDictionaryFileName.setNumOccurrencesFlag(llvm::cl::Required); - gOptDictionaryHeaderFiles.setNumOccurrencesFlag(llvm::cl::OneOrMore); - // Copied from cling driver. // FIXME: Uncomment once we fix ROOT's teardown order. //llvm::llvm_shutdown_obj shutdownTrigger; @@ -3913,25 +3896,12 @@ int RootClingMain(int argc, } #endif - // Hide options from llvm which we got from static initialization of libCling. - llvm::cl::HideUnrelatedOptions(/*keep*/gRootclingOptions); - - // Define Options aliasses - auto &opts = llvm::cl::getRegisteredOptions(); - llvm::cl::Option* optHelp = opts["help"]; - llvm::cl::alias optHelpAlias1("h", - llvm::cl::desc("Alias for -help"), - llvm::cl::aliasopt(*optHelp)); - llvm::cl::alias optHelpAlias2("?", - llvm::cl::desc("Alias for -help"), - llvm::cl::aliasopt(*optHelp)); - - llvm::cl::ParseCommandLineOptions(argc, argv, "rootcling"); - + // Check if first positional arg is the subcommand, we pass everything directly to cling. + // FIXME: It would be nice to have optparse handle subcommands, but this works for now. const char *etcDir = gDriverConfig->fTROOT__GetEtcDir(); std::string llvmResourceDir = etcDir ? std::string(etcDir) + "/cling" : ""; - if (gBareClingSubcommand) { + if (argc > 0 && std::string(argv[1]) == "bare-cling") { std::vector clingArgsC; clingArgsC.push_back(executableFileName); // Help cling finds its runtime (RuntimeUniverse.h and such). @@ -3943,8 +3913,11 @@ int RootClingMain(int argc, //clingArgsC.push_back("-resource-dir"); //clingArgsC.push_back(llvmResourceDir.c_str()); - for (const std::string& Opt : gOptBareClingSink) - clingArgsC.push_back(Opt.c_str()); + // Push all args after 'bare-cling' exactly as they were passed + for (int i = 2; i < argc; ++i) { + llvm::errs() << argv[i] << "\n"; + clingArgsC.push_back(argv[i]); + } auto interp = std::make_unique(clingArgsC.size(), &clingArgsC[0], @@ -3954,6 +3927,135 @@ int RootClingMain(int argc, return interp->getDiagnostics().hasFatalErrorOccurred(); } + ROOT::RCmdLineOpts opts; + DefineRootclingOptions(opts); + + std::vector cargv(argv, argv + argc); + opts.Parse(cargv.data(), argc); + + if (opts.ReportErrors()) { + std::cerr << kShortHelp; + return 1; + } + + if (opts.GetSwitch("help")) { + std::cerr << kShortHelp; + std::cerr << kLongHelp; + return 0; + } + + // Set the default verbosity + gOptVerboseLevel = v2; + + // FIXME: if -v2 and -v4 is set, should we set -v4 by default? + // From CommandLine docs: + // Options that are specified multiple times are redundant. Any instances after the first are discarded. + if (opts.GetSwitch("v0")) + gOptVerboseLevel = v0; + if (opts.GetSwitch("v1") || opts.GetSwitch("v")) + gOptVerboseLevel = v; + if (opts.GetSwitch("v2")) + gOptVerboseLevel = v2; + if (opts.GetSwitch("v3")) + gOptVerboseLevel = v3; + if (opts.GetSwitch("v4")) + gOptVerboseLevel = v4; + + gOptForce = opts.GetSwitch("f"); + gOptRootBuild = opts.GetSwitch("rootbuild"); + gOptCint = opts.GetSwitch("cint"); + gOptReflex = opts.GetSwitch("reflex"); + gOptGccXml = opts.GetSwitch("gccxml"); + gOptGeneratePCH = opts.GetSwitch("generate-pch"); + gOptC = opts.GetSwitch("c"); + gOptP = opts.GetSwitch("p"); + gOptCxxModule = opts.GetSwitch("cxxmodule"); + gOptUmbrellaInput = opts.GetSwitch("umbrellaHeader"); + gOptMultiDict = opts.GetSwitch("multiDict"); + gOptNoGlobalUsingStd = opts.GetSwitch("noGlobalUsingStd"); + gOptInterpreterOnly = opts.GetSwitch("interpreteronly"); + gOptSplit = opts.GetSwitch("split"); + gOptNoDictSelection = opts.GetSwitch("noDictSelection"); + gOptInlineInput = opts.GetSwitch("inlineInputHeader"); + gOptWriteEmptyRootPCM = opts.GetSwitch("writeEmptyRootPCM"); + gOptCheckSelectionSyntax = opts.GetSwitch("selSyntaxOnly"); + gOptFailOnWarnings = opts.GetSwitch("failOnWarnings"); + gOptNoIncludePaths = opts.GetSwitch("noIncludePaths"); + gOptSystemModuleByproducts = opts.GetSwitch("mSystemByproducts"); + + gOptLibListPrefix = std::string(opts.GetFlagValue("lib-list-prefix")); + gOptRootMapFileName = std::string(opts.GetFlagValue("rmf")); + gOptSharedLibFileName = std::string(opts.GetFlagValue("s")); + gOptISysRoot = std::string(opts.GetFlagValue("isysroot")); + + gOptRootmapLibNames.reserve(opts.GetFlagValues("rml").size()); + for (std::string_view v : opts.GetFlagValues("rml")) { + gOptRootmapLibNames.emplace_back(v); + } + + gOptModuleMapFiles.reserve(opts.GetFlagValues("moduleMapFile").size()); + for (std::string_view v : opts.GetFlagValues("moduleMapFile")) { + gOptModuleMapFiles.emplace_back(v); + } + + gOptModuleDependencies.reserve(opts.GetFlagValues("m").size()); + for (std::string_view v : opts.GetFlagValues("m")) { + gOptModuleDependencies.emplace_back(v); + } + + gOptExcludePaths.reserve(opts.GetFlagValues("excludePath").size()); + for (std::string_view v : opts.GetFlagValues("excludePath")) { + gOptExcludePaths.emplace_back(v); + } + + gOptSysIncludePaths.reserve(opts.GetFlagValues("isystem").size()); + for (std::string_view v : opts.GetFlagValues("isystem")) { + gOptSysIncludePaths.emplace_back(v); + } + + gOptIncludePaths.reserve(opts.GetFlagValues("I").size()); + for (std::string_view v : opts.GetFlagValues("I")) { + gOptIncludePaths.emplace_back(v); + } + + gOptCompDefaultIncludePaths.reserve(opts.GetFlagValues("compilerI").size()); + for (std::string_view v : opts.GetFlagValues("compilerI")) { + gOptCompDefaultIncludePaths.emplace_back(v); + } + + gOptPPDefines.reserve(opts.GetFlagValues("D").size()); + for (std::string_view v : opts.GetFlagValues("D")) { + gOptPPDefines.emplace_back(v); + } + + gOptPPUndefines.reserve(opts.GetFlagValues("U").size()); + for (std::string_view v : opts.GetFlagValues("U")) { + gOptPPUndefines.emplace_back(v); + } + + gOptWDiags.reserve(opts.GetFlagValues("W").size()); + for (std::string_view v : opts.GetFlagValues("W")) { + gOptWDiags.emplace_back(v); + } + + gOptModuleByproducts.reserve(opts.GetFlagValues("mByproduct").size()); + for (std::string_view v : opts.GetFlagValues("mByproduct")) { + gOptModuleByproducts.emplace_back(v); + } + + // Positional args: rootcling, , + auto positionalArgs = opts.GetArgs(); + if (!positionalArgs.empty()) { + gOptDictionaryFileName = positionalArgs[1]; + } else { + ROOT::TMetaUtils::Error(nullptr, "No dictionary file specified!\n"); + return 1; + } + + for (size_t i = 2, e = positionalArgs.size(); i < e; ++i) { + gOptDictionaryHeaderFiles.push_back(positionalArgs[i]); + } + std::string dictname; if (!gDriverConfig->fBuildingROOTStage1) { @@ -3964,11 +4066,9 @@ int RootClingMain(int argc, } if (!gOptModuleMapFiles.empty() && !gOptCxxModule) { - ROOT::TMetaUtils::Error("", "Option %s can be used only when option %s is specified.\n", - gOptModuleMapFiles.ArgStr.str().c_str(), - gOptCxxModule.ArgStr.str().c_str()); - std::cout << "\n"; - llvm::cl::PrintHelpMessage(); + ROOT::TMetaUtils::Error("", "Option %s can be used only when option %s is specified.\n", "moduleMapFile", + "cxxmodule"); + std::cerr << kShortHelp << kLongHelp; return 1; } @@ -4012,7 +4112,7 @@ int RootClingMain(int argc, if (gOptForce && dictname.empty()) { ROOT::TMetaUtils::Error(nullptr, "Inconsistent set of arguments detected: overwrite of dictionary file forced but no filename specified.\n"); - llvm::cl::PrintHelpMessage(); + std::cerr << kShortHelp << kLongHelp; return 1; } @@ -4035,13 +4135,9 @@ int RootClingMain(int argc, GetWarningsAreErrors() = true; } - if (gOptISysRoot != "-") { - if (gOptISysRoot.empty()) { - ROOT::TMetaUtils::Error("", "isysroot specified without a value.\n"); - return 1; - } - clingArgs.push_back(gOptISysRoot.ArgStr.str()); - clingArgs.push_back(gOptISysRoot.ValueStr.str()); + if (!gOptISysRoot.empty()) { + clingArgs.push_back("-isysroot"); + clingArgs.push_back(gOptISysRoot); } // Check if we have a multi dict request but no target library @@ -4140,7 +4236,7 @@ int RootClingMain(int argc, // FIXME: This line is from TModuleGenerator, but we can't reuse this code // at this point because TModuleGenerator needs a CompilerInstance (and we // currently create the arguments for creating said CompilerInstance). - bool isPCH = (gOptDictionaryFileName.getValue() == "allDict.cxx"); + bool isPCH = (gOptDictionaryFileName == "allDict.cxx"); std::string outputFile; // Data is in 'outputFile', therefore in the same scope. llvm::StringRef moduleName; @@ -4151,7 +4247,7 @@ int RootClingMain(int argc, auto clingArgsInterpreter = clingArgs; if (gOptSharedLibFileName.empty()) { - gOptSharedLibFileName = gOptDictionaryFileName.getValue(); + gOptSharedLibFileName = gOptDictionaryFileName; } if (!isPCH && gOptCxxModule) { @@ -4414,7 +4510,7 @@ int RootClingMain(int argc, unsigned expectedHeaderFilesSize = 1 + hasSelectionFile; if (gOptDictionaryHeaderFiles.size() > expectedHeaderFilesSize) ROOT::TMetaUtils::Error(nullptr, "Option %s used but more than one header file specified.\n", - gOptUmbrellaInput.ArgStr.data()); + "umbrellaHeader"); } // We have a multiDict request. This implies generating a pcm which is of the form @@ -4512,13 +4608,13 @@ int RootClingMain(int argc, // Check if code goes to stdout or rootcling file std::ofstream fileout; - string main_dictname(gOptDictionaryFileName.getValue()); + string main_dictname(gOptDictionaryFileName); std::ostream *splitDictStream = nullptr; std::unique_ptr splitDeleter(nullptr); // Store the temp files tempFileNamesCatalog tmpCatalog; if (!gOptDictionaryFileName.empty()) { - tmpCatalog.addFileName(gOptDictionaryFileName.getValue()); + tmpCatalog.addFileName(gOptDictionaryFileName); fileout.open(gOptDictionaryFileName.c_str()); if (!fileout) { ROOT::TMetaUtils::Error(nullptr, "rootcling: failed to open %s in main\n", @@ -4528,11 +4624,11 @@ int RootClingMain(int argc, } std::ostream &dictStream = (!gOptDictionaryFileName.empty()) ? fileout : std::cout; - bool isACLiC = gOptDictionaryFileName.getValue().find("_ACLiC_dict") != std::string::npos; + bool isACLiC = gOptDictionaryFileName.find("_ACLiC_dict") != std::string::npos; // Now generate a second stream for the split dictionary if it is necessary if (gOptSplit) { - splitDictStream = CreateStreamPtrForSplitDict(gOptDictionaryFileName.getValue(), tmpCatalog); + splitDictStream = CreateStreamPtrForSplitDict(gOptDictionaryFileName, tmpCatalog); splitDeleter.reset(splitDictStream); } else { splitDictStream = &dictStream; @@ -5004,7 +5100,6 @@ int RootClingMain(int argc, } return rootclingRetCode; - } namespace genreflex { @@ -5202,23 +5297,23 @@ namespace genreflex { // RootMap filename if (!newRootmapFileName.empty()) { - argvVector.push_back(string2charptr("-rmf")); + argvVector.push_back(string2charptr("--rmf")); argvVector.push_back(string2charptr(newRootmapFileName)); } // RootMap Lib filename if (!newRootmapLibName.empty()) { - argvVector.push_back(string2charptr("-rml")); + argvVector.push_back(string2charptr("--rml")); argvVector.push_back(string2charptr(newRootmapLibName)); } - // Always use the -reflex option: we want rootcling to behave + // Always use the --reflex option: we want rootcling to behave // like genreflex in this case - argvVector.push_back(string2charptr("-reflex")); + argvVector.push_back(string2charptr("--reflex")); // Interpreter only dictionaries if (interpreteronly) - argvVector.push_back(string2charptr("-interpreteronly")); + argvVector.push_back(string2charptr("--interpreteronly")); // Split dictionaries if (doSplit) @@ -5232,17 +5327,16 @@ namespace genreflex { // Multidict support if (multiDict) - argvVector.push_back(string2charptr("-multiDict")); + argvVector.push_back(string2charptr("--multiDict")); // Don't declare "using namespace std" if (noGlobalUsingStd) - argvVector.push_back(string2charptr("-noGlobalUsingStd")); - + argvVector.push_back(string2charptr("--noGlobalUsingStd")); AddToArgVectorSplit(argvVector, pcmsNames, "-m"); // Inline the input header - argvVector.push_back(string2charptr("-inlineInputHeader")); + argvVector.push_back(string2charptr("--inlineInputHeader")); // Write empty root pcms if (writeEmptyRootPCM) @@ -5258,7 +5352,7 @@ namespace genreflex { // Fail on warnings if (failOnWarnings) - argvVector.push_back(string2charptr("-failOnWarnings")); + argvVector.push_back(string2charptr("--failOnWarnings")); // Clingargs AddToArgVector(argvVector, includes, "-I"); @@ -5440,8 +5534,8 @@ bool IsGoodLibraryName(const std::string &name) /// New arguments: /// -l --library targetLib name (new) -s targetLib name /// -m pcmname (can be many -m) (new) -m pcmname (can be many -m) -/// --rootmap -rmf (new) -/// --rootmap-lib -rml (new) +/// --rootmap --rmf (new) +/// --rootmap-lib --rml (new) /// /// genreflex options which rise warnings (feedback is desirable) /// --no_membertypedefs (it should be irrelevant) diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx index d4ff40c5349e9..a77e0c8066805 100644 --- a/core/metacling/src/TCling.cxx +++ b/core/metacling/src/TCling.cxx @@ -1493,7 +1493,7 @@ TCling::TCling(const char *name, const char *title, const char* const argv[], vo clingArgsStorage.push_back("-ftime-report"); // Add the overlay file. Note that we cannot factor it out for both root - // and rootcling because rootcling activates modules only if -cxxmodule + // and rootcling because rootcling activates modules only if --cxxmodule // flag is passed. if (fCxxModulesEnabled && !fromRootCling) { // For now we prefer rootcling to enumerate explicitly its modulemaps. diff --git a/etc/dictpch/makepch.py b/etc/dictpch/makepch.py index 8233f4e2f222f..6d304523e9720 100755 --- a/etc/dictpch/makepch.py +++ b/etc/dictpch/makepch.py @@ -76,7 +76,7 @@ def makepch(): print ("ERROR: cannot find %s file here %s nor here %s" %(allheadersFilename, loc1, loc2)) sys.exit(1) else: - rootbuildFlag="-rootbuild" + rootbuildFlag="--rootbuild" cppFlags = getCppFlags(cppflagsFilename) @@ -100,7 +100,7 @@ def makepch(): alllinkdefsFilename.replace("\\","/") rootclingExe = os.path.join(rootdir,"bin","rootcling") - command = "%s %s -generate-pch -f allDict.cxx -noDictSelection %s %s %s %s" %(rootclingExe, + command = "%s %s --generate-pch -f allDict.cxx --noDictSelection %s %s %s %s" %(rootclingExe, rootbuildFlag, allCppFlags, allheadersFilename, diff --git a/roottest/cling/dict/ROOT-7879/CMakeLists.txt b/roottest/cling/dict/ROOT-7879/CMakeLists.txt index 20beb6c9b2b96..46434df9deb00 100644 --- a/roottest/cling/dict/ROOT-7879/CMakeLists.txt +++ b/roottest/cling/dict/ROOT-7879/CMakeLists.txt @@ -1,6 +1,6 @@ # ROOT-7879 ROOTTEST_ADD_TEST(skipLinkDefDict - COMMAND ${ROOT_rootcling_CMD} -f libSkippingDict.cxx -rmf libSkipping.rootmap -rml libSkipping${libsuffix} ${CMAKE_CURRENT_SOURCE_DIR}/skippingHeader.h ${CMAKE_CURRENT_SOURCE_DIR}/skipLinkDef.h + COMMAND ${ROOT_rootcling_CMD} -f libSkippingDict.cxx --rmf libSkipping.rootmap --rml libSkipping${libsuffix} ${CMAKE_CURRENT_SOURCE_DIR}/skippingHeader.h ${CMAKE_CURRENT_SOURCE_DIR}/skipLinkDef.h OUTREF skipLinkDefDict.ref) ROOTTEST_ADD_TEST(skipLinkDef diff --git a/roottest/cling/dict/ROOT-9185/CMakeLists.txt b/roottest/cling/dict/ROOT-9185/CMakeLists.txt index 813e8ff8c09a6..d2796c56b3d2f 100644 --- a/roottest/cling/dict/ROOT-9185/CMakeLists.txt +++ b/roottest/cling/dict/ROOT-9185/CMakeLists.txt @@ -1,4 +1,4 @@ ROOTTEST_ADD_TEST(ROOT9185 EXEC $ - OPTS -v2 -f ROOT9185Dict.cxx -s ROOT9185Dict.so -rml ROOT9185Dict.so -rmf ROOT9185Dict.rootmap ROOT9185.h ${CMAKE_CURRENT_SOURCE_DIR}/ROOT9185Linkdef.h + OPTS -v2 -f ROOT9185Dict.cxx -s ROOT9185Dict.so --rml ROOT9185Dict.so --rmf ROOT9185Dict.rootmap ROOT9185.h ${CMAKE_CURRENT_SOURCE_DIR}/ROOT9185Linkdef.h COPY_TO_BUILDDIR ROOT9185.h) diff --git a/roottest/root/meta/rootcling-modules/module-dep-order/CMakeLists.txt b/roottest/root/meta/rootcling-modules/module-dep-order/CMakeLists.txt index 2c8185b764f08..caaa11a13ab4b 100644 --- a/roottest/root/meta/rootcling-modules/module-dep-order/CMakeLists.txt +++ b/roottest/root/meta/rootcling-modules/module-dep-order/CMakeLists.txt @@ -1,5 +1,5 @@ ROOTTEST_ADD_TEST(cxxmodules-implicit-build-error - COMMAND ${ROOT_rootcling_CMD} -f ${CMAKE_CURRENT_BINARY_DIR}/out.cxx -cxxmodule + COMMAND ${ROOT_rootcling_CMD} -f ${CMAKE_CURRENT_BINARY_DIR}/out.cxx --cxxmodule implicit_build.h implicit_build_linkdef.h PRECMD ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/out.pcm ${CMAKE_CURRENT_BINARY_DIR}/out_rdict.pcm ${CMAKE_CURRENT_BINARY_DIR}/A.pcm diff --git a/tree/dataframe/test/CMakeLists.txt b/tree/dataframe/test/CMakeLists.txt index 490b883fe7cbb..b0515b7e14db2 100644 --- a/tree/dataframe/test/CMakeLists.txt +++ b/tree/dataframe/test/CMakeLists.txt @@ -29,7 +29,7 @@ endif() ROOT_ADD_GTEST(dataframe_splitcoll_arrayview dataframe_splitcoll_arrayview.cxx LIBRARIES ROOTDataFrame) target_include_directories(dataframe_splitcoll_arrayview PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -ROOT_GENERATE_DICTIONARY(TwoFloatsDict ${CMAKE_CURRENT_SOURCE_DIR}/TwoFloats.h MODULE dataframe_splitcoll_arrayview LINKDEF TwoFloatsLinkDef.h OPTIONS -inlineInputHeader DEPENDENCIES RIO) +ROOT_GENERATE_DICTIONARY(TwoFloatsDict ${CMAKE_CURRENT_SOURCE_DIR}/TwoFloats.h MODULE dataframe_splitcoll_arrayview LINKDEF TwoFloatsLinkDef.h OPTIONS --inlineInputHeader DEPENDENCIES RIO) ROOT_ADD_GTEST(dataframe_redefine dataframe_redefine.cxx LIBRARIES ROOTDataFrame) ROOT_ADD_GTEST(dataframe_definepersample dataframe_definepersample.cxx LIBRARIES ROOTDataFrame) @@ -38,7 +38,7 @@ if(NOT MSVC OR win_broken_tests) ROOT_ADD_GTEST(dataframe_simple dataframe_simple.cxx LIBRARIES ROOTDataFrame GenVector) target_include_directories(dataframe_simple PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) ROOT_GENERATE_DICTIONARY(DataFrameSimpleDict ${CMAKE_CURRENT_SOURCE_DIR}/MaxSlotHelper.h ${CMAKE_CURRENT_SOURCE_DIR}/SimpleFiller.h MODULE dataframe_simple - LINKDEF DataFrameSimpleLinkDef.h OPTIONS -inlineInputHeader DEPENDENCIES ROOTDataFrame Hist) + LINKDEF DataFrameSimpleLinkDef.h OPTIONS --inlineInputHeader DEPENDENCIES ROOTDataFrame Hist) endif() ROOT_ADD_GTEST(dataframe_vecops dataframe_vecops.cxx LIBRARIES ROOTDataFrame) ROOT_ADD_GTEST(dataframe_helpers dataframe_helpers.cxx LIBRARIES ROOTDataFrame) @@ -50,18 +50,18 @@ endif() ROOT_ADD_GTEST(dataframe_snapshot dataframe_snapshot.cxx LIBRARIES ROOTDataFrame GenVector) ROOT_GENERATE_DICTIONARY(DataFrameSnapshotUtils ${CMAKE_CURRENT_SOURCE_DIR}/DataFrameSnapshotUtils.hxx - MODULE dataframe_snapshot LINKDEF DataFrameSnapshotUtilsLinkDef.hxx OPTIONS -inlineInputHeader) + MODULE dataframe_snapshot LINKDEF DataFrameSnapshotUtilsLinkDef.hxx OPTIONS --inlineInputHeader) ROOT_ADD_GTEST(dataframe_snapshot_emptyoutput dataframe_snapshot_emptyoutput.cxx LIBRARIES ROOTDataFrame GenVector) ROOT_GENERATE_DICTIONARY(DummyDict ${CMAKE_CURRENT_SOURCE_DIR}/DummyHeader.hxx - MODULE dataframe_snapshot_emptyoutput LINKDEF DummyHeaderLinkDef.hxx OPTIONS -inlineInputHeader + MODULE dataframe_snapshot_emptyoutput LINKDEF DummyHeaderLinkDef.hxx OPTIONS --inlineInputHeader DEPENDENCIES ROOTVecOps GenVector) ROOT_ADD_GTEST(dataframe_snapshot_ntuple dataframe_snapshot_ntuple.cxx LIBRARIES ROOTDataFrame ROOTNTuple NTupleStruct) ROOT_ADD_GTEST(dataframe_snapshotWithVariations dataframe_snapshotWithVariations.cxx LIBRARIES ROOTDataFrame) ROOT_GENERATE_DICTIONARY(TwoFloats_SnapshotDict ${CMAKE_CURRENT_SOURCE_DIR}/TwoFloats_Snapshot.h LINKDEF TwoFloats_SnapshotLinkDef.h MODULE dataframe_snapshotWithVariations - OPTIONS -inlineInputHeader + OPTIONS --inlineInputHeader DEPENDENCIES RIO) ROOT_ADD_GTEST(dataframe_datasetspec dataframe_datasetspec.cxx LIBRARIES ROOTDataFrame) @@ -109,7 +109,7 @@ ROOT_GENERATE_DICTIONARY(ClassWithNestedSameNameDict ${CMAKE_CURRENT_SOURCE_DIR}/ClassWithNestedSameName.hxx MODULE datasource_tree LINKDEF ClassWithNestedSameNameLinkDef.hxx - OPTIONS -inlineInputHeader + OPTIONS --inlineInputHeader DEPENDENCIES RIO) ROOT_ADD_GTEST(datasource_ntuple datasource_ntuple.cxx LIBRARIES ROOTDataFrame) @@ -131,7 +131,7 @@ if(MSVC AND NOT CMAKE_GENERATOR MATCHES Ninja) ${CMAKE_CURRENT_BINARY_DIR}/libNTupleStruct.dll) endif() ROOT_GENERATE_DICTIONARY(ClassWithArraysDict ${CMAKE_CURRENT_SOURCE_DIR}/ClassWithArrays.h - MODULE datasource_ntuple LINKDEF ClassWithArraysLinkDef.h OPTIONS -inlineInputHeader + MODULE datasource_ntuple LINKDEF ClassWithArraysLinkDef.h OPTIONS --inlineInputHeader DEPENDENCIES ROOTVecOps) #### TESTS REQUIRING EXTRA ROOT FEATURES #### diff --git a/tree/ntuple/test/CMakeLists.txt b/tree/ntuple/test/CMakeLists.txt index 7bd5824ddfd7d..623f01cd9918a 100644 --- a/tree/ntuple/test/CMakeLists.txt +++ b/tree/ntuple/test/CMakeLists.txt @@ -37,7 +37,7 @@ ROOT_ADD_GTEST(ntuple_evolution_type ntuple_evolution_type.cxx LIBRARIES ROOTNTu ROOT_GENERATE_DICTIONARY(STLContainerEvolutionDict ${CMAKE_CURRENT_SOURCE_DIR}/STLContainerEvolution.hxx MODULE ntuple_evolution_type LINKDEF STLContainerEvolutionLinkDef.h - OPTIONS -inlineInputHeader + OPTIONS --inlineInputHeader DEPENDENCIES CustomStruct) if(NOT MSVC) # These unit tests rely on fork(), which is not available on Windows. @@ -72,7 +72,7 @@ if(NOT MSVC OR llvm13_broken_tests) ROOT_GENERATE_DICTIONARY(ProxiedSTLContainerDict ${CMAKE_CURRENT_SOURCE_DIR}/ProxiedSTLContainer.hxx MODULE ntuple_types LINKDEF ProxiedSTLContainerLinkDef.h - OPTIONS -inlineInputHeader + OPTIONS --inlineInputHeader DEPENDENCIES CustomStruct) endif() ROOT_ADD_GTEST(ntuple_view ntuple_view.cxx LIBRARIES ROOTNTuple CustomStruct) @@ -111,7 +111,7 @@ ROOT_ADD_GTEST(ntuple_limits ntuple_limits.cxx LIBRARIES ROOTNTuple) ROOT_ADD_GTEST(rfield_streamer rfield_streamer.cxx StreamerField.cxx StreamerFieldXML.cxx LIBRARIES ROOTNTuple) ROOT_GENERATE_DICTIONARY(StreamerFieldDict ${CMAKE_CURRENT_SOURCE_DIR}/StreamerField.hxx - MODULE rfield_streamer LINKDEF StreamerFieldLinkDef.h OPTIONS -inlineInputHeader + MODULE rfield_streamer LINKDEF StreamerFieldLinkDef.h OPTIONS --inlineInputHeader DEPENDENCIES RIO) if(MSVC) diff --git a/tree/tree/test/CMakeLists.txt b/tree/tree/test/CMakeLists.txt index 4e903b06daafc..8cc846afadae5 100644 --- a/tree/tree/test/CMakeLists.txt +++ b/tree/tree/test/CMakeLists.txt @@ -5,7 +5,7 @@ # For the list of contributors see $ROOTSYS/README/CREDITS. -ROOT_GENERATE_DICTIONARY(ElementStructDict ElementStruct.h LINKDEF ElementStructLinkDef.h OPTIONS -inlineInputHeader) +ROOT_GENERATE_DICTIONARY(ElementStructDict ElementStruct.h LINKDEF ElementStructLinkDef.h OPTIONS --inlineInputHeader) ROOT_ADD_GTEST(testTOffsetGeneration TOffsetGeneration.cxx ElementStruct.cxx ElementStructDict.cxx LIBRARIES RIO Tree MathCore ) @@ -42,6 +42,6 @@ ROOT_ADD_GTEST(evolution evolution.cxx LIBRARIES RIO Tree) ROOT_GENERATE_DICTIONARY(EvolutionStruct ${CMAKE_CURRENT_SOURCE_DIR}/EvolutionStruct.hxx MODULE evolution LINKDEF EvolutionStructLinkDef.h - OPTIONS -inlineInputHeader + OPTIONS --inlineInputHeader DEPENDENCIES RIO)