openzfsonwindows / ZFSin

OpenZFS on Windows port
https://openzfsonwindows.org
1.2k stars 68 forks source link

Starting on new port #309

Open lundman opened 3 years ago

lundman commented 3 years ago

So looking at the re-organisation of files to fit in with OpenZFS 2.0 repo.. no code changes, just a bunch of renaming, and moving functions around between files.

But it would be nice to get some comments.

*) There are currently two build systems, the (Windows) make files, and devstudio projects. Is it common to maintain two build systems? Can they be made from the other? Can devstudio import makefiles, or, create a solution that just runs the makes?

*) clang now optionally ships with devstudio. Would it be acceptable to switch default build to clang? It would simplify quite a few things. Can it be done as a selection in devstudio? Where you pick x64/x32/arm/clang_x64 ?

*) I'm not a fan of how you define the macros for build, like we set _KERNEL, DEBUG, __LP64, in devstudio properties - It would fit better like upstreams "-include zfs_config.h". Which clang supports, but perhaps not MSVC++.

Would any of these decisions impact you? What is the "norm" for Windows dev? What we have in ZFSin works, but here's a chance to change things, should there be better ways.

nazar554 commented 3 years ago

1) Developers working with Windows drivers have more experience with VS project files than CMake or any other build system. Also driver verifier and other static analysis tools can't run from VS when using a CMake project 2) Clang can't be used for building Windows drivers, a lot of WDK headers are not compatible (contain various #pragmas, etc..). Could be used for userspace tools though, it's available as a MSBuild toolset if using VS project files 3) MSVC and clang cl.exe both support /FI flag. But usually this is done by using Property Pages (.props) files instead.

lundman commented 3 years ago

Been working on this for a couple of weeks, and the cmake stuff now compiles the kernel section. But I noticed I don't appear to be able to "deploy" to the target-VM from VC when it is in CMake style, so that is a bit of a show stopper.

lundman commented 3 years ago

OK so, it seems I can use Cmake files to produce vcproj files, using:

cmake -DCMAKE_BUILD_TYPE=x64-Debug -G "Visual Studio 16" -A x64 -B contrib/windows  -T ClangCL -DCMAKE_C_COMPILER="C:/Program Files/LLVM/bin/clang-cl.exe" -DCMAKE_CXX_COMPILER="C:/Program Files/LLVM/bin/clang-cl.exe"

and loading that .sln into VC. Which would take care of debugging and deploying. However, I see that the "clang can't make drivers" is now an issue.

If I play with the produced project files, it will use clang fine, but only to generate an "application". The answer there is possibly to have cmake generate all the libs (libkernzfs, libkernspl, ...) with clang, and finally compile driver.c with MSVC++ to make the .sys file. I'm not entirely sure if I can mix toolsets in cmake. (cleanly?)

lundman commented 3 years ago

OK, flipping it around, the module will use MSVC cl.exe to compile, and each library, as in spl, zfs, spi etc, has:

set(CMAKE_C_COMPILER clang-cl.exe)
set(CMAKE_CXX_COMPILER clang-cl.exe)

which compiles the libs with clang, makes porting easy. Then for driver.c it uses MSVC, and link. That appears to work.

I do wonder if I can make that cleaner, since I have to put those lines in 10 odd files, and there are a few compiler options to set. Wonder if CMake can do functions from toplevel file and I can just "SetClangCompiler" or something, so there isn't so much repetition.

nazar554 commented 3 years ago

@lundman Not sure if it's legal in CMake. Clean way would be to have two root CMakeLists.txt project files (one with libraries built using clang-cl.exe and separate one (built with cl.exe)) then link them together ExternalProject_Add

I am not sure why clang can't build .sys files, isn't that on CMake target SUFFIX option?

lundman commented 3 years ago

In stackoverflow they said:

The main flag that makes this possible is "/DRIVER":

https://docs.microsoft.com/en-us/cpp/build/reference/driver-windows-nt-kernel-mode-driver?view=msvc-160

And clang-cl doesn't support that yet:

https://clang.llvm.org/docs/UsersManual.html#clang-cl

Perhaps consider filing a ticket for /DRIVER support from clang-cl?

Two top level cmakes? How does that work, it just automatically builds both, figuring out dependency? What names do the files have?

nazar554 commented 3 years ago

Isn't /DRIVER a linker flag? So if it's possible to force linker to be link.exe it should work (CMake is likely using clang-cl or lld-link by default)?

There is /KERNEL which is not supported, but I think it can ve replaced with equivalent separate flags.

lundman commented 3 years ago

Could be just linking would work, but I discovered the cmake -G "Visual Studio" generated projects files are wrong, made as "Application" and not kernel extension - and I don't see a way to "add" kernel debugger parts, so I can not deploy. Not entirely sure what to do about it. Wondering if I can make a shell project now that just deploys an already built .sys file. (build by cmake, then just deploy from project files).

aviksildc commented 3 years ago

@lundman do you have a release plan for this new port given that the upstream OpenZFS 2.0 is planned to be released this month?

lundman commented 3 years ago

OKOK I could not get any of those things to work. But for now, top level CMake to build openzfs.sys. This will be enough for most. Then for VS to deploy, I made a "mostly empty" vcxproj, compiling just driver.c (debug.c, Wpp.c), and uses the CMake libs to link. There is a tiny chance those three files could be compiled differently (msvc++ vs clang) but I can live with that. (link.exe is used by both). Then upstream will only add new files by editing the cmakelists.txt. I will test first deploy tomorrow.