Reputation: 63
I'm trying to build a simple Swift project on NixOS. Here are the steps to reproduce:
git clone https://github.com/PerfectlySoft/PerfectTemplate.git
cd PerfectTemplate
touch shell.nix
Add shell.nix
with following contents:
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "swift-env";
buildInputs = [
openssl
stdenv
binutils
cmake
pkgconfig
curl
glibc
icu
libblocksruntime
libbsd
libedit
libuuid
libxml2
ncurses
sqlite
swig
];
}
Running nix-shell --pure shell.nix
and from there swift build
, gives me:
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: unrecognized command line option ‘-target’
gcc: error: x86_64-unknown-linux: No such file or directory
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-fblocks’
gcc: error: unrecognized command line option ‘-target’
gcc: error: unrecognized command line option ‘-fmodule-name=PerfectCZlib’
gcc: error: unrecognized command line option ‘-fmodules’; did you mean ‘-fmudflap’?
gcc: error: unrecognized command line option ‘-fmodules-cache-path=/home/dmi3y/Dev/Swift/PerfectTemplate/.build/x86_64-unknown-linux/debug/ModuleCache’
gcc: error: unrecognized command line option ‘-fblocks’
I'd appreciate any help with this as I'm pretty much new to nix-shell and NixOS.
EDIT:
I changed my shell.nix
to this:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
name = "swift-env";
buildInputs = with pkgs; [
openssl
clang
swift
];
shellHook = ''
CC=clang
'';
}
However, when I run nix-shell
followed by swift build
, I'm now getting:
[1/25] Compiling PerfectCZlib zutil.c
[2/25] Compiling PerfectCZlib uncompr.c
[3/25] Compiling PerfectCZlib inftrees.c
[4/25] Compiling PerfectCZlib inflate.c
[5/25] Compiling PerfectCZlib trees.c
[6/25] Compiling PerfectCZlib inffast.c
[7/25] Compiling PerfectCZlib infback.c
[8/25] Compiling PerfectCZlib gzwrite.c
/nix/store/iz6k7x3l14ykr56crz3dizas1rrkcyzr-clang-wrapper-7.1.0/resource-root/include/module.modulemap:24:8: error: redefinition of module '_Builtin_intrinsics'
# warning _FORTIFY_SOURCE requires compiling with optimization (-O)
^
1 warning and 3 errors generated.
1 warning and 3 errors generated.
Full log can be found here.
This is now looks like a missing library dependency or a version conflict.
For the record, here's additional information about my setup that might shed more light:
$ nix-channel --list
home-manager https://github.com/rycee/home-manager/archive/master.tar.gz
nixos https://nixos.org/channels/nixos-19.09
$ nix-shell --run 'swift -version'
Swift version 5.0.2 (swift-5.0.2-RELEASE)
Target: x86_64-unknown-linux-gnub
After searching the web I found a Jira issue for Swift compiler and this specific comment. I decided to exclude clang
from dependencies and only include swift
, since this combination seem to be conflicting:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
name = "swift-env";
buildInputs = with pkgs; [
openssl
swift
];
shellHook = ''
CC=clang
'';
}
And that worked! I was finally able to build the project!
Upvotes: 3
Views: 1347
Reputation: 802
Since your using the --pure
option, nothing from your previous environment will be imported into the shell. This includes the swift
binary itself. So first I would add swift
to the buildInputs
.
The error your getting indicates that gcc
doesn't even understand the command line options being passed. I don't know anything about Swift, but after seeing that I assumed that it needs a different compiler. Sure enough, after a quick search it looks like it is llvm based. You will thus need to also add clang
to your build inputs. In addition, you'll need to use mkShell
instead of mkDerivation
to setup the proper environment.
The former is a wrapper to the latter that is specifically designed to set up a nix-shell, and ensures the environment is handled correctly. You'll need to pass in the shellHook
attribute to override the default c compiler to clang
using the CC
envvar. The shellHook
is a way of running arbitrary commands at the start of the shell.
As a final note, the nix-shell
command searches for shell.nix
by default so you don't have to pass it as an argument. If shell.nix
does not exist, then it will try default.nix
. If neither exist, then you'll have to explicitly specify the nix expressions location.
TLDR
to put it all together:
# a more idiomatic way to import nixpkgs, overridable from the cmdline
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
name = "swift-env";
buildInputs = with pkgs; [
# your other inputs
clang
swift
];
shellHook = ''
CC=clang
'';
}
Just to be sure my logic was correct I downloaded the repo and gave it go. Everything compiles and runs successfully.
Upvotes: 3