Any feasible way to compile only PyROOT?

Is there any reasonable way to compile PyROOT against the pre-compiled ROOT distributions? I have been compiling all of ROOT from source and that works fine, but it takes my computer about an hour to compile ROOT. I tried looking through the CMake configuration files, but I didn’t see an easy way to pull out a Makefile that could build PyROOT linked against the pre-built ROOT libraries. The Fedora EPEL distributes PyROOT built against different versions of Python, so I thought it might have a reference for how to do this, but what I found was that it builds ROOT normally, then moves the PyROOT files out of the way, switches out the lib and include directories, and then builds again (see https://src.fedoraproject.org/rpms/root/blob/master/f/root.spec#_2130). So I am not optimistic, but I just wanted to check if anyone had tried something like this.

Hi @wsha2

Right now the compilation of PyROOT works as you described, coupled with the rest of the ROOT build. We will be soon decoupling this a little bit, allowing to specify different Python versions for which the PyROOT libraries should be generated, possibly a posteriori (i.e. ask for a new Python version of the libraries once ROOT has already been built). But this is not yet there.

In the meantime, since PyROOT is mainly a few Python modules plus a C extension module, you could try to write e.g. a setup.py that builds PyROOT against a given ROOT distribution:
https://docs.python.org/3/extending/building.html

Hope this helps,
Enric

Thanks @etejedor, that is good to hear that the build will become a little more flexible. I am sure it is possible to write a setup.py file (or something for another config tool like cmake). However, I think it would take a fair amount of work to work from the boilerplate makefiles that cmake generates for the full ROOT build and turn them into something standalone (maybe not too bad since ultimately, you just need to compile a handful of cxx files into one .so file that links to some other libraries that are part of ROOT – though I don’t really understand what G__PyROOT is yet).

If I have time, I will give it a try because it would be instructive to understand the build system better. However, I mainly use PyROOT with conda, and I might lose interest in studying the build system if this new conda package for ROOT provides an easy way to install different versions of ROOT and Python (it looks like it is really close to working but not quite there yet).

Hi @wsha2

Yes, the ROOT conda package just made it to Conda Forge, that could definitely make your life simpler if you already are a user of conda.

Please let us know if we can help you with anything else.

Cheers,

Enric

I played around with compiling PyROOT.

I tried tinkering with the cmake configuration files, but I am not very familiar with cmake, so I didn’t have much success: several cmake files need to be loaded to define the necessary macros and variables for PyROOT but loading those files activated other dependencies that I didn’t want to build. This happened even though I tried to point cmake at a pre-compiled distribution of ROOT, probably because cmake wanted some intermediate build components to be present.

I also tried running cmake on the full source distribution and then editing the Makefile content that that produced. With this approach, I was able to put together a Makefile file that could be put in the bindings/pyroot directory of the source distribution and produce a working libPyROOT.so without compiling any other components (using a version of ROOT compiled separately).

My Makefile is below if anyone is interested to see it. I have a lot of Python experience but not so much C++, so I would appreciate any feedback on the format of the Makefile. In particular, I am not sure how universal the g++ flags are – those are what cmake put in for me but maybe they are platform specific and should be only added conditionally. That said, I was able to use this Makefile to compile libPyROOT.so for the conda version of Python 3.7 using the distribution of ROOT compiled for Fedora on the download page which had libPyROOT.so compiled for Python 2.7. I was also able to compile libPyROOT.so for Python 3.7 on CentOS 6, using a build of ROOT originally compiled for Python 3.6.

I thought about creating a setup.py file, but I have not done that so far. I think it would have to call out for an external command to do the rootcling step. Since I am not sure about the g++ flags, I am not sure if a setup.py file could handle the rest of the build process on its own if all the paths were set appropriately.

If you want to see the exact steps I took, you can look at this git repository where I have the Makefile and some scripts to set up ROOT in a container to test compiling PyROOT. Since this forum topic will be closed after a period of inactivity, any feedback about the Makefile could also be posted in an issue on that repo.

PYTHON_VERSION = $(shell python -V 2>&1 | sed -E 's/Python ([0-9]+\.[0-9]+).*/\1/')
PYTHON_INCLUDE_DIR ?= ${CONDA_PREFIX}/include/python${PYTHON_VERSION}m
PYTHON_LIBRARY_DIR ?= ${CONDA_PREFIX}/lib

default: libPyROOT.so

src/G__PyROOT.cxx:
	ROOTIGNOREPREFIX=1 rootcling -rootbuild -v2 -f src/G__PyROOT.cxx -s libPyROOT.so -m libCore_rdict.pcm -m libMathCore_rdict.pcm -m libNet_rdict.pcm -m libTree_rdict.pcm -m libRint_rdict.pcm -excludePath inc -rml libPyROOT.so -rmf libPyROOT.rootmap -writeEmptyRootPCM -I${ROOTSYS}/include -I${PYTHON_INCLUDE_DIR} TPyArg.h TPyDispatcher.h TPyException.h TPyFitFunction.h TPyROOTApplication.h TPyReturn.h TPySelector.h TPython.h inc/LinkDef.h

%.o: src/%.cxx
	g++ -fPIC -std=c++11 -I${ROOTSYS}/include -I${PYTHON_INCLUDE_DIR} -o $@ -c $<

G__PyROOT.o: src/G__PyROOT.cxx
	g++ -fPIC -std=c++11 -I${ROOTSYS}/include -I${PYTHON_INCLUDE_DIR} -o $@ -c $<

pyroot_objects: $(addsuffix .o, $(basename $(notdir $(wildcard src/*.cxx))))
pyroot_objects: G__PyROOT.o

libPyROOT.so: pyroot_objects G__PyROOT.o
	g++ -fPIC  -Wno-implicit-fallthrough -Wno-noexcept-type -pipe -m64  -Wshadow -Wall -W -Woverloaded-virtual -fsigned-char -pthread -std=c++11 -fno-strict-aliasing -Wno-parentheses-equality -O3 -g -DNDEBUG  -Wl,--no-undefined -shared -Wl,-soname,libPyROOT.so -o libPyROOT.so *.o -L${ROOTSYS}/lib -Wl,-rpath,${PYTHON_LIBRARY_DIR} ${PYTHON_LIBRARY_DIR}/libpython${PYTHON_VERSION}m.so ${ROOTSYS}/lib/libRint.so ${ROOTSYS}/lib/libROOTDataFrame.so ${ROOTSYS}/lib/libROOTVecOps.so -lvdt ${ROOTSYS}/lib/libTreePlayer.so ${ROOTSYS}/lib/libTree.so ${ROOTSYS}/lib/libGraf3d.so ${ROOTSYS}/lib/libGpad.so ${ROOTSYS}/lib/libGraf.so ${ROOTSYS}/lib/libMultiProc.so ${ROOTSYS}/lib/libNet.so ${ROOTSYS}/lib/libHist.so ${ROOTSYS}/lib/libRIO.so ${ROOTSYS}/lib/libMatrix.so ${ROOTSYS}/lib/libMathCore.so ${ROOTSYS}/lib/libImt.so ${ROOTSYS}/lib/libThread.so ${ROOTSYS}/lib/libCore.so 

clean:
	rm -f *.o libPyROOT.so src/G__PyROOT.cxx *.cpm *.rootmap

.PHONY: default pyroot_objects clean

Hi @wsha2,

Thank you for sharing your solution! Just an observation, the dependencies of libPyROOT are Core, MathCore, ROOTVecOps and Tree.

Cheers,
Enric

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.