
TABLE OF CONTENTS
-----------------
- [C-library](#c-library)
- [Julia](#julia)
- [Python](#python)
- [R-library](#r-library)
- [Build wheels](#build-wheels)
- [Normal testing](#normal-testing)
- [Benchmarking](#benchmarking)
- [Extra Testing](#extra-testing)
- [TestU01](#testu01)
- [PractRand](#practrand)

## C-LIBRARY
### Meson setup:
    scripts/meson-setup.sh release                     # optimized (default buildtype)
    scripts/meson-setup.sh debug --buildtype=debug     # debug-enabled
    CC=<C-compiler> scripts/meson-setup.sh <builddir>  # optional compiler override
    = these set library "prefix" to install/
    = an existing builddir is removed first

### Build:
    ninja -C release
    ninja -C debug

### Install:
    ninja -C release install    # used for Julia and Fortran
                                # (copies library to ./install)
    release/examples/RunRandom  # simple example program

## ALL SUBPROJECTS
    scripts/set_version.sh      # sets version number across all the language interfaces
    build-all.sh                # rebuilds all language interfaces

## JULIA
### First time setup:
    cd Randompack.jl           # the Julia package folder
    rm Manifest.toml           # needed e.g. after changing Julia version
    export JULIA_PROJECT=.     # use environment defined by ./Project.toml
    julia                      # run Julia
    julia> ] instantiate       # install project dependencies (once per Julia version) (1)

### After change to C library:
    Make sure to run "ninja -C release install" and restart Julia

### Use:
    export JULIA_PROJECT=.     # needed in a new shell (2)
    julia examples/TimeDist.jl # run timing program
    julia                      # run julia
    julia> using Randompack    # load into current session

    TO UPDATE JULIA
    juliaup add 1.13           # install Julia version 1.13
    juliaup default 1.13       # and make it default (3)

    Notes:
    (1) ] enters pkg> prompt; <backspace> to go back to julia> prompt
    (2) alternatively, set JULIA_PROJECT in .bashrc/.zshrc with absolute path
    (3) or run Julia with julia +1.13

## PYTHON
    To simplify setup, the Python instructions below assume a conda environment.

### First time setup:
    cd <project-root>
    conda create -n randompack-dev python
    conda activate randompack-dev
    conda install meson meson-python ninja cython pytest numpy
    scripts/syncpy.sh
    cd python
    = optionally use clang: "CC=clang pip install -e . --no-build-isolation"
    = optionally specify Python version: "conda create -n randompack-dev python=3.12"
    to change the setup remove python/build/cp312

    AFTER CHANGE TO C LIBRARY
    cd <project-root>
    scripts/syncpy.sh
    restart python

    USE:
    (with Python running in the same environment)
    >>> import randompack
    will automatically rebuild the module after changes to C/Cython sources.

## R-LIBRARY
### Build:
    cd <project-root>                  # enter project root
    scripts/syncR.sh                   # copy C sources from src to r-package/src
    R CMD INSTALL --preclean r-package # create R library
    = do this both first-time and 
      after changes to C library; 
      then restart R

### Use:
    R                                  # start R
    > library(randompack)              # load into session

## NORMAL TESTING
    meson test -C release              # run meson defined tests for C and Fortran
    release/tests/RunTests -v          # run C tests in verbose mode
    release/tests/RunTests -h          # show help for test runner
    release/tests/RunFortranTests      # Run only the Fortran tests

    cd python
    pytest -q                          # quiet testing of the Python Randompack
    pytest                             # verbose testing

    cd <project-root>
    R CMD build r-package              # build library in randompack_<version>.tar.gz 
    R CMD check randompack_*.tar.gz    # comprehensive CRAN-style full package check
    .                                  # replace * with actual version if > 1 .tar.gz file
    cd r-package                       # enter the package folder
    R                                  # start R
    > install.packages("testthat")     # first time only
    > testthat::test_local()           # run quick testthat tests

    cd Randompack.jl                   # enter Julia folder
    export JULIA_PROJECT=.             # unless set in .zshrc/.bashrc
    julia test/runtests.jl             # run the Julia tests

## BENCHMARKING
    cd <project-root>/release/examples # enter build folder
    TimeDistributions                  # benchmark distributions with C randompack
    TimeDistFortran                    # = distributions with Fortran randompack
    TimeEngines                        # = engines with C bitstream samples
    TimeIntegers                       # = integer sampling with C

    cd <project-root>
    export JULIA_PROJECT=Randompack.jl          # if not set in .zshrc/.bashrc
    Rscript r-package/inst/examples/TimeDist.R  # compare R-randompack with base-R and Dqrng
    julia Randompack.jl/examples/TimeDist.jl    # compare Julia randompack with the built-in
    python python/examples/TimeDist.py          # compare Python-randompack with numpy.random

    release/benchmark/TimeDistributions -h     # display short help
    .                                           # the other benchmark programs also accept -h

## EXTRA TESTING
    scripts/run-test-variants.sh  # Run built-in BLAS, no128, and nosimd variants
    scripts/test-all.sh           # Run tests for all language interfaces

### TestU01:
    In some folder:
    wget http://simul.iro.umontreal.ca/testu01/TestU01.zip  # Download official TestU01
    unzip TestU01.zip                                       # = unzip it
    cd TestU01-1.2.3                                        # = and install it 
    ./configure --prefix=<prefix>                           # E.g. $HOME/lib
    make -j                                                 #
    make install                                            #
    meson setup -C release -Dbuildtype=release \            #
        -DTestU01=<prefix>                                  # or edit meson_config.txt
    cd release/examples                                     #
    TestU01Driver -h                                        # help
    TestU01Driver -c                                        # Crush (minutes)
    TestU01Driver -b                                        # BigCrush (hours)
    TestU01PIT -h                                           # help
    TestU01PIT -c                                           # PIT test normal with Crush

### PractRand:
    [This only works on x86_64 Linux]
    cd to <project-root>/misc
    Download from https://sourceforge.net/projects/pracrand/files
    unzip and enter PractRand folder
    g++ -O3 -std=c++11 -pthread -Iinclude src/*.cpp src/RNGs/*.cpp src/RNGs/other/*.cpp 
      tools/RNG_test.cpp -o ../../release/examples/RNG_test
    cd <project-root>/release/examples

    RawStream | Rng_test stdin64           # default engine, runs "forever"
    RawStream -e x128+ | Rng_test stdin64  # x128+ fails fast
    RawStream -h                           # help
    Rng_test -h                            # help

## JULIA RELEASE
    Yggdrasil (Julia):
    scripts/make-julia-tarball.sh       # create .tar.gz file with C library in archives/
    cd archives                         # clone of github.com/jonasson2/randompack-src
    – update package/build_tarballs.jl  # change version number (2x) and sha (from script)
    git commit -am "Release x.y.z"      #
    git push                            # 
    git tag vx.y.z                      # (can also use local tarball from build_tarball.jl
    git push origin vx.y.z              # push new tag
    julia build_tarballs.jl --debug                  # 
      --verbose --deploy=local                       # Check all platforms
      x86_64-linux-gnu-libgfortran5-cxx11            # locally
      [repeat for all platforms]                     #
    git clone git@github.com:jonasson2/Yggdrasil.git #
    update build_tarballs.jl in R/Randompack         # - in the clone
    git commit -m "Add Randompack -vx.y.z            #
    git push                                         # push to Yggdrasil
    gh pr create --repo JuliaPackaging/Yggdrasil \   # open pull request for a merge
         --title "Add Randompack vX.Y.Z" \           # 
         --body "New version of Randompack"          #

    For Julia General registry:
    Wait for the Yggdrasil merge
    in julia:
      ] activate Randompack.jl
      ] add Randompack_jll
      ] update
    Commit and push randompack (including Randompack.jl)
    Tag it vX.Y.Z
    Comment on the new commit on github: @JuliaRegistrator register

## PYTHON PIPY
    Create wheels:
    Bump version with set_version.sh
    commit, push, and tag randompack
    scripts/wheel-build.sh             # trigger github Actions
    gh run list                        # monitor runs
    gh run view <RUN-ID> --log-failed  # view failed log
    gh run delete <RUN-ID>             # delete run
    .                                  # wait for the actions to complete successfully
    cd python/
    python -m build -s                 # build sdist in dist/
    scripts/wheel-download.sh          # download wheels from GH Actions into dist/

    Upload to TestPyPI:
    python -m twine upload --repository testpypi dist/*     # verify on TestPyPI
    python -m venv /tmp/rp-test                             # - using a fresh venv
    source /tmp/rp-test/bin/activate                        # 
    pip install \                                           # try out the new TestPyPI version 
      --index-url https://test.pypi.org/simple \            #
      --extra-index-url https://pypi.org/simple \           #
      randompack                                            #
    python -c "import randompack; print(randompack.Rng())"  #
    deactivate                                              # exit the venv

    Upload to PyPI:
    python -m twine upload dist/*   # real upload
    pip install randompack          # try it out

    More wheel commands:
    gh workflow list
    gh workflow run xxx.yml  # trigger wheel building
    gh run watch
    gh run list --json databaseId --jq '.[].databaseId'  # just the ids, use in foreach...

## CRAN SUBMISSION
    scripts/syncR.sh

    From r-package:
    R -e "devtools::document()"            # Creates man docs
    R -e "devtools::build_readme()"        # Creates README.md from README.Rmd
    R -e "devtools::check_win_devel()"     # offline-check of Windows
    R -e "devtools::check_win_release()"   # do.

    From project root:
    R CMD build r-package
    R CMD check randompack_*.tar.gz
    R CMD check --as-cran randompack_*.gz  # complete checking
                                           # edit cran-comments.md with results

## CONDA-FORGE
    When the version is bumped and a version tag pushed, a pull request (PR) is
    usually created within a few hours on:
       https://github.com/conda-forge/randompack-feedstock. 
    If it doesn't appear:
       edit recipe/meta.yaml on that page:
       version: x.y.z
       sha256: <new-sha>
    GitHub should guide one into opening a PR (perhaps one needs to choose:
    "Create a new branch for this commit and start a pull request") After the PR
    is created automatic testing of Randompack is carried out. If all the tests
    pass the changes the PR is "merged" either automatically or be a conda-forge
    maintainer, and following that the new release will be automatically
    installed on conda-forge.
    #
    To obtain the new sha use:
       curl -L -o randompack-0.1.6.tar.gz \
       https://github.com/jonasson2/randompack/archive/refs/tags/v0.1.6.tar.gz
    shasum -a 256 randompack-0.1.6.tar.gz

DEBIAN:
  1. work in:
     - /home/jonasson/randompack-debian-clean
  2. if needed, regenerate the upstream tarball from origin/main:

     rm -f ../randompack_0.1.5.orig.tar.xz
     git archive --format=tar --prefix=randompack-0.1.5/ origin/main | \
       xz -T0 > ../randompack_0.1.5.orig.tar.xz
  3. build binary package:

     DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -us -uc -b
  4. build source package:

     dpkg-buildpackage -S -us -uc
  5. lint source upload:

     lintian --profile debian ../randompack_0.1.5-1_source.changes
