From f1e5773303dead663b48c846e2f3eaf2830de4de Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Tue, 20 Jan 2026 13:12:31 +0100 Subject: [PATCH 1/3] Add test for user-defined classes Closes #10 --- .gitignore | 1 + types/README.md | 1 + types/user/README.md | 3 + types/user/class/LinkDef.h | 12 ++++ types/user/class/Makefile | 20 ++++++ types/user/class/README.md | 20 ++++++ types/user/class/UserClass.hxx | 27 ++++++++ types/user/class/read.C | 122 +++++++++++++++++++++++++++++++++ types/user/class/write.C | 60 ++++++++++++++++ 9 files changed, 266 insertions(+) create mode 100644 types/user/README.md create mode 100644 types/user/class/LinkDef.h create mode 100644 types/user/class/Makefile create mode 100644 types/user/class/README.md create mode 100644 types/user/class/UserClass.hxx create mode 100644 types/user/class/read.C create mode 100644 types/user/class/write.C diff --git a/.gitignore b/.gitignore index 7c44c1c..76d5064 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ *.pcm *.so Nested*.cxx +User*.cxx diff --git a/types/README.md b/types/README.md index c131b58..3b76e6a 100644 --- a/types/README.md +++ b/types/README.md @@ -11,6 +11,7 @@ * [`unique_ptr`](unique_ptr): `std::unique_ptr` with different element types * [`unordered_multiset`](unordered_multiset): `std::unordered_multiset` with all `[Split]Index{32,64}` column types * [`unordered_set`](unordered_set): `std::unordered_set` with all `[Split]Index{32,64}` column types + * [`user`](user): user-defined types, such as classes and enums * [`variant`](variant): `std::variant` with `Switch` column type * [`vector`](vector): `std::vector` with all `[Split]Index{32,64}` column types diff --git a/types/user/README.md b/types/user/README.md new file mode 100644 index 0000000..d42dfcf --- /dev/null +++ b/types/user/README.md @@ -0,0 +1,3 @@ +# User-defined Types + + * [`class`]: user-defined class(es) diff --git a/types/user/class/LinkDef.h b/types/user/class/LinkDef.h new file mode 100644 index 0000000..e6fb3a3 --- /dev/null +++ b/types/user/class/LinkDef.h @@ -0,0 +1,12 @@ +#include +#include +#include + +#ifdef __CLING__ +#pragma link C++ class Base+; +#pragma link C++ class Nested+; +// ROOT does not (yet) support std::variant, but this line silences a warning +// that fVariant would not be saved (which is not true for RNTuple). +#pragma link C++ class std::variant; +#pragma link C++ class User+; +#endif diff --git a/types/user/class/Makefile b/types/user/class/Makefile new file mode 100644 index 0000000..25b5584 --- /dev/null +++ b/types/user/class/Makefile @@ -0,0 +1,20 @@ +CXX=g++ +CXXFLAGS_ROOT=$(shell root-config --cflags) +ifeq ($(CXXFLAGS_ROOT),) + $(error cannot find root-config: make sure to source thisroot.sh) +endif +CXXFLAGS=-Wall $(CXXFLAGS_ROOT) +LDFLAGS=$(shell root-config --libs) + +.PHONY: all clean + +all: UserClass.cxx libUserClass.so + +UserClass.cxx: UserClass.hxx LinkDef.h + rootcling -f $@ $^ + +libUserClass.so: UserClass.cxx + $(CXX) -shared -fPIC -o $@ $^ $(CXXFLAGS) $(LDFLAGS) + +clean: + rm -f UserClass.cxx UserClass_rdict.pcm libUserClass.so diff --git a/types/user/class/README.md b/types/user/class/README.md new file mode 100644 index 0000000..14b996b --- /dev/null +++ b/types/user/class/README.md @@ -0,0 +1,20 @@ +# User-defined class(es) + +## Fields + + * `f` of type `User` with the following subfields: + * `:_0` of type `Base` + * `fInt` of type `std::int32_t` + * `fString` of type `std::string` + * `fVariant` of type `std::variant` + * `fVector` of type `std::vector` + * `fNested` of type `Nested` + * `fInt` of type `std::int32_t` + * `VectorUser` of type `std::vector` + +with the default column types. + +## Entries + +1. Simple values +2. Zero / empty values diff --git a/types/user/class/UserClass.hxx b/types/user/class/UserClass.hxx new file mode 100644 index 0000000..cc75f3e --- /dev/null +++ b/types/user/class/UserClass.hxx @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include +#include + +using Variant = std::variant; +using Vector = std::vector; + +class Base { +public: + std::int32_t fInt; +}; + +class Nested { +public: + std::int32_t fInt; +}; + +class User : public Base { +public: + std::string fString; + Variant fVariant; + Vector fVector; + Nested fNested; +}; diff --git a/types/user/class/read.C b/types/user/class/read.C new file mode 100644 index 0000000..94e793e --- /dev/null +++ b/types/user/class/read.C @@ -0,0 +1,122 @@ +#include +#include + +using ROOT::Experimental::REntry; +using ROOT::Experimental::RNTupleReader; + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "UserClass.hxx" + +static void PrintUserMembers(const User &value, std::ostream &os, + std::string_view indent) { + os << indent << "\":_0\": {\n"; + os << indent << " \"fInt\": " << value.fInt << "\n"; + os << indent << "},\n"; + os << indent << "\"fString\": \"" << value.fString << "\",\n"; + + os << indent << "\"fVariant\": "; + if (value.fVariant.index() == 0) { + os << std::get(value.fVariant); + } else if (value.fVariant.index() == 1) { + os << "\"" << std::get(value.fVariant) << "\""; + } + os << ",\n"; + + os << indent << "\"fVector\": ["; + bool first = true; + for (auto element : value.fVector) { + if (first) { + first = false; + } else { + os << ","; + } + os << "\n" << indent << " " << element; + } + if (!value.fVector.empty()) { + os << "\n" << indent; + } + os << "],\n"; + + os << indent << "\"fNested\": {\n"; + os << indent << " \"fInt\": " << value.fNested.fInt << "\n"; + os << indent << "}\n"; +} + +static void PrintUserValue(const REntry &entry, std::string_view name, + std::ostream &os, bool last = false) { + auto &value = *entry.GetPtr(name); + os << " \"" << name << "\": {\n"; + PrintUserMembers(value, os, " "); + os << " }"; + if (!last) { + os << ","; + } + os << "\n"; +} + +static void PrintUserVector(const REntry &entry, std::string_view name, + std::ostream &os, bool last = false) { + auto &vector = *entry.GetPtr>(name); + os << " \"" << name << "\": ["; + bool first = true; + for (const auto &element : vector) { + if (first) { + first = false; + } else { + os << ","; + } + os << "\n {\n"; + PrintUserMembers(element, os, " "); + os << " }"; + } + if (!vector.empty()) { + os << "\n "; + } + os << "]"; + if (!last) { + os << ","; + } + os << "\n"; +} + +void read(std::string_view input = "types.user.class.root", + std::string_view output = "types.user.class.json") { + if (gSystem->Load("libUserClass") == -1) + throw std::runtime_error("could not find the required ROOT dictionaries, " + "please make sure to run `make` first"); + + std::ofstream os(std::string{output}); + os << "[\n"; + + auto reader = RNTupleReader::Open("ntpl", input); + auto &entry = reader->GetModel().GetDefaultEntry(); + bool first = true; + for (auto index : *reader) { + reader->LoadEntry(index); + + if (first) { + first = false; + } else { + os << ",\n"; + } + os << " {\n"; + + PrintUserValue(entry, "f", os); + PrintUserVector(entry, "Vector", os, /*last=*/true); + + os << " }"; + // Newline is intentionally missing, may need to print a comma before the + // next entry. + } + os << "\n"; + os << "]\n"; +} diff --git a/types/user/class/write.C b/types/user/class/write.C new file mode 100644 index 0000000..5ead06c --- /dev/null +++ b/types/user/class/write.C @@ -0,0 +1,60 @@ +#include +#include +#include + +using ROOT::Experimental::RNTupleModel; +using ROOT::Experimental::RNTupleWriteOptions; +using ROOT::Experimental::RNTupleWriter; + +#include + +#include + +#include "UserClass.hxx" + +void write(std::string_view filename = "types.user.class.root") { + if (gSystem->Load("libUserClass") == -1) + throw std::runtime_error("could not find the required ROOT dictionaries, " + "please make sure to run `make` first"); + + auto model = RNTupleModel::Create(); + + auto value = model->MakeField("f"); + auto vector = model->MakeField>("Vector"); + + RNTupleWriteOptions options; + options.SetCompression(0); + auto writer = + RNTupleWriter::Recreate(std::move(model), "ntpl", filename, options); + + // First entry: simple values + value->fInt = 1; + value->fString = "b"; + value->fVariant = 3; + value->fVector = {4}; + value->fNested.fInt = 5; + + vector->resize(2); + vector->at(0).fInt = 6; + vector->at(0).fString = "g"; + vector->at(0).fVariant = "h"; + vector->at(0).fVector = {9, 10}; + vector->at(0).fNested.fInt = 11; + + vector->at(1).fInt = 12; + vector->at(1).fString = "m"; + vector->at(1).fVariant = 14; + vector->at(1).fVector = {15}; + vector->at(1).fNested.fInt = 16; + + writer->Fill(); + + // Second entry: zero / empty values + value->fInt = 0; + value->fString = ""; + value->fVariant = 0; + value->fVector.clear(); + value->fNested.fInt = 0; + vector->clear(); + writer->Fill(); +} From ce4e3c77f4e406acabfbacae76aa0209465d57fc Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Tue, 20 Jan 2026 14:26:29 +0100 Subject: [PATCH 2/3] Add test for user-defined enums Closes #12 --- types/user/README.md | 1 + types/user/enum/LinkDef.h | 10 ++++++ types/user/enum/Makefile | 20 +++++++++++ types/user/enum/README.md | 12 +++++++ types/user/enum/UserEnum.hxx | 43 +++++++++++++++++++++++ types/user/enum/read.C | 67 ++++++++++++++++++++++++++++++++++++ types/user/enum/write.C | 58 +++++++++++++++++++++++++++++++ 7 files changed, 211 insertions(+) create mode 100644 types/user/enum/LinkDef.h create mode 100644 types/user/enum/Makefile create mode 100644 types/user/enum/README.md create mode 100644 types/user/enum/UserEnum.hxx create mode 100644 types/user/enum/read.C create mode 100644 types/user/enum/write.C diff --git a/types/user/README.md b/types/user/README.md index d42dfcf..a204443 100644 --- a/types/user/README.md +++ b/types/user/README.md @@ -1,3 +1,4 @@ # User-defined Types * [`class`]: user-defined class(es) + * [`enum`]: user-defined enum(s) diff --git a/types/user/enum/LinkDef.h b/types/user/enum/LinkDef.h new file mode 100644 index 0000000..3a73363 --- /dev/null +++ b/types/user/enum/LinkDef.h @@ -0,0 +1,10 @@ +#ifdef __CLING__ +#pragma link C++ enum EnumInt8+; +#pragma link C++ enum EnumUInt8+; +#pragma link C++ enum EnumInt16+; +#pragma link C++ enum EnumUInt16+; +#pragma link C++ enum EnumInt32+; +#pragma link C++ enum EnumUInt32+; +#pragma link C++ enum EnumInt64+; +#pragma link C++ enum EnumUInt64+; +#endif diff --git a/types/user/enum/Makefile b/types/user/enum/Makefile new file mode 100644 index 0000000..77f750f --- /dev/null +++ b/types/user/enum/Makefile @@ -0,0 +1,20 @@ +CXX=g++ +CXXFLAGS_ROOT=$(shell root-config --cflags) +ifeq ($(CXXFLAGS_ROOT),) + $(error cannot find root-config: make sure to source thisroot.sh) +endif +CXXFLAGS=-Wall $(CXXFLAGS_ROOT) +LDFLAGS=$(shell root-config --libs) + +.PHONY: all clean + +all: UserEnum.cxx libUserEnum.so + +UserEnum.cxx: UserEnum.hxx LinkDef.h + rootcling -f $@ $^ + +libUserEnum.so: UserEnum.cxx + $(CXX) -shared -fPIC -o $@ $^ $(CXXFLAGS) $(LDFLAGS) + +clean: + rm -f UserEnum.cxx UserEnum_rdict.pcm libUserEnum.so diff --git a/types/user/enum/README.md b/types/user/enum/README.md new file mode 100644 index 0000000..5dcc827 --- /dev/null +++ b/types/user/enum/README.md @@ -0,0 +1,12 @@ +# User-defined enum(s) + +## Fields + + * `Enum[U]Int{8,16,32,64}` + +with the default column types. + +## Entries + +1. Simple values +2. Zero values diff --git a/types/user/enum/UserEnum.hxx b/types/user/enum/UserEnum.hxx new file mode 100644 index 0000000..6053e3a --- /dev/null +++ b/types/user/enum/UserEnum.hxx @@ -0,0 +1,43 @@ +#pragma once + +#include + +enum class EnumInt8 : std::int8_t { + Zero = 0, + Simple = 1, +}; + +enum class EnumUInt8 : std::uint8_t { + Zero = 0, + Simple = 2, +}; + +enum class EnumInt16 : std::int16_t { + Zero = 0, + Simple = 3, +}; + +enum class EnumUInt16 : std::uint16_t { + Zero = 0, + Simple = 4, +}; + +enum class EnumInt32 : std::int32_t { + Zero = 0, + Simple = 5, +}; + +enum class EnumUInt32 : std::uint32_t { + Zero = 0, + Simple = 6, +}; + +enum class EnumInt64 : std::int64_t { + Zero = 0, + Simple = 7, +}; + +enum class EnumUInt64 : std::uint64_t { + Zero = 0, + Simple = 8, +}; diff --git a/types/user/enum/read.C b/types/user/enum/read.C new file mode 100644 index 0000000..54f4050 --- /dev/null +++ b/types/user/enum/read.C @@ -0,0 +1,67 @@ +#include +#include + +using ROOT::Experimental::REntry; +using ROOT::Experimental::RNTupleReader; + +#include +#include +#include +#include +#include +#include + +#include "UserEnum.hxx" + +template +static void PrintEnumValue(const REntry &entry, std::string_view name, + std::ostream &os, bool last = false) { + T value = *entry.GetPtr(name); + os << " \"" << name << "\": "; + // We want to print the integer value even if it is a character; use the unary + // + operator (https://stackoverflow.com/a/28414758). + os << +static_cast>(value); + if (!last) { + os << ","; + } + os << "\n"; +} + +void read(std::string_view input = "types.user.enum.root", + std::string_view output = "types.user.enum.json") { + if (gSystem->Load("libUserEnum") == -1) + throw std::runtime_error("could not find the required ROOT dictionaries, " + "please make sure to run `make` first"); + + std::ofstream os(std::string{output}); + os << "[\n"; + + auto reader = RNTupleReader::Open("ntpl", input); + auto &entry = reader->GetModel().GetDefaultEntry(); + bool first = true; + for (auto index : *reader) { + reader->LoadEntry(index); + + if (first) { + first = false; + } else { + os << ",\n"; + } + os << " {\n"; + + PrintEnumValue(entry, "EnumInt8", os); + PrintEnumValue(entry, "EnumUInt8", os); + PrintEnumValue(entry, "EnumInt16", os); + PrintEnumValue(entry, "EnumUInt16", os); + PrintEnumValue(entry, "EnumInt32", os); + PrintEnumValue(entry, "EnumUInt32", os); + PrintEnumValue(entry, "EnumInt64", os); + PrintEnumValue(entry, "EnumUInt64", os, /*last=*/true); + + os << " }"; + // Newline is intentionally missing, may need to print a comma before the + // next entry. + } + os << "\n"; + os << "]\n"; +} diff --git a/types/user/enum/write.C b/types/user/enum/write.C new file mode 100644 index 0000000..57240e6 --- /dev/null +++ b/types/user/enum/write.C @@ -0,0 +1,58 @@ +#include +#include +#include + +using ROOT::Experimental::RNTupleModel; +using ROOT::Experimental::RNTupleWriteOptions; +using ROOT::Experimental::RNTupleWriter; + +#include + +#include + +#include "UserEnum.hxx" + +void write(std::string_view filename = "types.user.enum.root") { + if (gSystem->Load("libUserEnum") == -1) + throw std::runtime_error("could not find the required ROOT dictionaries, " + "please make sure to run `make` first"); + + auto model = RNTupleModel::Create(); + + // TODO: enums with bool underlying type are possible since ROOT 6.38 + auto EInt8 = model->MakeField("EnumInt8"); + auto EUInt8 = model->MakeField("EnumUInt8"); + auto EInt16 = model->MakeField("EnumInt16"); + auto EUInt16 = model->MakeField("EnumUInt16"); + auto EInt32 = model->MakeField("EnumInt32"); + auto EUInt32 = model->MakeField("EnumUInt32"); + auto EInt64 = model->MakeField("EnumInt64"); + auto EUInt64 = model->MakeField("EnumUInt64"); + + RNTupleWriteOptions options; + options.SetCompression(0); + auto writer = + RNTupleWriter::Recreate(std::move(model), "ntpl", filename, options); + + // First entry: simple values + *EInt8 = EnumInt8::Simple; // = 1; + *EUInt8 = EnumUInt8::Simple; // = 2; + *EInt16 = EnumInt16::Simple; // = 3; + *EUInt16 = EnumUInt16::Simple; // = 4; + *EInt32 = EnumInt32::Simple; // = 5; + *EUInt32 = EnumUInt32::Simple; // = 6; + *EInt64 = EnumInt64::Simple; // = 7; + *EUInt64 = EnumUInt64::Simple; // = 8; + writer->Fill(); + + // Second entry: zero values + *EInt8 = EnumInt8::Zero; + *EUInt8 = EnumUInt8::Zero; + *EInt16 = EnumInt16::Zero; + *EUInt16 = EnumUInt16::Zero; + *EInt32 = EnumInt32::Zero; + *EUInt32 = EnumUInt32::Zero; + *EInt64 = EnumInt64::Zero; + *EUInt64 = EnumUInt64::Zero; + writer->Fill(); +} From 83f14401a2337de628217bb15791f6f7917c8aed Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Thu, 22 Jan 2026 11:05:38 +0100 Subject: [PATCH 3/3] Improve Makefile setup More use of variables that users can also override, and removal of unnecessary dependencies. Co-authored-by: Jakob Blomer --- Makefile | 2 +- types/multiset/nested/Makefile | 24 +++++++++++++++--------- types/set/nested/Makefile | 24 +++++++++++++++--------- types/unordered_multiset/nested/Makefile | 24 +++++++++++++++--------- types/unordered_set/nested/Makefile | 24 +++++++++++++++--------- types/user/class/Makefile | 24 +++++++++++++++--------- types/user/enum/Makefile | 24 +++++++++++++++--------- 7 files changed, 91 insertions(+), 55 deletions(-) diff --git a/Makefile b/Makefile index cadf867..1cb46a8 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -ROOT_EXE := $(shell which root.exe) +ROOT_EXE ?= $(shell which root.exe) ifeq ($(ROOT_EXE),) $(error Could not find root.exe) endif diff --git a/types/multiset/nested/Makefile b/types/multiset/nested/Makefile index 9cce17d..b2ab526 100644 --- a/types/multiset/nested/Makefile +++ b/types/multiset/nested/Makefile @@ -1,20 +1,26 @@ -CXX=g++ -CXXFLAGS_ROOT=$(shell root-config --cflags) -ifeq ($(CXXFLAGS_ROOT),) - $(error cannot find root-config: make sure to source thisroot.sh) +ROOT_CONFIG ?= $(shell which root-config) +ifeq ($(ROOT_CONFIG),) +$(error Could not find root-config) endif -CXXFLAGS=-Wall $(CXXFLAGS_ROOT) -LDFLAGS=$(shell root-config --libs) +ROOTCLING ?= $(shell which rootcling) +ifeq ($(ROOTCLING),) +$(error Could not find rootcling) +endif + +CXX := $(shell $(ROOT_CONFIG) --cxx) +CXXFLAGS_ROOT := $(shell $(ROOT_CONFIG) --cflags) +CXXFLAGS := -Wall $(CXXFLAGS_ROOT) +LDFLAGS := $(shell $(ROOT_CONFIG) --libs) .PHONY: all clean -all: NestedMultiset.cxx libNestedMultiset.so +all: libNestedMultiset.so NestedMultiset.cxx: NestedMultiset.hxx LinkDef.h - rootcling -f $@ $^ + $(ROOTCLING) -f $@ $^ libNestedMultiset.so: NestedMultiset.cxx $(CXX) -shared -fPIC -o $@ $^ $(CXXFLAGS) $(LDFLAGS) clean: - rm -f NestedMultiset.cxx NestedMultiset_rdict.pcm libNestedMultiset.so + $(RM) NestedMultiset.cxx NestedMultiset_rdict.pcm libNestedMultiset.so diff --git a/types/set/nested/Makefile b/types/set/nested/Makefile index 836e1a2..0a80f5b 100644 --- a/types/set/nested/Makefile +++ b/types/set/nested/Makefile @@ -1,20 +1,26 @@ -CXX=g++ -CXXFLAGS_ROOT=$(shell root-config --cflags) -ifeq ($(CXXFLAGS_ROOT),) - $(error cannot find root-config: make sure to source thisroot.sh) +ROOT_CONFIG ?= $(shell which root-config) +ifeq ($(ROOT_CONFIG),) +$(error Could not find root-config) endif -CXXFLAGS=-Wall $(CXXFLAGS_ROOT) -LDFLAGS=$(shell root-config --libs) +ROOTCLING ?= $(shell which rootcling) +ifeq ($(ROOTCLING),) +$(error Could not find rootcling) +endif + +CXX := $(shell $(ROOT_CONFIG) --cxx) +CXXFLAGS_ROOT := $(shell $(ROOT_CONFIG) --cflags) +CXXFLAGS := -Wall $(CXXFLAGS_ROOT) +LDFLAGS := $(shell $(ROOT_CONFIG) --libs) .PHONY: all clean -all: NestedSet.cxx libNestedSet.so +all: libNestedSet.so NestedSet.cxx: NestedSet.hxx LinkDef.h - rootcling -f $@ $^ + $(ROOTCLING) -f $@ $^ libNestedSet.so: NestedSet.cxx $(CXX) -shared -fPIC -o $@ $^ $(CXXFLAGS) $(LDFLAGS) clean: - rm -f NestedSet.cxx NestedSet_rdict.pcm libNestedSet.so + $(RM) NestedSet.cxx NestedSet_rdict.pcm libNestedSet.so diff --git a/types/unordered_multiset/nested/Makefile b/types/unordered_multiset/nested/Makefile index 2eadb02..ed4ce36 100644 --- a/types/unordered_multiset/nested/Makefile +++ b/types/unordered_multiset/nested/Makefile @@ -1,20 +1,26 @@ -CXX=g++ -CXXFLAGS_ROOT=$(shell root-config --cflags) -ifeq ($(CXXFLAGS_ROOT),) - $(error cannot find root-config: make sure to source thisroot.sh) +ROOT_CONFIG ?= $(shell which root-config) +ifeq ($(ROOT_CONFIG),) +$(error Could not find root-config) endif -CXXFLAGS=-Wall $(CXXFLAGS_ROOT) -LDFLAGS=$(shell root-config --libs) +ROOTCLING ?= $(shell which rootcling) +ifeq ($(ROOTCLING),) +$(error Could not find rootcling) +endif + +CXX := $(shell $(ROOT_CONFIG) --cxx) +CXXFLAGS_ROOT := $(shell $(ROOT_CONFIG) --cflags) +CXXFLAGS := -Wall $(CXXFLAGS_ROOT) +LDFLAGS := $(shell $(ROOT_CONFIG) --libs) .PHONY: all clean -all: NestedUnorderedMultiset.cxx libNestedUnorderedMultiset.so +all: libNestedUnorderedMultiset.so NestedUnorderedMultiset.cxx: NestedUnorderedMultiset.hxx LinkDef.h - rootcling -f $@ $^ + $(ROOTCLING) -f $@ $^ libNestedUnorderedMultiset.so: NestedUnorderedMultiset.cxx $(CXX) -shared -fPIC -o $@ $^ $(CXXFLAGS) $(LDFLAGS) clean: - rm -f NestedUnorderedMultiset.cxx NestedUnorderedMultiset_rdict.pcm libNestedUnorderedMultiset.so + $(RM) NestedUnorderedMultiset.cxx NestedUnorderedMultiset_rdict.pcm libNestedUnorderedMultiset.so diff --git a/types/unordered_set/nested/Makefile b/types/unordered_set/nested/Makefile index 66c4e16..2ba4937 100644 --- a/types/unordered_set/nested/Makefile +++ b/types/unordered_set/nested/Makefile @@ -1,20 +1,26 @@ -CXX=g++ -CXXFLAGS_ROOT=$(shell root-config --cflags) -ifeq ($(CXXFLAGS_ROOT),) - $(error cannot find root-config: make sure to source thisroot.sh) +ROOT_CONFIG ?= $(shell which root-config) +ifeq ($(ROOT_CONFIG),) +$(error Could not find root-config) endif -CXXFLAGS=-Wall $(CXXFLAGS_ROOT) -LDFLAGS=$(shell root-config --libs) +ROOTCLING ?= $(shell which rootcling) +ifeq ($(ROOTCLING),) +$(error Could not find rootcling) +endif + +CXX := $(shell $(ROOT_CONFIG) --cxx) +CXXFLAGS_ROOT := $(shell $(ROOT_CONFIG) --cflags) +CXXFLAGS := -Wall $(CXXFLAGS_ROOT) +LDFLAGS := $(shell $(ROOT_CONFIG) --libs) .PHONY: all clean -all: NestedUnorderedSet.cxx libNestedUnorderedSet.so +all: libNestedUnorderedSet.so NestedUnorderedSet.cxx: NestedUnorderedSet.hxx LinkDef.h - rootcling -f $@ $^ + $(ROOTCLING) -f $@ $^ libNestedUnorderedSet.so: NestedUnorderedSet.cxx $(CXX) -shared -fPIC -o $@ $^ $(CXXFLAGS) $(LDFLAGS) clean: - rm -f NestedUnorderedSet.cxx NestedUnorderedSet_rdict.pcm libNestedUnorderedSet.so + $(RM) NestedUnorderedSet.cxx NestedUnorderedSet_rdict.pcm libNestedUnorderedSet.so diff --git a/types/user/class/Makefile b/types/user/class/Makefile index 25b5584..a806b2e 100644 --- a/types/user/class/Makefile +++ b/types/user/class/Makefile @@ -1,20 +1,26 @@ -CXX=g++ -CXXFLAGS_ROOT=$(shell root-config --cflags) -ifeq ($(CXXFLAGS_ROOT),) - $(error cannot find root-config: make sure to source thisroot.sh) +ROOT_CONFIG ?= $(shell which root-config) +ifeq ($(ROOT_CONFIG),) +$(error Could not find root-config) endif -CXXFLAGS=-Wall $(CXXFLAGS_ROOT) -LDFLAGS=$(shell root-config --libs) +ROOTCLING ?= $(shell which rootcling) +ifeq ($(ROOTCLING),) +$(error Could not find rootcling) +endif + +CXX := $(shell $(ROOT_CONFIG) --cxx) +CXXFLAGS_ROOT := $(shell $(ROOT_CONFIG) --cflags) +CXXFLAGS := -Wall $(CXXFLAGS_ROOT) +LDFLAGS := $(shell $(ROOT_CONFIG) --libs) .PHONY: all clean -all: UserClass.cxx libUserClass.so +all: libUserClass.so UserClass.cxx: UserClass.hxx LinkDef.h - rootcling -f $@ $^ + $(ROOTCLING) -f $@ $^ libUserClass.so: UserClass.cxx $(CXX) -shared -fPIC -o $@ $^ $(CXXFLAGS) $(LDFLAGS) clean: - rm -f UserClass.cxx UserClass_rdict.pcm libUserClass.so + $(RM) UserClass.cxx UserClass_rdict.pcm libUserClass.so diff --git a/types/user/enum/Makefile b/types/user/enum/Makefile index 77f750f..da2b4bf 100644 --- a/types/user/enum/Makefile +++ b/types/user/enum/Makefile @@ -1,20 +1,26 @@ -CXX=g++ -CXXFLAGS_ROOT=$(shell root-config --cflags) -ifeq ($(CXXFLAGS_ROOT),) - $(error cannot find root-config: make sure to source thisroot.sh) +ROOT_CONFIG ?= $(shell which root-config) +ifeq ($(ROOT_CONFIG),) +$(error Could not find root-config) endif -CXXFLAGS=-Wall $(CXXFLAGS_ROOT) -LDFLAGS=$(shell root-config --libs) +ROOTCLING ?= $(shell which rootcling) +ifeq ($(ROOTCLING),) +$(error Could not find rootcling) +endif + +CXX := $(shell $(ROOT_CONFIG) --cxx) +CXXFLAGS_ROOT := $(shell $(ROOT_CONFIG) --cflags) +CXXFLAGS := -Wall $(CXXFLAGS_ROOT) +LDFLAGS := $(shell $(ROOT_CONFIG) --libs) .PHONY: all clean -all: UserEnum.cxx libUserEnum.so +all: libUserEnum.so UserEnum.cxx: UserEnum.hxx LinkDef.h - rootcling -f $@ $^ + $(ROOTCLING) -f $@ $^ libUserEnum.so: UserEnum.cxx $(CXX) -shared -fPIC -o $@ $^ $(CXXFLAGS) $(LDFLAGS) clean: - rm -f UserEnum.cxx UserEnum_rdict.pcm libUserEnum.so + $(RM) UserEnum.cxx UserEnum_rdict.pcm libUserEnum.so