Nix + cmake + 3rd party archives

I’m working on updating the nix package for the upcoming release of Textadept.

The previous version of this package was built with make. The makefile used wget to download some archives for 3rd party libraries, which doesn’t work inside a nix derivation. That problem was solved by using fetchurl to pre-fetch the archives and putting them where the makefile expected them to be, and only then invoking make.

The new version of textadept is built with CMake, and it also wants to download stuff. I tried to use the same trick of pre-fetching the archives. For example I downloaded scintilla530.tgz and put it where CMake would have put it, in build/_deps/scintilla-subbuild/scintilla-populate-prefix/src/. However, CMake tries to download it anyway. This may be because it also expects other directories such as build/_deps/scintilla-subbuild/scintilla-populate-prefix/src/scintilla-populate-stamp to be populated with a lot of additional stuff.

Any suggestions on how to proceed? I’ve been looking through the nixpkgs repo to see how others have handled similar situations, but I haven’t found any examples.

Are there any nix functions that can help with this scenario?

I’m not familiar with CMake, but a cursory web search hasn’t turned up a way (without modifying CMakeLists.txt) to tell CMake to use pre-fetched archives instead of downloading them.

If all else fails, I guess the only option is to work with the developer to modify the CMake configuration to support nix.

I see three packages in nixpkgs that include wget in their buildInputs, so maybe I was wrong about that not being allowed in the build step.

it can’t touch the internet during a nix build. However, some scripts just check for the presence of a command.

You can add wget to make the build logic happy, you just can’t use it.

1 Like

it can’t touch the internet during a nix build

For the last 24 hours I’ve had an image stuck in my head of the Internet dancing around in MC Hammer-style parachute pants singing “Can’t touch this”. Showing my age!

Anyway, I contacted the developer, and they already designed the system to handle this; I was just putting the files in the wrong place.

For anyone in a similar situation who (like me) isn’t familiar with CMake, here’s an example from the CMakeLists.txt file. Once I knew that the build system was designed this way, it was easy for me to spot the relevant code and understand it. CMake checks for the presence of the file in ${CMAKE_BINARY_DIR}/_deps, and if it’s there, it won’t download it again. Perhaps this example will help someone.

set(deps_dir ${CMAKE_BINARY_DIR}/_deps)
set(scintilla_tgz scintilla530.tgz)
set(scintilla_url file://${deps_dir}/${scintilla_tgz})
if(NOT EXISTS ${deps_dir}/${scintilla_tgz})
  set(scintilla_url https://www.scintilla.org/${scintilla_tgz})
endif()
FetchContent_Declare(scintilla
  URL ${scintilla_url}
  PATCH_COMMAND patch -N -p1 < ${ta}/src/scintilla.patch)
FetchContent_MakeAvailable(scintilla)
1 Like