How to install c++ program into conda environment from source

Viewed 607

I would like to compile and then use the scientific project BASS, which is distributed as c++ source code on github. I've set up a conda environment bass to hold everything related to BASS, and I'd like to compile BASS into this environment (so that if I delete the environment, it's cleanly removed).

I don't know if I should be using conda-build or make to do this. There is a Makefile distributed with the project, but I think it might have an error.

My latest try is the following: (the source files are in code/ and gsl seems to be a dependency):

conda create -n bass
conda activate bass
conda install make
conda install gsl
cd code/  
make

I get the following:

gcc -c main.cpp -I../Libs/GSL/include/ -I./
main.cpp:19:10: fatal error: 'gsl/gsl_statistics.h' file not found
#include <gsl/gsl_statistics.h>
         ^~~~~~~~~~~~~~~~~~~~~~
1 error generated.
make: *** [Makefile:11: main.o] Error 1

My questions:

  • should I be doing this with make?
  • do I need gcc/g++/cxx-compiler installed in my conda env?
  • is the Makefile correct where it says "-I../Libs/GSL/include/"

Thank you!

2 Answers

Here's a very basic Conda recipe for the package. Make a folder (say recipe) and put the following two files in it:

meta.yaml

package:
  name: bass
  version: 0.1  # this is totally arbitrary (there are no versions)

source:
  git_url: https://github.com/judyboon/BASS.git

requirements:
  build:
    - {{ compiler('cxx') }}
  host:
    - gsl
  run:
    - gsl

about:
  home: https://github.com/judyboon/BASS
  license: GPL-3.0-only
  license_file: COPYING
  license_family: GPL

build.sh

#!/bin/bash                                                                                                                                                                                                                                   

## change to source dir                                                                                                                                                                                                                       
cd ${SRC_DIR}/code

## compile                                                                                                                                                                                                                                    
${CXX} -c main.cpp *.cpp -I./ ${CXXFLAGS}

## link                                                                                                                                                                                                                                       
${CXX} *.o -o BASS -lgsl -lgslcblas -lm ${LDFLAGS}

## install                                                                                                                                                                                                                                    
mkdir -p $PREFIX/bin
cp BASS ${PREFIX}/bin/BASS

You can then build this with conda build ., run from in that directory.

Installing

After successful build, you can create an environment with this package installed using

conda create -n foo --use-local bass

Since I'm on an Intel architecture, and this tool uses CBLAS, I would further specify to use MKL:

conda create -n foo --use-local bass blas=*=*mkl

Now if you activate the environment foo (that's an arbitrary name), the software will be on PATH, under the binary BASS.


Additional Notes

I verified this works on osx-64 platform with the conda-forge channel prioritized.

The Makefile accompanying the code isn't very generic. Here we just have it compile all .cpp files and subsequently link all .o files.

There aren't any releases on the repository, so the versioning in the meta.yaml is arbitrary.

The build.sh defines the final output binary as BASS - that could be changed, and differs from the original Makefile which outputs the binary as main.

Based on what you write, the correct way is to build a conda recipe. By writing a recipe the conda knows what to delete, when you delete the environment.

The recipe is a text file (the meta.yaml file), where you write some metadata describing the package, define dependencies and write a short build script that executes the make file and installs the binaries to correct location. Defining the compilation environment may not be trivial and you should follow the documentation for the package you are trying to install. If there are problems with the package code (that includes the makefile) that's something conda can't help you with.

See the documentation on how to write the recipe: https://docs.conda.io/projects/conda-build/en/latest/concepts/recipe.html

When you've got the recipe complete, then you would run the conda build and conda install -c [path to the build] [the package name] (I'm writing this because it took me ages to realize how to correctly install a local package.)

Related