Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build a minimized Nix with MinGW #8901

Merged
merged 5 commits into from
Apr 17, 2024
Merged

Conversation

Ericson2314
Copy link
Member

@Ericson2314 Ericson2314 commented Sep 2, 2023

Motivation

Chasing my white whale of Nix on Windows again. Based off of @volth's great work.

At this point many features are stripped out, but this works:

  • Can run libnix{util,store,expr} unit tests
  • Can run some Nix commands

Context

Depends on #8887
Depends on #8920
Depends on #8886
Depends on #9518
Depends on #9519
Depends on #9736
Depends on #9737
Depends on #9757
Depends on #9767
Depends on #10329
Depends on #10361
Depends on #10362
Depends on #10363
Depends on #10364
Depends on #10399
Depends on #10400
Depends on #10401

Checklist for maintainers

Maintainers: tick if completed or explain if not relevant

  • agreed on idea
  • agreed on implementation strategy
  • tests, as appropriate
    • functional tests - tests/**.sh
    • unit tests - src/*/tests
    • integration tests - tests/nixos/*
  • documentation in the manual
  • documentation in the internal API docs
  • code and comments are self-explanatory
  • commit message explains why the change was made
  • new feature or incompatible change: updated release notes

Priorities

Add 👍 to pull requests you find important.

@github-actions github-actions bot added new-cli Relating to the "nix" command with-tests Issues related to testing. PRs with tests have some priority fetching Networking with the outside (non-Nix) world, input locking labels Sep 2, 2023
This was referenced Sep 4, 2023
@Artturin
Copy link
Member

Artturin commented Sep 4, 2023

I guess this overlaps with cygwin stuff CC @corngood #4953

@Ericson2314
Copy link
Member Author

Oh yes it does! If we could get a cygwin (and msys2) build in CI that would be a great first step.

@corngood
Copy link
Contributor

corngood commented Sep 5, 2023

I've never had much trouble building nix on cygwin. What I did have a lot of trouble with is fibers/coroutines, which are used by nix via boost. They are sort of fundamentally broken in cygwin, which causes nix to crash (e.g. on network operations).

I actually proposed a patch to cygwin which allows them to work, but it hasn't been merged:

https://cygwin.com/pipermail/cygwin-developers/2020-September/011970.html

Last time I did any work on this, it was mostly on the nixpkgs side. The idea was to be able to cross compile a patched cygwin1.dll, and use that to bootstrap, and build up from there. Unfortunately I haven't had time to work on it for a while.

I gave up on bootstrapping using unmodified cygwin.

@dpulls
Copy link

dpulls bot commented Sep 25, 2023

🎉 All dependencies have been resolved !

@Ericson2314 Ericson2314 changed the title Build Nix with MinGW Build libnixutil with MinGW Oct 21, 2023
@github-actions github-actions bot added store Issues and pull requests concerning the Nix store repl The Read Eval Print Loop, "nix repl" command and debugger labels Oct 21, 2023
Copy link

dpulls bot commented Nov 5, 2023

🎉 All dependencies have been resolved !

@github-actions github-actions bot removed store Issues and pull requests concerning the Nix store repl The Read Eval Print Loop, "nix repl" command and debugger labels Nov 6, 2023
@Ericson2314
Copy link
Member Author

I think we'll want to install the unit tests into a separate output so we can run them on windows.

@github-actions github-actions bot added the store Issues and pull requests concerning the Nix store label Nov 15, 2023
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2023-11-17-nix-team-meeting-minutes-104/35753/1

@2xsaiko
Copy link

2xsaiko commented Apr 8, 2024

Just curious, what is the oldest version of Windows this supports?

(Also I haven't looked too closely at the code but related: if you're touching winapi you might want to enable UTF-8 mode so you don't have to touch wchar_t which I think is only supported on Windows 10 and up)

@Ericson2314
Copy link
Member Author

Just curious, what is the oldest version of Windows this supports?

Don't know!

(Also I haven't looked too closely at the code but related: if you're touching winapi you might want to enable UTF-8 mode so you don't have to touch wchar_t which I think is only supported on Windows 10 and up)

Does that support ill-formed UTF-16 the way https://simonsapin.github.io/wtf-8/ does? In any event the plan for paths (main place this comes up) is using std::filesystem::path (#9205) which I suppose makes working with the native 16-bit characters less bad.

@2xsaiko
Copy link

2xsaiko commented Apr 8, 2024

Does that support ill-formed UTF-16 the way https://simonsapin.github.io/wtf-8/ does? In any event the plan for paths (main place this comes up) is using std::filesystem::path (#9205) which I suppose makes working with the native 16-bit characters less bad.

No, it seems to be actual UTF-8. What it does when you explicitly call the WideCharToMultiByte function it depends on whether the MB_ERR_INVALID_CHARS is set:

MB_ERR_INVALID_CHARS Fail if an invalid input character is encountered.

Starting with Windows Vista, the function does not drop illegal code points if the application does not set this flag, but instead replaces illegal sequences with U+FFFD (encoded as appropriate for the specified codepage).

Windows 2000 with SP4 and later, Windows XP: If this flag is not set, the function silently drops illegal code points. A call to GetLastError returns ERROR_NO_UNICODE_TRANSLATION.

I assume the default with conversions in Windows's own functions is that it isn't set, no idea though.

For paths I would also just use std::filesystem::path so you don't have to worry about that though, yeah.

src/libcmd/repl.cc Outdated Show resolved Hide resolved
src/libexpr/eval.hh Show resolved Hide resolved
@@ -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())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely clear on the difference between native() and string(), but the docs for string() say:

Otherwise, if path::value_type is wchar_t, conversion, if any, is unspecified. This is the case on Windows, where wchar_t is 16 bit and the native encoding is UTF-16.

which seems worrying.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the more we use std::filesystem::path the more it will go away --- for now I am fine with it because it has no effect on Unix and it gets Windows at least compiling.

src/libmain/shared.cc Show resolved Hide resolved
src/libmain/shared.cc Outdated Show resolved Hide resolved
src/libstore/store-api.cc Outdated Show resolved Hide resolved
src/libutil/file-descriptor.hh Show resolved Hide resolved
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_RDONLY
// TODO
#ifndef _WIN32
| O_CLOEXEC
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can define O_CLOEXEC as 0 on Windows in a header? Are filehandles created by open() inherited by default on Windows? We could use CreateFile() which returns a handle that isn't inherited by default.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I hope to go to CreateFile and side-step this issue longer term. (As the original Windows port did.) Just didn't do that for now to minimize CPP / windows-specific code for the first version.

src/libutil/unix/environment-variables.cc Outdated Show resolved Hide resolved

auto [gens, curGen] = findGenerations(globals.profile);

RunPager pager;

for (auto & i : gens) {
#ifdef _WIN32 // TODO portable wrapper in libutil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could probably be made portable using std::chrono, though the time zone stuff is C++20.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll make this a good-first-issue follow-up task, since it is localized.

This keeps the call sites simple, eventually this should be filled in.
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]>
We don't need it now that our (minimized) Windows build of Nix succeeds!
This is a hacky solution, but it will do for now.
@Ericson2314
Copy link
Member Author

Yay this is finally approved! Fixed what things I could from the review. The rest I will create issues for.

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/nix-on-windows/1113/109

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation fetching Networking with the outside (non-Nix) world, input locking new-cli Relating to the "nix" command repl The Read Eval Print Loop, "nix repl" command and debugger store Issues and pull requests concerning the Nix store windows with-tests Issues related to testing. PRs with tests have some priority
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

7 participants