mirror of
https://github.com/NixOS/nix.git
synced 2025-11-16 15:32:43 +01:00
Build a minimized Nix with MinGW
At this point many features are stripped out, but this works:
- Can run libnix{util,store,expr} unit tests
- Can run some Nix commands
Co-Authored-By volth <volth@volth.com>
Co-Authored-By Brian McKenna <brian@brianmckenna.org>
This commit is contained in:
parent
2248a3f545
commit
8433027e35
111 changed files with 1162 additions and 140 deletions
|
|
@ -76,7 +76,11 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
|
|||
throw Error("collision between '%1%' and non-directory '%2%'", srcFile, target);
|
||||
if (unlink(dstFile.c_str()) == -1)
|
||||
throw SysError("unlinking '%1%'", dstFile);
|
||||
if (mkdir(dstFile.c_str(), 0755) == -1)
|
||||
if (mkdir(dstFile.c_str()
|
||||
#ifndef _WIN32 // TODO abstract mkdir perms for Windows
|
||||
, 0755
|
||||
#endif
|
||||
) == -1)
|
||||
throw SysError("creating directory '%1%'", dstFile);
|
||||
createLinks(state, target, dstFile, state.priorities[dstFile]);
|
||||
createLinks(state, srcFile, dstFile, priority);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include "daemon.hh"
|
||||
#include "monitor-fd.hh"
|
||||
#include "signals.hh"
|
||||
#include "worker-protocol.hh"
|
||||
#include "worker-protocol-impl.hh"
|
||||
|
|
@ -16,6 +15,10 @@
|
|||
#include "args.hh"
|
||||
#include "git.hh"
|
||||
|
||||
#ifndef _WIN32 // TODO need graceful async exit support on Windows?
|
||||
# include "monitor-fd.hh"
|
||||
#endif
|
||||
|
||||
namespace nix::daemon {
|
||||
|
||||
Sink & operator << (Sink & sink, const Logger::Fields & fields)
|
||||
|
|
@ -1018,7 +1021,9 @@ void processConnection(
|
|||
TrustedFlag trusted,
|
||||
RecursiveFlag recursive)
|
||||
{
|
||||
#ifndef _WIN32 // TODO need graceful async exit support on Windows?
|
||||
auto monitor = !recursive ? std::make_unique<MonitorFdHup>(from.fd) : nullptr;
|
||||
#endif
|
||||
|
||||
/* Exchange the greeting. */
|
||||
unsigned int magic = readInt(from);
|
||||
|
|
|
|||
|
|
@ -516,10 +516,12 @@ struct curlFileTransfer : public FileTransfer
|
|||
|
||||
Sync<State> state_;
|
||||
|
||||
#ifndef _WIN32 // TODO need graceful async exit support on Windows?
|
||||
/* We can't use a std::condition_variable to wake up the curl
|
||||
thread, because it only monitors file descriptors. So use a
|
||||
pipe instead. */
|
||||
Pipe wakeupPipe;
|
||||
#endif
|
||||
|
||||
std::thread workerThread;
|
||||
|
||||
|
|
@ -539,8 +541,10 @@ struct curlFileTransfer : public FileTransfer
|
|||
fileTransferSettings.httpConnections.get());
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32 // TODO need graceful async exit support on Windows?
|
||||
wakeupPipe.create();
|
||||
fcntl(wakeupPipe.readSide.get(), F_SETFL, O_NONBLOCK);
|
||||
#endif
|
||||
|
||||
workerThread = std::thread([&]() { workerThreadEntry(); });
|
||||
}
|
||||
|
|
@ -561,15 +565,19 @@ struct curlFileTransfer : public FileTransfer
|
|||
auto state(state_.lock());
|
||||
state->quit = true;
|
||||
}
|
||||
#ifndef _WIN32 // TODO need graceful async exit support on Windows?
|
||||
writeFull(wakeupPipe.writeSide.get(), " ", false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void workerThreadMain()
|
||||
{
|
||||
/* Cause this thread to be notified on SIGINT. */
|
||||
#ifndef _WIN32 // TODO need graceful async exit support on Windows?
|
||||
auto callback = createInterruptCallback([&]() {
|
||||
stopWorkerThread();
|
||||
});
|
||||
#endif
|
||||
|
||||
#if __linux__
|
||||
unshareFilesystem();
|
||||
|
|
@ -607,9 +615,11 @@ struct curlFileTransfer : public FileTransfer
|
|||
/* Wait for activity, including wakeup events. */
|
||||
int numfds = 0;
|
||||
struct curl_waitfd extraFDs[1];
|
||||
#ifndef _WIN32 // TODO need graceful async exit support on Windows?
|
||||
extraFDs[0].fd = wakeupPipe.readSide.get();
|
||||
extraFDs[0].events = CURL_WAIT_POLLIN;
|
||||
extraFDs[0].revents = 0;
|
||||
#endif
|
||||
long maxSleepTimeMs = items.empty() ? 10000 : 100;
|
||||
auto sleepTimeMs =
|
||||
nextWakeup != std::chrono::steady_clock::time_point()
|
||||
|
|
@ -693,7 +703,9 @@ struct curlFileTransfer : public FileTransfer
|
|||
throw nix::Error("cannot enqueue download request because the download thread is shutting down");
|
||||
state->incoming.push(item);
|
||||
}
|
||||
#ifndef _WIN32 // TODO need graceful async exit support on Windows?
|
||||
writeFull(wakeupPipe.writeSide.get(), " ");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ENABLE_S3
|
||||
|
|
|
|||
|
|
@ -9,11 +9,14 @@
|
|||
#include <map>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <dlfcn.h>
|
||||
# include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
#ifdef __GLIBC__
|
||||
# include <gnu/lib-names.h>
|
||||
# include <nss.h>
|
||||
|
|
@ -56,7 +59,9 @@ Settings::Settings()
|
|||
, nixManDir(canonPath(NIX_MAN_DIR))
|
||||
, nixDaemonSocketFile(canonPath(getEnvNonEmpty("NIX_DAEMON_SOCKET_PATH").value_or(nixStateDir + DEFAULT_SOCKET_PATH)))
|
||||
{
|
||||
#ifndef _WIN32
|
||||
buildUsersGroup = isRootUser() ? "nixbld" : "";
|
||||
#endif
|
||||
allowSymlinkedStore = getEnv("NIX_IGNORE_SYMLINK_STORE") == "1";
|
||||
|
||||
auto sslOverride = getEnv("NIX_SSL_CERT_FILE").value_or(getEnv("SSL_CERT_FILE").value_or(""));
|
||||
|
|
@ -239,11 +244,15 @@ StringSet Settings::getDefaultExtraPlatforms()
|
|||
|
||||
bool Settings::isWSL1()
|
||||
{
|
||||
#if __linux__
|
||||
struct utsname utsbuf;
|
||||
uname(&utsbuf);
|
||||
// WSL1 uses -Microsoft suffix
|
||||
// WSL2 uses -microsoft-standard suffix
|
||||
return hasSuffix(utsbuf.release, "-Microsoft");
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
Path Settings::getDefaultSSLCertFile()
|
||||
|
|
@ -341,6 +350,7 @@ void initPlugins()
|
|||
for (const auto & file : pluginFiles) {
|
||||
/* handle is purposefully leaked as there may be state in the
|
||||
DSO needed by the action of the plugin. */
|
||||
#ifndef _WIN32 // TODO implement via DLL loading on Windows
|
||||
void *handle =
|
||||
dlopen(file.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!handle)
|
||||
|
|
@ -351,6 +361,9 @@ void initPlugins()
|
|||
void (*nix_plugin_entry)() = (void (*)())dlsym(handle, "nix_plugin_entry");
|
||||
if (nix_plugin_entry)
|
||||
nix_plugin_entry();
|
||||
#else
|
||||
throw Error("could not dynamically open plugin file '%s'", file);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -666,6 +666,7 @@ public:
|
|||
Setting<bool> sandboxFallback{this, true, "sandbox-fallback",
|
||||
"Whether to disable sandboxing when the kernel doesn't allow it."};
|
||||
|
||||
#ifndef _WIN32
|
||||
Setting<bool> requireDropSupplementaryGroups{this, isRootUser(), "require-drop-supplementary-groups",
|
||||
R"(
|
||||
Following the principle of least privilege,
|
||||
|
|
@ -683,6 +684,7 @@ public:
|
|||
(since `root` usually has permissions to call setgroups)
|
||||
and `false` otherwise.
|
||||
)"};
|
||||
#endif
|
||||
|
||||
#if __linux__
|
||||
Setting<std::string> sandboxShmSize{
|
||||
|
|
|
|||
|
|
@ -4,9 +4,12 @@ libstore_NAME = libnixstore
|
|||
|
||||
libstore_DIR := $(d)
|
||||
|
||||
libstore_SOURCES := $(wildcard $(d)/*.cc $(d)/builtins/*.cc $(d)/build/*.cc)
|
||||
libstore_SOURCES := $(wildcard $(d)/*.cc $(d)/builtins/*.cc)
|
||||
ifdef HOST_UNIX
|
||||
libstore_SOURCES += $(wildcard $(d)/unix/*.cc)
|
||||
libstore_SOURCES += $(wildcard $(d)/unix/*.cc $(d)/unix/builtins/*.cc $(d)/unix/build/*.cc)
|
||||
endif
|
||||
ifdef HOST_WINDOWS
|
||||
libstore_SOURCES += $(wildcard $(d)/windows/*.cc)
|
||||
endif
|
||||
|
||||
libstore_LIBS = libutil
|
||||
|
|
@ -55,9 +58,9 @@ libstore_CXXFLAGS += \
|
|||
ifeq ($(embedded_sandbox_shell),yes)
|
||||
libstore_CXXFLAGS += -DSANDBOX_SHELL=\"__embedded_sandbox_shell__\"
|
||||
|
||||
$(d)/build/local-derivation-goal.cc: $(d)/embedded-sandbox-shell.gen.hh
|
||||
$(d)/unix/build/local-derivation-goal.cc: $(d)/unix/embedded-sandbox-shell.gen.hh
|
||||
|
||||
$(d)/embedded-sandbox-shell.gen.hh: $(sandbox_shell)
|
||||
$(d)/unix/embedded-sandbox-shell.gen.hh: $(sandbox_shell)
|
||||
$(trace-gen) hexdump -v -e '1/1 "0x%x," "\n"' < $< > $@.tmp
|
||||
@mv $@.tmp $@
|
||||
else
|
||||
|
|
@ -66,11 +69,11 @@ else
|
|||
endif
|
||||
endif
|
||||
|
||||
$(d)/local-store.cc: $(d)/schema.sql.gen.hh $(d)/ca-specific-schema.sql.gen.hh
|
||||
$(d)/unix/local-store.cc: $(d)/unix/schema.sql.gen.hh $(d)/unix/ca-specific-schema.sql.gen.hh
|
||||
|
||||
$(d)/build.cc:
|
||||
$(d)/unix/build.cc:
|
||||
|
||||
clean-files += $(d)/schema.sql.gen.hh $(d)/ca-specific-schema.sql.gen.hh
|
||||
clean-files += $(d)/unix/schema.sql.gen.hh $(d)/unix/ca-specific-schema.sql.gen.hh
|
||||
|
||||
$(eval $(call install-file-in, $(buildprefix)$(d)/nix-store.pc, $(libdir)/pkgconfig, 0644))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#include "derivations.hh"
|
||||
#include "parsed-derivations.hh"
|
||||
#include "globals.hh"
|
||||
#include "local-store.hh"
|
||||
#include "store-api.hh"
|
||||
#include "thread-pool.hh"
|
||||
#include "realisation.hh"
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "types.hh"
|
||||
#include "pathlocks.hh"
|
||||
|
||||
#include <optional>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -71,11 +71,15 @@ std::pair<ref<SourceAccessor>, CanonPath> RemoteFSAccessor::fetch(const CanonPat
|
|||
auto narAccessor = makeLazyNarAccessor(listing,
|
||||
[cacheFile](uint64_t offset, uint64_t length) {
|
||||
|
||||
AutoCloseFD fd = open(cacheFile.c_str(), O_RDONLY | O_CLOEXEC);
|
||||
AutoCloseFD fd = toDescriptor(open(cacheFile.c_str(), O_RDONLY
|
||||
#ifndef _WIN32
|
||||
| O_CLOEXEC
|
||||
#endif
|
||||
));
|
||||
if (!fd)
|
||||
throw SysError("opening NAR cache file '%s'", cacheFile);
|
||||
|
||||
if (lseek(fd.get(), offset, SEEK_SET) != (off_t) offset)
|
||||
if (lseek(fromDescriptorReadOnly(fd.get()), offset, SEEK_SET) != (off_t) offset)
|
||||
throw SysError("seeking in '%s'", cacheFile);
|
||||
|
||||
std::string buf(length, 0);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ bool SSHMaster::isMasterRunning() {
|
|||
std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(
|
||||
Strings && command, Strings && extraSshArgs)
|
||||
{
|
||||
#ifdef _WIN32 // TODO re-enable on Windows, once we can start processes.
|
||||
throw UnimplementedError("cannot yet SSH on windows because spawning processes is not yet implemented");
|
||||
#else
|
||||
Path socketPath = startMaster();
|
||||
|
||||
Pipe in, out;
|
||||
|
|
@ -105,8 +108,8 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(
|
|||
}, options);
|
||||
|
||||
|
||||
in.readSide = -1;
|
||||
out.writeSide = -1;
|
||||
in.readSide = INVALID_DESCRIPTOR;
|
||||
out.writeSide = INVALID_DESCRIPTOR;
|
||||
|
||||
// Wait for the SSH connection to be established,
|
||||
// So that we don't overwrite the password prompt with our progress bar.
|
||||
|
|
@ -126,15 +129,18 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(
|
|||
conn->in = std::move(in.writeSide);
|
||||
|
||||
return conn;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef _WIN32 // TODO re-enable on Windows, once we can start processes.
|
||||
|
||||
Path SSHMaster::startMaster()
|
||||
{
|
||||
if (!useMaster) return "";
|
||||
|
||||
auto state(state_.lock());
|
||||
|
||||
if (state->sshMaster != -1) return state->socketPath;
|
||||
if (state->sshMaster != INVALID_DESCRIPTOR) return state->socketPath;
|
||||
|
||||
state->socketPath = (Path) *state->tmpDir + "/ssh.sock";
|
||||
|
||||
|
|
@ -167,7 +173,7 @@ Path SSHMaster::startMaster()
|
|||
throw SysError("unable to execute '%s'", args.front());
|
||||
}, options);
|
||||
|
||||
out.writeSide = -1;
|
||||
out.writeSide = INVALID_DESCRIPTOR;
|
||||
|
||||
std::string reply;
|
||||
try {
|
||||
|
|
@ -182,4 +188,6 @@ Path SSHMaster::startMaster()
|
|||
return state->socketPath;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ private:
|
|||
|
||||
struct State
|
||||
{
|
||||
#ifndef _WIN32 // TODO re-enable on Windows, once we can start processes.
|
||||
Pid sshMaster;
|
||||
#endif
|
||||
std::unique_ptr<AutoDelete> tmpDir;
|
||||
Path socketPath;
|
||||
};
|
||||
|
|
@ -31,13 +33,19 @@ private:
|
|||
void addCommonSSHOpts(Strings & args);
|
||||
bool isMasterRunning();
|
||||
|
||||
#ifndef _WIN32 // TODO re-enable on Windows, once we can start processes.
|
||||
Path startMaster();
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
SSHMaster(const std::string & host, const std::string & keyFile, const std::string & sshPublicHostKey, bool useMaster, bool compress, int logFD = -1);
|
||||
|
||||
struct Connection
|
||||
{
|
||||
#ifndef _WIN32 // TODO re-enable on Windows, once we can start processes.
|
||||
Pid sshPid;
|
||||
#endif
|
||||
AutoCloseFD out, in;
|
||||
};
|
||||
|
||||
|
|
@ -51,8 +59,6 @@ public:
|
|||
std::unique_ptr<Connection> startCommand(
|
||||
Strings && command,
|
||||
Strings && extraSshArgs = {});
|
||||
|
||||
Path startMaster();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include "archive.hh"
|
||||
#include "callback.hh"
|
||||
#include "git.hh"
|
||||
#include "remote-store.hh"
|
||||
#include "posix-source-accessor.hh"
|
||||
// FIXME this should not be here, see TODO below on
|
||||
// `addMultipleToStore`.
|
||||
|
|
@ -21,6 +20,10 @@
|
|||
#include "signals.hh"
|
||||
#include "users.hh"
|
||||
|
||||
#ifndef _WIN32
|
||||
# include "remote-store.hh"
|
||||
#endif
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <regex>
|
||||
|
||||
|
|
@ -1266,9 +1269,10 @@ Derivation Store::readInvalidDerivation(const StorePath & drvPath)
|
|||
|
||||
}
|
||||
|
||||
|
||||
#include "local-store.hh"
|
||||
#include "uds-remote-store.hh"
|
||||
#ifndef _WIN32
|
||||
# include "local-store.hh"
|
||||
# include "uds-remote-store.hh"
|
||||
#endif
|
||||
|
||||
|
||||
namespace nix {
|
||||
|
|
@ -1286,6 +1290,9 @@ std::pair<std::string, Store::Params> splitUriAndParams(const std::string & uri_
|
|||
return {uri, params};
|
||||
}
|
||||
|
||||
#ifdef _WIN32 // Unused on Windows because the next `#ifndef`
|
||||
[[maybe_unused]]
|
||||
#endif
|
||||
static bool isNonUriPath(const std::string & spec)
|
||||
{
|
||||
return
|
||||
|
|
@ -1298,6 +1305,9 @@ static bool isNonUriPath(const std::string & spec)
|
|||
|
||||
std::shared_ptr<Store> openFromNonUri(const std::string & uri, const Store::Params & params)
|
||||
{
|
||||
// TODO reenable on Windows once we have `LocalStore` and
|
||||
// `UDSRemoteStore`.
|
||||
#ifndef _WIN32
|
||||
if (uri == "" || uri == "auto") {
|
||||
auto stateDir = getOr(params, "state", settings.nixStateDir);
|
||||
if (access(stateDir.c_str(), R_OK | W_OK) == 0)
|
||||
|
|
@ -1342,6 +1352,9 @@ std::shared_ptr<Store> openFromNonUri(const std::string & uri, const Store::Para
|
|||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
// The `parseURL` function supports both IPv6 URIs as defined in
|
||||
|
|
|
|||
37
src/libstore/windows/build.cc
Normal file
37
src/libstore/windows/build.cc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#include "store-api.hh"
|
||||
#include "build-result.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
void Store::buildPaths(const std::vector<DerivedPath> & reqs, BuildMode buildMode, std::shared_ptr<Store> evalStore)
|
||||
{
|
||||
unsupported("buildPaths");
|
||||
}
|
||||
|
||||
std::vector<KeyedBuildResult> Store::buildPathsWithResults(
|
||||
const std::vector<DerivedPath> & reqs,
|
||||
BuildMode buildMode,
|
||||
std::shared_ptr<Store> evalStore)
|
||||
{
|
||||
unsupported("buildPathsWithResults");
|
||||
}
|
||||
|
||||
BuildResult Store::buildDerivation(const StorePath & drvPath, const BasicDerivation & drv,
|
||||
BuildMode buildMode)
|
||||
{
|
||||
unsupported("buildDerivation");
|
||||
}
|
||||
|
||||
|
||||
void Store::ensurePath(const StorePath & path)
|
||||
{
|
||||
unsupported("ensurePath");
|
||||
}
|
||||
|
||||
|
||||
void Store::repairPath(const StorePath & path)
|
||||
{
|
||||
unsupported("repairPath");
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue