Hey folks,
I am trying to setup a Nix build for a C++ CMake-based project and am wondering what the correct way to set this up yes. This is what I currently have which works:
let
nixpkgs = fetchGit {
url = "https://github.com/NixOS/nixpkgs.git";
rev = "8130f3c1c2bb0e533b5e150c39911d6e61dcecc2";
};
pkgs = import nixpkgs {};
in
pkgs.stdenv.mkDerivation {
name = "tvm";
src = pkgs.lib.cleanSource ./.;
nativeBuildInputs = [ pkgs.cmake ];
dontUseCmakeConfigure = true;
enableParallelBuilding = true;
NIX_BUILD_CORES = 4;
installPhase = ''
mkdir $out
cp -r build/* $out/
'';
}
This seems to approximately work, I am primarily looking to get at the *.dylib (macOS) and *.so (Linux) shared libraries. In the result
directory I see these files among a couple other CMake files so it looks OK.
However in my experience with Nix packages I know some packages have a separate *-dev package and there is some support for a $outputDev
placeholder variable when building with multiple outputs? Given what I am building doesnât have an executable and is just a shared library is the way I have up there fine, or should I be using another way instead?
Also curious for any suggestions to improve the expression as well.
Thanks!
-Adelbert
1 Like
This looks a little off by me. Why did you resort to using dontUseCmakeConfigure = true;
? This looks to me that you will have to manually build the project before being able to call nix-build
, which will be both not reproducible and also result in incorrect *.so files not containing the correct references to depending libraries.
Usually you would nixify your project in such a way that nix-build
produces correct outputs and then using nix-shell
to interactively build and develop the package should work mostly out of the box.
I would assume that removing both the dontUseCmakeConfigure
and the manually defined installPhase
should get you somewhat further. If cmake fails during configuring the project you might want to add possible other dependencies of your project
Sorry for the extremely late reply! I am back to trying to get this project done the right Nix way.
The reason I set dontUseCmakeConfigure = true
was purely experimentally, without it when I try to nix-build
I get:
...
CMake Warning at cmake/modules/Git.cmake:39 (message):
Git not found
Call Stack (most recent call first):
CMakeLists.txt:353 (include)
-- Performing Test SUPPORT_CXX14
-- Performing Test SUPPORT_CXX14 - Success
-- Building with TVM Map...
-- Build with thread support...
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Configuring done
CMake Error at CMakeLists.txt:369 (add_library):
Cannot find source file:
src/target/var/empty/build_cuda_off.cc
Tried extensions .c .C .c++ .cc .cpp .cxx .cu .m .M .mm .h .hh .h++ .hm
.hpp .hxx .in .txx
CMake Error at CMakeLists.txt:372 (add_library):
No SOURCES given to target: tvm
CMake Error at CMakeLists.txt:369 (add_library):
No SOURCES given to target: tvm_objs
CMake Generate step failed. Build files cannot be regenerated correctly.
builder for '/nix/store/23xbzrdg7y9rnylwk584r16dlwh9vmhg-tvm.drv' failed with exit code 1
error: build of '/nix/store/23xbzrdg7y9rnylwk584r16dlwh9vmhg-tvm.drv' failed
Somehow I found that flag and I can confirm with that flag on and a fresh repo checkout everything builds fine.
Separate from that I am also curious, after a nix-build in my result/
directory I see:
CMakeCache.txt CMakeFiles Makefile cmake_install.cmake libtvm.dylib libtvm_runtime.dylib
⌠so the shared libraries are in there, but not sure if that is the right place as I often see other Nix C++ projects have a -dev
folder with include/
or share/
folders?
The âvar/emptyâ looks suspiciously like something went wrong in detecting a target or an environment variable being unset. This means there is a bug in your CMakelists.txt
As for why youâve got CMakeCache.txt in your $out: in your custom installPhase youâre copying everything in the build directory to the output directory.
This is not a good idea since the build directory also will contain some things that should not go to the output.
Instead normally nixpkgs is set up to call âmake installâ. So as long as your CMakeLists.txt contains a âinstall(âŚ)â command everything should work fine if you donât override the installPhase manually.
1 Like
Wow. I wasnât aware of that. Is this really a good idea? Seems that every occurrence of â/usrâ will be replaced. Even legitimate usages will be removed?
Ahh yeah, in this case it was âincorrectlyâ picking up the /opt
as it was referencing a directory in the project itself as opposed to a global one. Setting dontFixCmake = true;
seems to fix it - I see a couple other derivations in nixpkgs do the same - thank you!
EDIT Toggling dontFixCmake
and then removing the installPhase
override works beautifully! It results in the expected include
and lib
subdirectories in result
woot - thanks everyone!