Issues in building AFNI from source for a container

Hello,

I hope I didn’t miss a documentation page or a message in this board in starting this thread.

I’m trying to install a fixed version of AFNI in a container (apptainer), so that no matter when and where I run my analysis, it doesn’t change. The apptainer contains other software too, and it’s based on ubuntu 20.04.
I tried to use neurodocker, but I encountered a couple of issues and limitations that made it not the best option for me (although I’m thinking about contributing to it once I solve my current issues). Equally, basing my container on AFNI’s dockerimage is not an option.

At first, I tried to install AFNI through the binaries, but I’m missing how to install a precise version using @update.afni.binaries, so I decided to go for the (painful) way of cloning from source.

Premise: I’m not so familiar with building from source, my experience comes mainly from building ANTs over and over.
I created the symlinks for libgsl, libXmu, and libXp.
I git cloned the repository on Github, copied the

Makefile.linux_ubuntu_16_64 file

as

Makefile

(to use it, if I understood correctly), set CC and CXX, and run

cmake
make
make install

That worked well, but then I realised most of the programs I needed (mainly, those based in R like 3dICC and 3dLMER) where missing. I’m also not sure I installed SUMA, as calling SUMA_paperplane I get:

SUMA_paperplane: error while loading shared libraries: libSUMA.so: cannot open shared object file: No such file or directory

On top of that, cmake states:

Comparison with build using the make system: programs not built: 'model_conv_PRF_6_BAD;3dBallMatch;3dCompareAffine;3dDiff;3dEdu_01_scale;3dmaxdisp;cifti_tool;cjpeg;djpeg;imcat;SurfLocalstat'

I then tried to follow the instructions in github, but (probably obviously, but not to me) running

cmake
make vastness

didn’t work. Instead, I copied again Makefile.linux_ubuntu_16_64 as Makefile, and used

make vastness

. This resulted in a bunch of errors like:

gcc: error: backspace.o: No such file or directory

and:

make[1]: *** [Makefile:39: libf2c.so] Error 1
make[1]: Leaving directory '/tmp/general_preproc_build_2023-01-05_12-39-30/source2/src/f2c'
/bin/mv: cannot stat 'libf2c.so': No such file or directory
make: *** [Makefile.INCLUDE:3073: libf2c.so] Error 1

I tried again what neurodocker does:

cp Makefile.linux_openmp_64 Makefile
perl -p -i -e 's/^LGIFTI.*/LGIFTI    = -lexpat/' Makefile
perl -p -i -e 's/^USE_LOCAL_X_TREE/#USE_LOCAL_X_TREE/' Makefile
perl -p -i -e 's/XLIBS = \$\(XROOT\)\/lib64\/libXm.a -lXt/XLIBS = \$\(XROOT\)\/lib64\/libXm.a \$\(XROOT\)\/lib\/x86_64-linux-gnu\/libXm.a -lXt/' Makefile
perl -p -i -e 's/^# XLIBS =/XLIBS =/' Makefile
perl -p -i -e 's/^CCOLD.*/CCOLD  = \$\(CC\)/' Makefile
perl -p -i -e 's/(^LFLAGS.*)/$1 -L\/usr\/lib\/x86_64-linux-gnu/' Makefile
perl -p -i -e 's/(^PLFLAGS.*)/$1 -L\/usr\/lib -L\/usr\/lib\/x86_64-linux-gnu/' Makefile
perl -p -i -e 's/-lXpm -lXext/-lXpm -lfontconfig -lXext/' Makefile
perl -p -i -e 's/(^SUMA_INCLUDE_PATH.*)/$1 -I\/usr\/lib\/x86_64-linux-gnu\/glib-2.0\/include/' Makefile

make INSTALLDIR="/opt/afni-latest" vastness

This gave me the following error (which was the reason I didn’t use neurodocker):


SUMA_Makefile:33: *** Recursive variable 'CC' references itself (eventually).  Stop.
make[1]: Leaving directory '/tmp/general_preproc_build_2023-01-05_12-39-30/source2/src/SUMA'
/bin/cp: cannot stat 'SUMA/libgts.a': No such file or directory
/bin/cp: cannot stat 'SUMA/libgts.a': No such file or directory
make: *** [Makefile.INCLUDE:3833: libgts.a] Error 1

Finally, I tried one last time declaring the R path (if I’m not mistaken) in cmake, doing:


ln -s /usr/lib/x86_64-linux-gnu/libgsl.so.23 /usr/lib/x86_64-linux-gnu/libgsl.so.19
ln -s /usr/lib/x86_64-linux-gnu/libXmu.so.6 /usr/lib/x86_64-linux-gnu/libXmu.so
ln -s /usr/lib/x86_64-linux-gnu/libXp.so.6 /usr/lib/x86_64-linux-gnu/libXp.so
git clone https://github.com/afni/afni.git source
cd source || exit 1
git fetch --tags
git -c advice.detachedHead=false checkout AFNI_22.3.07
cp src/Makefile.linux_ubuntu_16_64 src/Makefile
export CC=$( which gcc )
export CXX=$( which g++ )
cmake -DCMAKE_INSTALL_RPATH='/usr/lib' .
make -j20
make install

I’m still missing 3dICC, 3dLMEr, and rPkgsinstall.
At this point, I’m a bit lost. What am I missing? Why I am not compiling the programs related to R?

I’m sorry if I’m not clear enough in reporting the steps, but I’m happy to write more and attach files, if needed.

Cheers,
Stefano

Hi Stefano,

For compiling on a clean Ubuntu 20.04 system from a clean afni/src directory, I would expect it to be enough to:

install needed build packages

bash afni/src/other_builds/OS_notes.linux_ubuntu_20_64

and build

cd afni/src
cp afni/src/other_builds/Makefile.linux_ubuntu_16_64_glw_local_shared Makefile
make itall 2>&1 | tee out.make.txt

For nicities, install the packages in afni/src/other_builds/OS_notes.linux_ubuntu_[abc]* .
Note that python-is-python3 might be important for running.

Give that a try.

  • rick

Adding a tiny bit more to Rick’s usual sage advice, R should be installed first before the build.

Hi Rick, Daniel,

thank you both for your insight on the issue!
RE R installation: R was installed already before I started anything. Is there any environment variable I should set for the source build to know where to find it?
R (the environment call) is in /usr/bin, my R folder is in /usr/lib (/usr/lib/R is the R folder with its lib and modules subfolders). In one of my attempts I set cmake to point to /usr/lib, but didn’t seem to change anything (maybe because I didn’t understand the use of the variable):

cmake -DCMAKE_INSTALL_RPATH='/usr/lib'

Rick, I tried what you suggested, but it didn’t work. Of note, all of the listed packages in other_builds/OS_notes.linux_ubuntu_20_64 were already installed. I then proceeded to do:


cp other_builds/Makefile.linux_ubuntu_16_64_glw_local_shared Makefile
make -j20 itall 2>&1 | tee out.make.txt
make install

But the final make returned again:


SUMA_Makefile:33: *** Recursive variable 'CC' references itself (eventually).  Stop.
make[1]: Leaving directory '/tmp/general_preproc_build_2023-01-05_21-18-44/afni/source/src/SUMA'
/bin/cp: cannot stat 'SUMA/libgts.a': No such file or directory
/bin/cp: cannot stat 'SUMA/libgts.a': No such file or directory
make: *** [Makefile.INCLUDE:3833: libgts.a] Error 1

Something else I could try?

Stefano

Hi, Stefano-

Does running make without the parallel jobs:


make itall 2>&1 | tee out.make.txt

work? I wonder if the Makefile is not setup necessarily for parallelized building. I have never run with that “-j …” option.

–pt

The way the make files are set up, I think that you should not initialize CC via an environment variable like you are probably prone to doing with cmake.

I will have to revisit that, but try clearing CC (in your env) before the make.

Thanks,

  • rick

There is also a small issue with the -j option. The make doesn’t quite parallelize, but it usually works the second time through. Anyway, I’d skip that for this test.

Hi everyone,
thank you for all of your feedback!

It looks like I finally managed to compile it from source!
I unset CC and CXX, and run make itall without parallel jobs (pity, cause it takes a while, but it works!)
I also run rPkgsInstall, specifying R_LIBS as the folder where I installed R system-wise (/usr/lib/R in my case).
I didn’t run a formal test, but R-based programs like 3dICC are now available and not angrily protesting missing R libraries!

Is this the suggested way to build AFNI? Should I check again neurodocker’s installation, or make vastness is still a valid option?

Thank you for the help!
Cheers,
Stefano

Hi, Stefano-

I generally use “make vastness” when I build, indeed.

Have you run:


afni_system_check.py -check_all

to check your AFNI setup on that system? That would be the best way to verify things.

–pt

Actually, “make vastness” is identical to “make itall”, and was presumably added without the author realizing that that particular target list already existed.
And ‘totality’ does that same thing as well, but also does cleaning on both ends.

Yes, that is how we generally build, without any parallelization. Parallelized cmake is only used as one of the circleci tests, I believe.

  • rick