-
Notifications
You must be signed in to change notification settings - Fork 73
Windows Build #88
Comments
Nobody has mentioned to me that they are working on a Windows port. A Win32 client would be the easiest for people to install and use. It should be possible to run Curv under WSL, if your X server supports OpenGL and the GLX protocol. You'll need to read documentation and enable GLX in your X server. I haven't tried this.
If you get it working, please let me know which X server you used. It would be nice to document the setup process. In the future, Microsoft says that WSL 2 will support direct hardware GPU access, no need to resort to a Win32 X server. There's no schedule for this. https://docs.microsoft.com/en-us/windows/wsl/wsl2-faq In the future, I plan to have a WASM port of Curv. I imagine we could have a GUI-only WASM demo this year, and a fully functional client with mesh export next year. A WASM client running in a web browser will probably never match the performance of a native client. Mesh export is hard, because it is unacceptably slow unless you use the |
I see.
Re native build: I see! What would be the best way to start making adjustments for a native build? Should I just try the commands inside the Makefile on Windows? I guess libraries are dealt with wholly different on Windows. |
vcxsrv is another popular choice of X server. I found a report of somebody getting this same GLFW error using vcxsrv, plus they figured out how to fix it: alecjacobson/computer-graphics-bounding-volume-hierarchy#43 quote: "I fixed it with disabling the native opengl when starting VcXsrv." quote:
|
Good news! I followed the instructions for installing and configuring vcxsrv, and Curv is working for me in WSL + Ubuntu 18.04. |
The bad news is, 3D rendering is quite slow. WSL does not provide direct access to the GPU hardware, so Ubuntu Linux defaults to software rendering. Unfortunately, this can't be fixed until Microsoft updates WSL to support hardware GPU access. DetailsHere's what goes wrong in more detail. Curv uses the X window system, and uses GLX to interface with OpenGL. GLX supports two modes of operation: "direct" and "indirect".
Running Curv using Direct GLXTo run Curv using direct GLX, you must disable indirect GLX in the X server:
This works, but rendering is slow. The command
which indicates that software rendering is being used (llvmpipe is a software renderer). Running Curv using Indirect GLXTo run Curv using indirect GLX, you must enable indirect GLX in the X server and in the client. In the X server, enable indirect GLX like this:
In the Linux bash shell (the client), set the environment variable
If I do this on my machine, then
The good news is that the X server is now reporting my GPU hardware (HD Graphics 5500). If I run |
@ComFreek Okay, I'm disappointed by WSL, the performance of software rendering isn't that great. So a WIN32 port looks like it would provide value. |
Thanks for your further investigations and explanations! I decided to try native compilation with msys2. At the moment I get some compilation errors, perhaps you could help.
// Ignore these:
I get the following compilation errors:
I get similar errors with
|
The above compiler error should be fixed by commit 1653b19. |
Thanks, that fixed the error. I now get some other errors stemming from the fact that I'll post a link to my fork soon when everything compiles. Clang: if desired to use Clang, be sure to pass |
@doug-moen It compiles! (But doesn't link.) My fork is here: master...ComFreek:master. Apart from the modifications to the submodules below, this changeset highlights all the places which need adjustment for portability. As I lack knowledge, I cannot work on it without further advice from you. Perhaps it would be the fastest if you worked on it (?) Additionally, you need the following modifications in some submodules:
Compiles fine, only with some seemingly straightforward link errors:
|
@ComFreek Thanks for running this experiment. I can see two paths to porting Curv to Win32.
We have to consider the impact of use-cygwin vs use-win32 on each of my dependencies. For use-cygwin, does each dependency compile and run using Cygwin? For use-win32, does each dependency compile and run on Win32? Here are my dependencies:
All of my current dependencies support use-win32 and can be compiled against the WIN32 API, based on the fact that they all have #ifdef _WIN32 code in them. Some of my dependencies fail to compile on Cygwin: replxx, openvdb. So with use-cygwin, we'd have to fix these problems and submit patches to upstream. One thing that bothers me about Cygwin is that it isn't POSIX and it isn't WIN32. Instead, it is some weird and undocumented hybrid of the two. You don't follow a spec to program against it, you just compile and run your code and debug it until all of the Cygwin weirdness has been fixed. Win32 is a terrible API, but it has the advantage of being stable and well documented. Can a hybrid approach work? Like, use-cygwin for the Curv source code, and use-win32 for all my dependencies? I don't know. The problem is header files. I'd be mixing use-cygwin and use-win32 header files in the same Curv source files, and there might be conflicts. It seems like use-win32 is the safe approach, and would avoid heroic reverse engineering efforts to debug conflicts between posix, cygwin and win32 APIs. Like, figuring out what is causing the current compile errors. The work involved would be identifying Curv code that is posix-dependent, and rewriting it to use portability abstractions. We could use the Boost library for most of the portability abstractions. That one place where I compile a curv program into a native code executable file, then load the file into memory and execute it, is likely resistant to any portability abstraction, so we'll just have a separate Win32 implementation for that. Then, the next question is what compiler to use on Windows. People who do all their development on Windows use MS Visual C++. But that compiler is weird, and doesn't behave the same as gcc and clang. I think it is safest to use gcc or clang, in terms of compatibility with the Curv source and all my linux-friendly dependency libraries. I don't have any personal experience doing an open source Windows port. What do you think? |
I second use-win32, possibly with a wrapper library (e.g. Boost), and with a Linux-style build environment (msys2 + gcc/clang, not MSVC).
In particular, I would not even know how to install the libraries for compiling on Windows.
I already identifier most of this code, I suppose. See my fork changeset. One of the biggest things is that I think I'll work on that linker errors first. |
I suggest that the first step is to adjust your build environment, revert all the source code changes that you made previously, and then build Curv in Win32 mode. You will get more compile errors than with MSYS2/Cygwin: that is expected. All of the dependencies that I compile from source are in the extern directory. Ideally there are no Win32 compile errors in any of the extern subdirectories. The dependency that most worries me is openvdb. It is the biggest and most complex of my source dependencies. It isn't necessary to compile it from source. If we have problems compiling it, the solution is to grab a pre-compiled copy of the openvdb library from the openvdb project, or from a Windows package manager. The problem with boost::filesystem::path::c_str() returning a wchar_t* is not hard to solve. The short answer is to use path.string().c_str() instead. Documentation is here: https://www.boost.org/doc/libs/1_72_0/libs/filesystem/doc/reference.html#class-path |
I don't understand this. I thought I did this. |
I want you to do a native Windows build, not a Cygwin build. This means building Curv on Windows without the Cygwin headers, or the Cygwin library, and without defining My understanding is that if you download MinGW-w64 But if you use MSYS2, then you are doing a Cygwin build. MSYS2 contains MinGW-w64, plus the cygwin libraries and headers, plus other stuff. I just read some of the MSYS2 documentation, and found this paragraph:
So maybe what you need to do is build Curv using the "mingw shell" instead of the "msys2 shell". Does that make sense? |
My notes on building Antimony as a native Windows app may be relevant – the specific shell that you're looking for is the "MSYS2 MinGW 64-bit" shell. |
Thanks for the replies. Currently, I cannot find the time to do this, so at least from my side this needs to be postponed a few weeks perhaps. |
Due to the unfortunate situation caused by COVID-19, I had more spare time than expected: tl;dr: @doug-moen Compilation works, linking fails due to lots of undefined references to OpenVDB stuff. Do you have any ideas?
So far, it compiles fine in step 4, but it fails to link with the same errors as above:
Actually, running
Differences to the actual command line run by
That linker command I run in the
If I didn't miss anything, all linker errors are caused by undefined references to OpenVDB stuff. |
https://stackoverflow.com/questions/22766540/semantics-of-imp-symbols The build file I wrote for Curv (CMakeLists.txt) contains this line:
Note that the dependency is on Note that |
Thanks, that was a very good hint! I now succeeded in building Curv as follows:
Caveats:
|
Thanks, @ComFreek, that's good news. I looked at your changes, so here are some comments. In general, I think it is okay to use
in C++ code, in those few places where no better alternative exists. That's the technique used by most of my dependencies. MinGW is documented to define _WIN32. The change from There are many code changes related to strings, paths and filename strings. All of the affected lines of code can be changed to be portable between Windows and POSIX, without ifdefs, and without using the wchar_t* type. See https://www.boost.org/doc/libs/1_72_0/libs/filesystem/doc/reference.html#class-path.
The other nonportable C++ Curv code can initially be ported using I notice you have a private fork of replxx. That library is already portable to Windows, and it uses #ifdef _WIN32 for non-portable code. The goal is to use the replxx git repository directly without maintaining a local fork. I'm using a version locked submodule to reference replxx; I can update to the latest release and that might fix some Windows portability bugs. If there are further problems then the fix can be pushed to the replxx repo: the owner is quite responsive. I notice you have a private fork of openvdb. This is a large, complex library maintained by a large organization. I don't want to maintain a private fork. They already support a Windows build. Looking at the code and documentation, they use Microsoft Visual C++ to build the library. They don't use |
Good! I'll work on converting my dirty changes to real portable code following your suggestions.
Yes, they were just meant to contain my quick & dirty "fixes" as of now. In the long run, I wanted to submit upstream patches, too.
If I read correctly, this is something you want to look into, it seems from your wording. I hope that'll work without ABI incompatilibities. |
To clarify about openvdb: It is a large complex library, and there are bureaucratic barriers to submitting changes (you have to sign a CLA). I think it will be less work for you if you install the openvdb library using pacman (header files and DLL). You'll be installing version 7.x, so you will need to compile Curv using the pacman installed openvdb header files. The reason I stopped using the preinstalled OpenVDB library on Linux was to work around a problem with Gentoo Linux installing an old and incompatible version of OpenVDB: see #16 |
Wohoo, Curv now works on Windows! E.g. Also, it has access to my "graphics card" (I don't have any dedicated one):
I will now prepare a PR. Would you like to still retain openvdb compiled as a submodule for non-Windows OSes? |
Wow, that is fantastic news! I still need to compile openvdb as a submodule in order to build Curv on Gentoo Linux, so the answer to your question is yes. |
#89 did it! |
Latest update: curv has now Windows support merged into master!
I would like to give Windows builds a shot. Has there been any previous failure or success stories?
Describe the solution you'd like A native Windows build capable of accessing the GPU on Windows.
Describe alternatives you've considered
WSL: apparently there isn't any host's GPU exposure within WSL yet, so we could only software-render here.
Nonetheless, I am currently trying out this route.
Build successful
Running CLI successful (e.g.
curve -x 2+2
)Running GUI not successful:
Even though I do have an X server on my Windows host, which works fine with other GUI applications within WSL.
Browser: I read on the mailing list that someone is working on a wasm build for the web. If that turns out to have good performance, do we actually need a Windows build?
The text was updated successfully, but these errors were encountered: