How to force Nix to "install packages" by building them locally instead of downloading a pre-built binary? - nix

By "install packages" I mean to evaluate Nix build expressions (using nix-env, nix-shell -p, etc.) to build from source instead of using a substitute.
Also cross-posted to Unix& Linux because, as Charles Duffy pointed out, it is more on topic if it is about command-line tools or configuration. Still leaving this here because I assume forcing a package to always compile from source is possible by only using the Nix language, I just don't yet know how. (Or if it is in fact not possible, someone will point it out, and then this question does belong here.)

Either set the substitute option to false in nix.conf (the default is true) or use --option substitute false when invoking a Nix command.
nix-env --options substitute false -i hello
nix-shell --options substitute false -p hello
Might not be the droids you are looking for
As Robert Hensing (comment, chat), Henri Menke (comment), and Vladimír Čunát (comment) pointed out, this may not be the thing that you are really after.
To elaborate: I have been using the most basic Nix features confidently, but got to a point where I need to maintain and deploy a custom fork of a large application written in C, which is quite intimidating at the outset.
Tried to attack the problem the simplest way to just fetch my fork and re-build it with the new source, so I boiled it down to this question. Although, I suspect that the right direction for me is something along the lines of Nixpkgs/Create and debug packages in the NixOS Wiki.
Only re-build the package itself
Vladimír Čunát commented that "disabling substitutes makes you rebuild everything that's missing locally, even though I suspect that people asking such a question often only want to rebuild the specified package itself."
(This is probably achieved with nix-build or "just" overriding the original package but could be wrong. The latter is mention (maybe demonstrated even?) in the NixOS wiki article Development environment with nix-shell but haven't been able to read it thoroughly yet.)
Test for reproducibility
One might arrive to formulating this same question if they want to make sure that subsequent builds are deterministic. As Henri Menke comments, one should use nix-build --check for that.
The --check option is easy to miss; it's not documented in man nix-build or at nix-build in the Nix manual, but at nix-store --realize because (as man nix-build explains it):
nix-build is essentially a wrapper around nix-instantiate (to
translate a high-level Nix expression to a low-level store derivation)
and nix-store --realise (to build the store derivation) [and so] all
options not listed here are passed to nix-store --realise, except
for --arg and --attr / -A which are passed to nix-instantiate.
See detailed examples in the Nix manual at 18.1. Spot-Checking Build Determinism and the next section right after it.
The relevant parts for the substitute configuration option under the nix.conf section from the Nix manual:
Name
nix.conf — Nix configuration file
Description
Nix reads settings from two configuration files:
The system-wide configuration file sysconfdir/nix/nix.conf (i.e. /etc/nix/nix.conf on most systems), or $NIX_CONF_DIR/nix.conf if NIX_CONF_DIR is set.
The user configuration file $XDG_CONFIG_HOME/nix/nix.conf, or ~/.config/nix/nix.conf if XDG_CONFIG_HOME is not set.
You can override settings on the command line using the --option flag,
e.g. --option keep-outputs false.
The following settings are currently available:
[..]
substitute
If set to true (default), Nix will use binary substitutes if available. This option can be disabled to force building from source.
(Formerly known as use-binary-caches.)
Notes
Setting substitute to false (either with --options or in nix.conf) won't recompile the package if the command issue multiple times. That is, hello above would be compiled from source the first time, and then it will access the already present store path if the command issued again.
This is where it gets fuzzy: it is clear that no recompilation takes place because unless the package's Nix build expression doesn't change, the store output hash won't change either, making the next compilation output equivalent to the previous one, hence the action would be superfluous.
So if one would do some light hacking on a package, and just wanted to try it out locally (e.g., with nix-shell) then one would have to use -I nixpkgs=a/local/nixpkgs/dir to pick up those changes - and eventually do a recompilation? Or should one use nix-build?
See also question How to nix-build again a built store path?

Related

trying to understand LD_PRELOAD and SUID/SGID with checkinstall or porg

I want to use porg in my LFS distro. It's similar to checkinstall, it uses LD_PRELOAD.
1. If you read the README:
CheckInstall currently is unable to track any file system changes made
by statically linked programs
I think it refers to the commands like mkdir, mv, ln, etc. So I should not have any problems with this. Am I right?
2. Then, the main problem:
NOTE ON SUID/SGID PROGRAMS: CheckInstall can't track their actions
because of some limitations in the LD_PRELOAD system that
installwatch uses. This is good for security reasons, but it can
generate unexpected results when the installation process uses
SUID/SGID binaries.
What does it mean? I don't care if I lose track of some files. I do care if there will be unexpected results, or if I can't install correctly the package.
Also, how many packages have this problem?
In case coreutils (mkdir, mv, etc. ) on your system are statically linked (i.e. running file on them reports "statically linked") porg will not be able to track their operations and thus some installed files may go untracked. Statically linked executables are second-class citizens in Linux and LD_PRELOAD does not support them.
Setuid executables indeed sanitize LD_PRELOAD before usage - they ignore all files which have slashes in name (so that only files from standard system paths can be loaded) and also require that shared library itself has setuid bit set. So in your case you'll need to locate porg's preloaded library and set setuid bit on it (via chmod a+s libxyz.so). BTW it may make sense to ask porg authors to do this change in their distro. I don't think this will cause any problems in a typical package as installers typically don't need to run setuid programs (like mount, passwd, sudo).

Nix how to use alternative store path for CI caching

Many CI providers give you a directory whose contents are retained across builds and you can use that as a cache. Everything that is stored elsewhere is lost. This means that any artefacts that are created during a nix-build that are placed in the nix store (/nix/store) are lost. I'm trying to figure out how to convince nix to prefer that other cache directory over the global /nix/store. However the documentation is a bit lacking.
What I've tried so far:
Add file:///the/path to substituters and then nix copy --to that path. However I discovered that nix only creates some metadata files in that directory and copies the actual derivation into /nix/store. That's not what I want.
Use local?root=/the/path instead of the file:// url (btw, this syntax is not documented anywhere, I only found it in a single github issue!). That made nix copy the whole derivation to that folder, but I couldn't figure out how to convince nix-build to actually consult that store during build.
Would it be possible to use something along the lines of nix run --store ~/my-nix nixpkgs.hello -c hello --greeting 'Hi everybody!'? The installation guide points to uses of --store for such a use case, as well as some sections in the manual: 1, 2.
An example of this can be found in nix run's tests.
There are also the environment variables NIX_STORE_DIR which might be of use? It's documented in nix-shell --help.
There's also several issues in the Nix repo, here's an interesting discussion.

Is there a tool for generating crosstool files for installed compilers?

Bazel use CROSSTOOL files to figure out how to builds things. This can be used to (for example) switch between GCC and Clang by setting --crosstool_top. The problem is that it's far from trivial to construct those files.
Does anyone know of any tools that can inspect a Linux installation and generate the needed crosstool files for any "common" compiler(s) that happens to be installed? Something that would be able to find and support any installed versions of Clang and GCC would be enought, any other compilers (icc, etc.) would be fantastic.
(Alternatively: are there any repo's with pre-constructed crosstool files for default installations of all the common compilers?)
Note
I've already found #bazel_tools//tools/cpp:cc_configure.bzl et al. but those seem to only generate configs for the default system compiler and I'm specifically looking for support for the non default compiler(s).
It's only a variation on cc_configure, but you can use environment variables to tweak the generation. Maybe using CC will be enough? If not, what else would you need (pull requests welcomed)?
There is no repo with premade crosstools yet, there will eventually be (maybe in the form of docker containers, we'll see) but currently there's not.

How to use Nix to setup a development environment?

Let's say I need PostgreSQL 9.6.3 and Ruby 2.3.1 and various other tools. I can't find a tutorial that explains what I need to do.
From the Nix manual, I seem to need to write a Nix expression to install the needed dependencies, but I can't make the leap from:
{ stdenv, fetchurl, perl }:
stdenv.mkDerivation {
name = "hello-2.1.1";
builder = ./builder.sh;
src = fetchurl {
url = ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz;
md5 = "70c9ccf9fac07f762c24f2df2290784d";
};
inherit perl;
}
to the expression that will install the proper PostgreSQL and Ruby versions. It is absolutely unclear to me where to even put the file that installs PostgreSQL and Ruby, or how to run a single file in a given directory.
Can someone provide pointers to such tutorials, or point me in the right direction?
You can use nix-shell for this. It drops you into a shell configured to the given nix expression. Initially that expression could simply be along the lines of buildInputs = [ pkgs.ruby ]; and you can develop it from that. There are a number of helpful articles online written by nix users that give more examples of using nix-shell, like this one from garbas.si
You may also find it useful to get a better idea of how nix packages work. There's a separate nixpkgs manual that covers in greater detail using nix to create package expressions. A quick skim of the 3rd section should be useful to give a bit more understanding. There's also a chapter on using nix with ruby bundler that might be useful for you. Again there are articles that give more examples of its use, such as one from stesie.github.io.
If you need postgresql actually running in your environment nix won't manage that for you; its function is solely the building and management of packages, not their activation. You could simply activate postgres manually, use the nix-shell hook, or create some other integration with nix, but I think the most robust option is to make use of the Linux distribution that's built on top of Nix - NixOS. NixOS integrates with nix packages and manages the services provided by the packages. You could create a NixOS configuration with postgres active and your development environment present. This utility from github.com/chrisfarms may also be of interest.

How to use luadoc in ubuntu/linux?

As the title says, how to use luadoc in ubuntu/linux? I generated documentation in windows using batch file but no success in ubuntu. Any ideas?
luadoc
Usage: /usr/bin/luadoc [options|files]
Generate documentation from files. Available options are:
-d path output directory path
-t path template directory path
-h, --help print this help and exit
--noindexpage do not generate global index page
--nofiles do not generate documentation for files
--nomodules do not generate documentation for modules
--doclet doclet_module doclet module to generate output
--taglet taglet_module taglet module to parse input code
-q, --quiet suppress all normal output
-v, --version print version information
First off, I have little experience with Luadoc, but a lot of experience with Ubuntu and Lua, so I'm basing all my points off of that knowledge and a quick install that I've just done of luadoc. Luadoc, as far as I can see, is a Lua library (so can also be used in Lua scripts as well as bash). To make documentation (in bash), you just run
luadoc file.lua
(where file is the name of your file that you want to create documentation for)
The options -d and -t are there to choose where you want to put the file and what template you want to use (which I have no clue about, I'm afraid :P). For example (for -d):
luadoc file.lua -d ~/Docs
As far as I can see, there is little else to explain about the actual options (as your code snippet explains what they do well enough).
Now, looking at the errors you obtained when running (lua5.1: ... could not open "index.html" for writing), I'd suggest a few things. One, if you compiled the source code, then you may have made a mistake somewhere, such as not installing dependencies (which I'd be surprised about, because otherwise you wouldn't have been able to make it at all). If you did, you could try getting it from the repos with
sudo apt-get install luadoc
which will install the dependencies too. This is probably the problem, as my working copy of luadoc runs fine from /usr/bin with the command
./luadoc
which means that your luadoc is odd, or you're doing something funny (which I cannot work out from what you've said). I presume that you have lua5.1 installed (considering the errors), so it's not to do with that.
My advice to you is to try running
luadoc file.lua
in the directory of file.lua with any old lua file (although preferably one with at least a little data in) and see if it generates an index.html in the same folder (don't change the directory with -d, for testing purposes). If that DOESN'T work, then reinstall it from the repos with apt-get. If doing that and trying luadoc file.lua doesn't work, then reply with the errors, as something bigger is going wrong (probably).

Resources