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

Improve build/install instructions for Windows #124

Open
nlfiedler opened this issue Jun 1, 2024 · 7 comments
Open

Improve build/install instructions for Windows #124

nlfiedler opened this issue Jun 1, 2024 · 7 comments

Comments

@nlfiedler
Copy link
Owner

The existing instructions are not adequate to build this crate on Windows. I will soon submit a change that helps, but still isn't completely satisfying because one of the bindings unit tests fails (size of long double). I'm hoping someone like @gyk can offer some insight. Questions I have:

  1. Assuming the use of MSYS2, how to get clang such that the unit tests pass? I see the github action for testing on Windows, but I don't get how everything is set up (where is clang?).
  2. Is it necessary to set IMAGE_MAGICK_INCLUDE_DIRS to include the path to mm_malloc.h because without that, the build fails to find that header file. This is unlike on other platforms, which is why I wonder if I'm doing something wrong.
  3. I added instructions using MSYS2 to the INSTALL.md file, if those need fixing, please let me know.

Hoping someone who knows Windows better than I (who only really uses it for video games) can help.

Other concerns I have: can we possibly build this crate on Windows without introducing a Unix-like environment? For instance, using the Visual Studio Installer should suffice, but it installs a 32-bit version of Clang, which is like WTF. Hard to image how people use Windows for anything other than C# development.

@5ohue
Copy link
Contributor

5ohue commented Jun 1, 2024

That would be very handy!

@5ohue
Copy link
Contributor

5ohue commented Jun 1, 2024

The MSYS instructions worked! What a timing, just as I started to try to compile it on windows and have issues, you added the instructions. Thanks!

@gyk
Copy link
Contributor

gyk commented Jun 2, 2024

Hi,

  1. In Support building with ImageMagick from MSYS2 #114 I chose mingw64 environment, but we should switch to ucrt64 as it causes fewer compatibility issues. Please see this commit. Most unit tests in v0.19 except test_set_background_color will pass.

    one of the bindings unit tests fails (size of long double)

    Which one is it?

    Regarding to clang, LLVM is preinstalled in the GitHub Actions runner image so it is already usable.

  2. Never come across any problems related to mm_malloc.h.


can we possibly build this crate on Windows without introducing a Unix-like environment?

Of course we can. I believe MSYS2 support was added to address this use case: Some application needs to be released on multiple platforms, and may require a custom build of ImageMagick. Unfortunately ImageMagick uses separate instructions to build natively on Windows and it looks complicated, in this case, using MSYS2 is preferable.

@gyk
Copy link
Contributor

gyk commented Jun 2, 2024

The following may be helpful for someone trying to build this crate against MSYS2.

As other Unix-like environments, there are two approaches for MSYS2:

  1. Set up everything manually:

    $env:PATH = "C:\msys64\usr\bin;C:\msys64\ucrt64\bin;$env:Path"
    $env:IMAGE_MAGICK_DIR = "C:\msys64\ucrt64"
    $env:IMAGE_MAGICK_INCLUDE_DIRS = "C:\msys64\ucrt64\include\ImageMagick-7"
    $env:IMAGE_MAGICK_LIB_DIRS = "C:\msys64\ucrt64\lib"
    $env:IMAGE_MAGICK_LIBS = "libMagickCore-7.Q16.dll.a;libMagickWand-7.Q16.dll.a"
  2. Just rely on pkg-config to resolve the configuration:

    $env:PATH = "C:\msys64\usr\bin;C:\msys64\ucrt64\bin;$env:Path"
    $env:IMAGE_MAGICK_LIBS = "libMagickCore-7.Q16.dll.a;libMagickWand-7.Q16.dll.a"

Please note that the order in $env:PATH is important. C:\msys64\usr\bin appears first to make sure MSYS2's sh takes precedence over other sh.exe installed in the system. C:\msys64\ucrt64\bin introduces essential commands like pkg-config and MagickCore-config.

@5ohue
Copy link
Contributor

5ohue commented Jun 2, 2024

Also, after I built a rust project with this library, it works fine when its run from the MSYS2 MINGW64 shell. But running a compiled executable directly without the mingw64 envirenment (just running it from CMD.exe for example) causes NoDecodeDelegateForThisImageFormat 'PNG' @ error/constitute.c/ReadImage/746 error to appear. That makes me think image magick maybe relies on some env variables to find the libraries. Not sure what I could do.

Maybe something about shipping the executable on windows should be added to INSTALL.md, since you cannot just ask users to "sudo apt install libeverthing-thats-needed", windows has a funny way of installing software :) and just putting all dlls in the same folder as the .exe doesn't seem to work (it gives errors like the one I have with PNGs not opening)

@gyk
Copy link
Contributor

gyk commented Jun 4, 2024

@5ohue The env variable is MAGICK_CODER_MODULE_PATH. Without it ImageMagick will try to read coder path from the registry. However, if you're willing to build ImageMagick from scratch, coder modules can be disabled by passing --without-modules to configure.

@5ohue
Copy link
Contributor

5ohue commented Jun 15, 2024

@nlfiedler I think I found a way to compile, run and destribute an application that uses magick-rust. It requires using MSYS2 to compile, but the final executable doesn't require users to install anything additional. Here's how it worked for me:

  1. I installed MSYS2 and the needed packages. Unfortunately I don't currently have a nice list of packages. I used MINGW64 packages instead of UCRT64 (the latter doesn't work for some reason). So I installed packages like mingw-w64-x86_64-imagemagick, mingw-w64-x86_64-rust and probably some more. I can try to get a nice list of packages later.
  2. I opened powershell and ran these commands (thank a lot @gyk!):
$env:PATH = "C:\msys64\usr\bin;C:\msys64\mingw64\bin;$env:Path"
$env:IMAGE_MAGICK_DIR = "C:\msys64\mingw64"
$env:IMAGE_MAGICK_INCLUDE_DIRS = "C:\msys64\mingw64\include\ImageMagick-7"
$env:IMAGE_MAGICK_LIB_DIRS = "C:\msys64\mingw64\lib"
$env:IMAGE_MAGICK_LIBS = "libMagickCore-7.Q16HDRI.dll.a;libMagickWand-7.Q16HDRI.dll.a"
  1. I cded into the crate's directory and built the project (cargo build --release or cargo install --path . or any other way to build a crate). It compiles fine here for me.
  2. I copied all the dynamic libraries the executable is linked to. I did that by running this command from inside of MSYS2 shell: ldd <PATH TO EXECUTABLE>.exe | awk '{print ($3)}' | grep "^/mingw64" | xargs -I FILE cp FILE lib/. The lib folder now contains all the DLL files.
  3. I created the app folder. The folder structure is this:
<APP NAME>\
    bin\
        *.dll
        <EXECUTABLE>.exe
    lib\
        ImageMagick-7.1.1\

So basically I copied all the DLL files and executable to bin\ folder (and also some additional DLLs for extra file formats, like libjpeg-8.dll file for example. The application isn't directly linked to that, so ldd cannot know about it).
To bin\ folder I copied the ImageMagick-7.1.1 folder from C:\msys64\mingw64\lib.
6. Now opening powershell and running the executable works without having to tinker with path or anything else. The <APP NAME> can now be packaged and shared to other computers, and the executable can be run without problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants