Custom Nix Shell
Python
Example is forked from Setting up a Python development environment, having the following app myapp.py
:
#!/usr/bin/env python
import random
import subprocess
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
result = subprocess.run(
["cowsay", random.choice(["Nix rules!"] * 6 + ["Nix sucks!"])],
capture_output=True,
)
result.check_returncode()
return {"message": result.stdout.decode()}
def run():
app.run(host="0.0.0.0", port=5000)
if __name__ == "__main__":
run()
Let's create an evironment with app dependencies + extra developer tools, named myapp.nix
:
{ pkgs ? import <nixpkgs> { } }:
pkgs.mkShell {
packages = with pkgs; [
(python3.withPackages (ps: [ ps.flask ]))
curl
jq
cowsay
];
}
Enter the shell and run the app:
nix-shell myapp.nix
python ./myapp.py &
curl 127.0.0.1:5000 | jq -r '.message'
C++
Let's run the Boost Python hello world, filename boost.cc
:
#include <boost/python.hpp>
char const* greet()
{
return "hello, world";
}
BOOST_PYTHON_MODULE(hello_ext)
{
boost::python::def("greet", greet);
}
Standard CMakeLists.txt
file:
cmake_minimum_required(VERSION 3.5)
project(BoostPythonHello)
find_package(Python 3 REQUIRED COMPONENTS Development)
find_package(Boost COMPONENTS python REQUIRED)
set(CMAKE_SHARED_MODULE_PREFIX "")
add_library(hello_ext MODULE boost.cc)
target_link_libraries(hello_ext PRIVATE Boost::python Python::Module)
Nix environment boost.nix
, notice that we override the default boost package options to get python support:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
packages = with pkgs;
let
myPython = python3.withPackages (ps: [ ps.matplotlib ps.numpy ]);
in
[
(boost.override {
enablePython = true;
enableNumpy = true;
python = myPython;
})
myPython
cmake
];
}
Build and run:
nix-shell boost.nix
cmake -S . -B build
cmake --build build
cd build
python3
>>> import hello_ext
>>> hello_ext.greet()
'hello, world'