what is midipix, and how is it different?
midipix is a development environment that lets you create
programs for Windows using the standard C and POSIX APIs. No
compromises made, no shortcuts taken.
If you are interested in cross-platform programming that
reclaims the notion of write once, compile everywhere; if you
believe that the 'standard' in the C Standard Library should
not be a null signifier; and if you like cooking your code
without #ifdef hell and low-level minutiae, then this page is
for you.
midipix makes cross-platform programming better, simpler and
faster, specifically by bringing a modern, conforming C Runtime
Library to the Windows platform. While the idea itself is not
new, the approach taken in midipix to code portability is
radically different from that found in other projects.
- layering and modularity
- midipix fosters true separation between the POSIX
system call layer and the C runtime library. In other
projects that provide a POSIX programming environment,
such as cygwin and SUA/Interix, there is no practical way
to tell the (2) from the (3), and one often finds that the
system call interface, e.g. poll(2), is unified with its
respective libc function. Although closely related, C and
POSIX are two independent standards that evolve differently
and at a different pace. Between the two, midipix focuses
on the part that is painfully missing on Windows, namely
the POSIX system call layer.
- complete, fast, and robust
- The midipix system call layer is written using the
Windows Native API, this including the implementation of
sockets, pseudo-terminal file descriptors, job control,
path resolution, inter-process communication, and virtual
mount system. The use of the Native API provides key
performance increases, most notably when compared with
cygwin, and the completeness of the system call layer
provides a true advantage over msys and mingw.
Additional features that distinguish midipix from cygwin
and mingw include a copy-on-write fork, the native
implementation of thread- and process-creation, the native
handling of utf-8 in system call arguments, and the use of
fast LPC for signals, session-management, and locking
arbitration.
- easy distribution
- midipix supports both static and dynamic linking; there
are no assumptions about the directory structure on the
end-user machine, and unlike SUA/Interix, no special
installation of a Windows component is required. Midipix
applications running on the same system are completely
independent of one another; as opposed to cygwin there is
no arbitrary inherited state between two unrelated
applications, and the crashing or misbehavior of one
application can in no direct way affect another. The one
intentional exception to the rule is that of POSIX
sessions, where you would want such inheritance and
integration to take place. For instance, you would want an
application created via fork(), execve(), or posix_spawn()
to inherit its file descriptors (and in the case of fork()
also address space) from its parent, and would likewise
want termination of a child application to cause a SIGCHLD
signal to be sent to the parent. In all other cases,
however, midipix applications would only interact with one
another if you so desire (using your favorite method of
IPC), thus making both distribution and debugging
considerably easier.
- flexible execution environment
- midipix applications are part of the native Windows
subsystem; unlike SUA/Interix there is no need for special
kernel support, yet double-clicking a midipix application
will never open a terminal window against your will, as in
the case of msys or cygwin. At the same time, and similar
to other unix-like systems, midipix applications that are
started from within a terminal session can automatically
take advantage of job control, (pseudo-)terminal signals,
and standard input and output.
- a modern libc of your choice
- Whereas cygwin is paired with newlib, mingw depends on
msvcrt, and SUA mandates its own C library, the midipix
system call layer (psxscl) is not tied to any particular
libc, and may thus be used for porting several different
implementations. The midipix libc of choice, however, is
musl: a modern libc implementation that puts special
emphasis on portability and correctness, and which provides
complete, high-quality, and exceptionally robust pthread-
and C11 support. The musl developers and users in general,
and the project architect Rich Felker in particular, have
been tremendously helpful in shaping the direction of the
midipix project, and have provided invaluable tips,
suggestions, and technical feedback. A tiny set of files
that bridge between an application's entry point and
musl's __libc_start_main, the midipix musl-glue files turn
NT into just another supported system, and may also be used
as a model for porting additional libc's to Windows.
- portability from below
- Rather than porting a POSIX C library by way of
modification, midipix renders porting easy by satisfying
the libc's largest (and often only) dependency, namely the
system call layer. In doing so, midipix follows the design
of musl libc, where about 99% of the code base is shared
between platforms, and where the few low-level,
architecture-specific bits remain transparent to
application and library authors. There are several clear
advantages to that approach, most notably with respect to
sustainability and reliability; sustainability, since
maintaining the system call layer does not require
maintaining a libc on top of it; and reliability, since
every single function in the libc gets tested and reviewed
by a large number of users in a variety of platforms.
Then again, there is virtually no lag between the
introduction of a feature to the libc, and its availability
on Windows, and it is likewise easy to switch between
different version of the C library for testing purposes.