Skip to content

Commit

Permalink
Build a minimized Nix with MinGW
Browse files Browse the repository at this point in the history
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 <[email protected]>
Co-Authored-By Brian McKenna <[email protected]>
  • Loading branch information
Ericson2314 committed Apr 8, 2024
1 parent 1d9d201 commit 319d77c
Show file tree
Hide file tree
Showing 112 changed files with 1,158 additions and 143 deletions.
12 changes: 9 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ clean-files += $(buildprefix)Makefile.config

# List makefiles

include mk/platform.mk

ifeq ($(ENABLE_BUILD), yes)
makefiles = \
mk/precompiled-headers.mk \
Expand All @@ -20,7 +22,10 @@ makefiles = \
src/nix/local.mk \
src/libutil-c/local.mk \
src/libstore-c/local.mk \
src/libexpr-c/local.mk \
src/libexpr-c/local.mk

ifdef HOST_UNIX
makefiles += \
src/resolve-system-dependencies/local.mk \
scripts/local.mk \
misc/bash/local.mk \
Expand All @@ -30,6 +35,7 @@ makefiles = \
misc/launchd/local.mk \
misc/upstart/local.mk
endif
endif

ifeq ($(ENABLE_UNIT_TESTS), yes)
makefiles += \
Expand All @@ -43,6 +49,7 @@ makefiles += \
endif

ifeq ($(ENABLE_FUNCTIONAL_TESTS), yes)
ifdef HOST_UNIX
makefiles += \
tests/functional/local.mk \
tests/functional/ca/local.mk \
Expand All @@ -51,6 +58,7 @@ makefiles += \
tests/functional/test-libstoreconsumer/local.mk \
tests/functional/plugins/local.mk
endif
endif

# Some makefiles require access to built programs and must be included late.
makefiles-late =
Expand Down Expand Up @@ -79,8 +87,6 @@ else
unexport NIX_HARDENING_ENABLE
endif

include mk/platform.mk

ifdef HOST_WINDOWS
# Windows DLLs are stricter about symbol visibility than Unix shared
# objects --- see https://gcc.gnu.org/wiki/Visibility for details.
Expand Down
8 changes: 5 additions & 3 deletions m4/gcc_bug_80431.m4
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ AC_DEFUN([ENSURE_NO_GCC_BUG_80431],
]])],
[status_80431=0],
[status_80431=$?],
[
# Assume we're bug-free when cross-compiling
])
[status_80431=''])
AC_LANG_POP(C++)
AS_CASE([$status_80431],
[''],[
AC_MSG_RESULT(cannot check because cross compiling)
AC_MSG_NOTICE(assume we are bug free)
],
[0],[
AC_MSG_RESULT(yes)
],
Expand Down
21 changes: 12 additions & 9 deletions precompiled-headers.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,22 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <netdb.h>
#include <pwd.h>
#include <signal.h>
#include <sys/resource.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>

#ifndef _WIN32
# include <grp.h>
# include <netdb.h>
# include <pwd.h>
# include <sys/resource.h>
# include <sys/select.h>
# include <sys/socket.h>
# include <sys/utsname.h>
# include <sys/wait.h>
# include <termios.h>
#endif

#include <nlohmann/json.hpp>
2 changes: 1 addition & 1 deletion src/libcmd/common-eval-args.cc
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state)
v->mkString(arg.s);
},
[&](const AutoArgFile & arg) {
v->mkString(readFile(arg.path));
v->mkString(readFile(arg.path.string()));
},
[&](const AutoArgStdin & arg) {
v->mkString(readFile(STDIN_FILENO));
Expand Down
4 changes: 2 additions & 2 deletions src/libcmd/markdown.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
#include "finally.hh"
#include "terminal.hh"

#include <sys/queue.h>
#if HAVE_LOWDOWN
#include <lowdown.h>
# include <sys/queue.h>
# include <lowdown.h>
#endif

namespace nix {
Expand Down
4 changes: 4 additions & 0 deletions src/libcmd/repl-interacter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ static constexpr const char * promptForType(ReplPromptType promptType)

bool ReadlineLikeInteracter::getLine(std::string & input, ReplPromptType promptType)
{
#ifndef _WIN32 // TODO use more signals.hh for this
struct sigaction act, old;
sigset_t savedSignalMask, set;

Expand All @@ -161,9 +162,12 @@ bool ReadlineLikeInteracter::getLine(std::string & input, ReplPromptType promptT
};

setupSignals();
#endif
char * s = readline(promptForType(promptType));
Finally doFree([&]() { free(s); });
#ifndef _WIN32 // TODO use more signals.hh for this
restoreSignals();
#endif

if (g_signal_received) {
g_signal_received = 0;
Expand Down
4 changes: 4 additions & 0 deletions src/libcmd/repl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,14 @@ void runNix(Path program, const Strings & args,
auto subprocessEnv = getEnv();
subprocessEnv["NIX_CONFIG"] = globalConfig.toKeyValue();

#ifndef _WIN32 // TODO re-enable on Windows, once we can start processes.
runProgram2(RunOptions {
.program = settings.nixBinDir+ "/" + program,
.args = args,
.environment = subprocessEnv,
.input = input,
});
#endif

return;
}
Expand Down Expand Up @@ -480,6 +482,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
reloadFiles();
}

#ifndef _WIN32 // TODO re-enable on Windows, once we can start processes.
else if (command == ":e" || command == ":edit") {
Value v;
evalString(arg, v);
Expand Down Expand Up @@ -514,6 +517,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
state->resetFileCache();
reloadFiles();
}
#endif

else if (command == ":t") {
Value v;
Expand Down
10 changes: 8 additions & 2 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,17 @@
#include <optional>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <fstream>
#include <functional>
#include <iostream>

#include <sys/resource.h>
#include <nlohmann/json.hpp>
#include <boost/container/small_vector.hpp>

#ifndef _WIN32 // TODO use portable implementation
# include <sys/resource.h>
#endif

#if HAVE_BOEHMGC

#define GC_INCLUDE_NEW
Expand Down Expand Up @@ -2632,9 +2634,11 @@ void EvalState::maybePrintStats()

void EvalState::printStatistics()
{
#ifndef _WIN32 // TODO use portable implementation
struct rusage buf;
getrusage(RUSAGE_SELF, &buf);
float cpuTime = buf.ru_utime.tv_sec + ((float) buf.ru_utime.tv_usec / 1000000);
#endif

uint64_t bEnvs = nrEnvs * sizeof(Env) + nrValuesInEnvs * sizeof(Value *);
uint64_t bLists = nrListElems * sizeof(Value *);
Expand All @@ -2651,7 +2655,9 @@ void EvalState::printStatistics()
if (outPath != "-")
fs.open(outPath, std::fstream::out);
json topObj = json::object();
#ifndef _WIN32 // TODO implement
topObj["cpuTime"] = cpuTime;
#endif
topObj["envs"] = {
{"number", nrEnvs},
{"elements", nrValuesInEnvs},
Expand Down
2 changes: 2 additions & 0 deletions src/libexpr/eval.hh
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ struct DebugTrace {
bool isError;
};

// Don't want Windows function
#undef SearchPath

class EvalState : public std::enable_shared_from_this<EvalState>
{
Expand Down
13 changes: 11 additions & 2 deletions src/libexpr/primops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include "path-references.hh"
#include "store-api.hh"
#include "util.hh"
#include "processes.hh"
#include "value-to-json.hh"
#include "value-to-xml.hh"
#include "primops.hh"
Expand All @@ -28,7 +27,11 @@
#include <algorithm>
#include <cstring>
#include <regex>
#include <dlfcn.h>

#ifndef _WIN32
# include <dlfcn.h>
# include "processes.hh"
#endif

#include <cmath>

Expand Down Expand Up @@ -324,6 +327,8 @@ static RegisterPrimOp primop_import({
}
});

#ifndef _WIN32 // TODO implement via DLL loading on Windows

/* Want reasonable symbol names, so extern C */
/* !!! Should we pass the Pos or the file name too? */
extern "C" typedef void (*ValueInitializer)(EvalState & state, Value & v);
Expand Down Expand Up @@ -396,6 +401,8 @@ void prim_exec(EvalState & state, const PosIdx pos, Value * * args, Value & v)
}
}

#endif

/* Return a string representing the type of the expression. */
static void prim_typeOf(EvalState & state, const PosIdx pos, Value * * args, Value & v)
{
Expand Down Expand Up @@ -4581,6 +4588,7 @@ void EvalState::createBaseEnv()
)",
});

#ifndef _WIN32 // TODO implement on Windows
// Miscellaneous
if (evalSettings.enableNativeCode) {
addPrimOp({
Expand All @@ -4594,6 +4602,7 @@ void EvalState::createBaseEnv()
.fun = prim_exec,
});
}
#endif

addPrimOp({
.name = "__traceVerbose",
Expand Down
3 changes: 3 additions & 0 deletions src/libexpr/search-path.hh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

namespace nix {

// Do not want the windows macro (alias to `SearchPathA`)
#undef SearchPath

/**
* A "search path" is a list of ways look for something, used with
* `builtins.findFile` and `< >` lookup expressions.
Expand Down
26 changes: 18 additions & 8 deletions src/libfetchers/git-utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
#include "memory-input-accessor.hh"
#include "cache.hh"
#include "finally.hh"
#include "processes.hh"
#ifndef _WIN32 // TODO re-enable on Windows, once we can start processes.
# include "processes.hh"
#endif
#include "signals.hh"
#include "users.hh"
#include "fs-sink.hh"
Expand Down Expand Up @@ -151,11 +153,11 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
{
initLibGit2();

if (pathExists(path.native())) {
if (git_repository_open(Setter(repo), path.c_str()))
if (pathExists(path.string())) {
if (git_repository_open(Setter(repo), path.string().c_str()))
throw Error("opening Git repository '%s': %s", path, git_error_last()->message);
} else {
if (git_repository_init(Setter(repo), path.c_str(), bare))
if (git_repository_init(Setter(repo), path.string().c_str(), bare))
throw Error("creating Git repository '%s': %s", path, git_error_last()->message);
}
}
Expand Down Expand Up @@ -210,7 +212,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
std::vector<Submodule> parseSubmodules(const std::filesystem::path & configFile)
{
GitConfig config;
if (git_config_open_ondisk(Setter(config), configFile.c_str()))
if (git_config_open_ondisk(Setter(config), configFile.string().c_str()))
throw Error("parsing .gitmodules file: %s", git_error_last()->message);

ConfigIterator it;
Expand Down Expand Up @@ -282,7 +284,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>

/* Get submodule info. */
auto modulesFile = path / ".gitmodules";
if (pathExists(modulesFile))
if (pathExists(modulesFile.string()))
info.submodules = parseSubmodules(modulesFile);

return info;
Expand Down Expand Up @@ -377,12 +379,13 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
auto dir = this->path;
Strings gitArgs;
if (shallow) {
gitArgs = { "-C", dir, "fetch", "--quiet", "--force", "--depth", "1", "--", url, refspec };
gitArgs = { "-C", dir.string(), "fetch", "--quiet", "--force", "--depth", "1", "--", url, refspec };
}
else {
gitArgs = { "-C", dir, "fetch", "--quiet", "--force", "--", url, refspec };
gitArgs = { "-C", dir.string(), "fetch", "--quiet", "--force", "--", url, refspec };
}

#ifndef _WIN32 // TODO re-enable on Windows, once we can start processes.
runProgram(RunOptions {
.program = "git",
.searchPath = true,
Expand All @@ -392,6 +395,9 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
.input = {},
.isInteractive = true
});
#else
throw UnimplementedError("Cannot shell out to git on Windows yet");
#endif
}

void verifyCommit(
Expand Down Expand Up @@ -420,6 +426,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
}
writeFile(allowedSignersFile, allowedSigners);

#ifndef _WIN32 // TODO re-enable on Windows, once we can start processes.
// Run verification command
auto [status, output] = runProgram(RunOptions {
.program = "git",
Expand Down Expand Up @@ -450,6 +457,9 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
printTalkative("Signature verification on commit %s succeeded.", rev.gitRev());
else
throw Error("Commit signature verification on commit %s failed: %s", rev.gitRev(), output);
#else
throw Error("Commit signature verification not implemented on Windows yet");
#endif
}

Hash treeHashToNarHash(const Hash & treeHash) override
Expand Down
Loading

0 comments on commit 319d77c

Please sign in to comment.