Hello, I have to use criterion for unit test.
I have this in my Makefile
CC = gcc
CFLAGS = -Wall -Wextra -Werror -std=gnu17 -g -I./include
OBJ = my_alloc.o
all: ${OBJ}
test ${OBJ}: test.o
${CC} -L./lib -lcriterion -o test test.o my_alloc.o
./test
clean:
$(RM) *.o .*.swp .*.swo
distclean: clean
$(RM) test
.PHONY: all clean distclean test
in my usual linux I use this command inside include/ to symlink include with criterion
include$ ln -s /usr/local/include/criterion
include$ ll
total 16
drwxr-xr-x 2 lol users 4096 May 3 13:15 ./
drwxr-xr-x 4 lol users 4096 May 3 15:30 ../
lrwxrwxrwx 1 lol lol 28 May 3 12:18 criterion -> /usr/local/include/criterion
-rw-r--r-- 1 lol users 98 Apr 29 14:57 my_alloc.h
-rw-r--r-- 1 lol users 291 May 3 13:15 my_alloc.private.h
and now on Nixos I got this error with criterion installed:
sgcc -L./lib -lcriterion -o test test.o my_alloc.o
/nix/store/vj57s3h2za2qrfccrvc9b6i7s8mw3ndn-binutils-2.41/bin/ld: cannot find crt1.o: No such file or directory
/nix/store/vj57s3h2za2qrfccrvc9b6i7s8mw3ndn-binutils-2.41/bin/ld: cannot find crti.o: No such file or directory
/nix/store/vj57s3h2za2qrfccrvc9b6i7s8mw3ndn-binutils-2.41/bin/ld: cannot find -lcriterion: No such file or directory
/nix/store/vj57s3h2za2qrfccrvc9b6i7s8mw3ndn-binutils-2.41/bin/ld: cannot find my_alloc.o: No such file or directory
/nix/store/vj57s3h2za2qrfccrvc9b6i7s8mw3ndn-binutils-2.41/bin/ld: cannot find -lgcc_s: No such file or directory
collect2: error: ld returned 1 exit status
make: *** [Makefile:8: test] Error 1
how I can translate it in Nixos?
thank you in advance!
Nix’s approach is quite different from other OSs. I think a small example might illustrate the first steps to take. (Or at least give you something to work with, or maybe some more specific things to ask questions about).
With a simple test using criterion in test.c
:
#include <string.h>
#include <criterion/criterion.h>
Test(sample, test) {
cr_expect(strlen("Test") == 4, "Expected \"Test\" to have a length of 4.");
cr_expect(strlen("Hello") == 4, "This will always fail, why did I add this?");
cr_assert(strlen("") == 0);
}
and a simple Makefile (some discussion below):
CFLAGS=-g -Wall -Wextra `pkg-config --cflags criterion`
LDFLAGS=`pkg-config --libs criterion`
test:
gcc ${CFLAGS} -o test test.c ${LDFLAGS}
./test
The nix-specific part can be done with a shell.nix
:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = [ pkgs.pkg-config pkgs.criterion ];
}
Here, we’re using the criterion
provided by nixpkgs. (If you need a specific version, there are ways of achieving that). The shell.nix
file declares what dependencies we need for the project.
The compiler needs to know where to find the headers, where to look for the libraries, and what libraries to link against. The pkg-config
commands in the Makefile
provide that information.
With those files in the same directory, you should be able to enter the nix-shell with nix-shell
, then run make test
.
2 Likes
hello, thank you for taking the time to answer!
nix-shell is something that I would like to understand better. for example if I have several projects on different languages, how to create separate nix shells for each project?
The shell.nix
is pretty much intended to provide a shell with the tools/dependencies for some project. Kinda like the VSCode devcontainers, but without using containers. So, ideally, you have a shell.nix
in each project. (With direnv, it can even load the shell automatically).
The contents of the shell.nix
might vary a bit by language.
Some links for further reading:
This tutorial from nix.dev:
https://nix.dev/tutorials/first-steps/declarative-shell
Searching whatever language you’re interested in on the NixOS wiki:
https://wiki.nixos.org/wiki/NixOS_Wiki
1 Like