-
Notifications
You must be signed in to change notification settings - Fork 1
Developer Notes
Here I will document my steps to prepare a development evironment for the Sciencetools with an eye towards releasing a new version of the conda Fermitools package.
This meta-package of the user-facing Fermi ScienceTools employs git submodules to link to component packages. A git submodule is another git repository which is linked to by this repository. To also fetch these submodules on clone run:
git clone --recurse-submodules -j8 [email protected]:fermi-lat/ScienceTools.git
The --recurse-submodules -j8
flag tells git to also get the attached submodules and do so in parallel with 8 jobs. The repo url [email protected]:fermi-lat/ScienceTools.git
uses an ssh protocol checkout which requires you as a developer to setup ssh keys with github in advance.
If you have cloned the top level repo already you can also grab all the submodule repositories with this command from within the ScienceTools directory:
git submodule update --init .
Submodules defined here are checked out as detached HEAD repositories under ScienceTools/src/
, To reattach their heads efficiently, cd to ScienceTools and execute:
git submodule foreach 'git checkout master ||:'
To make the submodules all use the ssh git protocol:
git submodule foreach 'git remote -v set-url origin [email protected]:fermi-lat/$(basename $(pwd)).git ||:'
Pull and merge any upstream changes, this is probably more useful later on.
git submodule update --remote --merge --init
Note: It is possible to update the Sciencetools repo to use the git ssh protocol by default for submodules for all users. Please do not commit such a change; It will prevent future users who do not have git ssh keys set-up from cloning the submodules. This also holds for the CI pipeline.
With a fully set up conda installation you can install the needed development dependencies
for your operating system from the provided conda environment files in ScienceTools/environments/
.
For example on linux:
conda env create -n fermi-dev -f environments/fermitools-develop-linux.yml
conda activate fermi-dev
Caveat for pyenv virtualenv.
It's possible to run `conda` from within a pyenv virtual environment and still compile the fermitools. However the CMake path resolver has difficulty with multiple levels of virtual environment activation, such as having both a pyenv virtualenv and a conda env active simultaneously. This can be overcome by only using the pyenv virtualenv feature. In this case the environment creation and activation steps are as follows.pyenv activate miniconda3-latest
conda env create -n fermi-dev -f environments/fermitools-develop-linux.yml
pyenv activate miniconda3-latest/envs/fermi-dev
conda activate fermi-dev
Build-only dependencies.
System specific environment files also exist for just building the tools, but neither running nor testing them once built.conda env create -n fermi-build -f environments/fermitools-build-linux-x86.yml
conda activate fermi-build
Generating dependency environment files.
A new environment file candidate can be created from the command line. I say candidate because the YAML needs to me modified to actually be installable. You need to remove the 'prefix:' seciton and probably add a '-fermi' to the channel list.conda env export -n fermi-build --from-history > environments/fermitools-build.yml
The Fermitools has moved to using CMAKE for its build system. When paired with conda for dependency package management this provides robust and well-supported system for cross-compiling the tools on differing host and target systems.
The build process is split into two steps. Generation is similar to a configure
step;
The host system is polled for needed attributes, programs, and libraries and a Makefile
system is created. The Build stage then executes the generated Makefile system to
compile all the Fermitools targets.
Assuming your dependencies are installed and system compilers are all in the local
$PATH
you can generate a build system by executing the following command from within
the ScienceTools directory:
cmake -S . \
-B RelWithDebInfo \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_INSTALL_PREFIX="</install/destination/path>" \
-DCMAKE_PREFIX_PATH="</dependency/search/path/>"
If your CMAKE_INSTALL_PREFIX
is the location of your dependencies you can optionally
exclude CMAKE_PREFIX_PATH
. I recommend specifying -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX
.
Other useful CMake flags.
TODO: Flesh out useful flags.-
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
: output a compile_commands.json file in the build tree. Useful for LSP programs like clangd. -
--graphviz "<dir/prefix_string>"
: generatedot
files plotting the dependency graphs of the CMake targets. - Sanitizer flags.
-
-G Ninja
Use the Ninja build system, or some other build system generator.
This locates needed dependencies and prepares a release build with debug symbols in the 'RelWithDebInfo' directory. To compile the tools now run:
cmake --build RelWithDebInfo --parallel
You can install the tools in your CMAKE_INSTALL_PREFIX
with
cmake --build RelWithDebInfo --parallel --target=install
The Fermitools relies on a properly setup shell environment to populate needed path
information for certain directories, like CALDB. In a conda build this is handled by the activate
function, but as a developer working locally you can instead source the provided
scripts/activate.sh
. Simply source that file with the argument for your build
directory like so:
source scripts/activate.sh RelWithDebInfo
This populates your environment with variables determined relative to your CMAKE_INSTALL_PREFIX
, including PATH
You can now run your compiled code!
To publish commits in a submodule and have it tracked by the Sciencetools you need to add the commit and push it in the submodule, then cd
to ScienceTools and commit and push the new changes there too. This way, ScienceTools knows that it needs the submodule to track the new SHA, rather than the old one that it's already tracking. A git status
in ScienceTools will let you know if your submodule changes are out-of-sync with what the ScienceTools is meant to track.
If you do not commit and push new tracking changes for ScienceTools submodules, later git clone
attempts to pull the tools won't track your changes, even if they're on your target branch. To learn more about git submodule see here: https://git-scm.com/book/en/v2/Git-Tools-Submodules
Hurray!
Let's add modelEditor as a submodule be sure to use the https protocol so members of the public and the CI pipeline can checkout the code too:
git submodule add https://github.com/fermi-lat/modelEditor.git src/modelEditor
Next let's add a new branch to modelEditor and push it back to github.
cd src/modelEditor
git checkout -b cmake-update
Next we edit modelEditor and push some commits.
<software engineering goes here>
<git commit stuff>
Make the local git protocoal ssh and push the new branch back to github.
git remote -v set-url origin [email protected]:fermi-lat/modelEditor.git
git push --set-upstream origin cmake-update
Let's set the ScienceTools repo to track the cmake-update
branch of modelEditor.
cd ../../
git submodule set-branch --branch cmake-update src/modelEditor
Now let's push all the submodule changes and our top-level changes to ScienceTools
git commit -am "Add modelEditor"
git push --recurse-submodules=on-demand
CMake Error: Could NOT find Python3 (missing: Python3_NumPy_INCLUDE_DIRS NumPy) (found suitable version "3.12.5", minimum required is "3.7")
This annoying issue crops up sometimes with conda not reading implicit values in the environment correctly.
One way to fix it is to manually set the numpy and python paths with the following cmake options.
-DPython3_NumPy_INCLUDE_DIRS=$(python -c "import numpy; print(numpy.get_include())")
-DPython3_EXECUTABLE=$(which python)
so a full command might look like
$ cmake -S . \
-B Release \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DPython3_NumPy_INCLUDE_DIRS=$(python -c "import numpy; print(numpy.get_include())") \
-DPython3_EXECUTABLE=$(which python) \
-G Ninja