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

uv pip install gdal fails to build, with workaround (Windows) #11466

Open
maphew opened this issue Feb 12, 2025 · 12 comments
Open

uv pip install gdal fails to build, with workaround (Windows) #11466

maphew opened this issue Feb 12, 2025 · 12 comments
Labels
external The problem is with another package or dependency (not uv) question Asking for clarification or support

Comments

@maphew
Copy link

maphew commented Feb 12, 2025

Summary

I'm not sure this is actually a uv problem, but I didn't find it documented in one place anywhere so I'm doing that here. Close if there isn't anything uv should do about this scenario; the workaround will still be here for future searchers to build on.

Problem:

D:\test> uv venv --python 3.11
D:\test> uv pip install gdal

Resolved 1 package in 230ms
  x Failed to build `gdal==3.10.1`
  |-> The build backend returned an error
  `-> Call to `setuptools.build_meta.build_wheel` failed (exit code: 1)

      [stdout]
      Using numpy 2.2.2
      running bdist_wheel
      running build
      running build_py
      creating build\lib.win-amd64-cpython-311\osgeo
      copying osgeo\gdal.py -> build\lib.win-amd64-cpython-311\osgeo
[...]
      building 'osgeo._gnm' extension
      building 'osgeo._osr' extension

      [stderr]
      C:\Users\mhwilkie\AppData\Local\uv\cache\builds-v0\.tmpuXEvrM\Lib\site-packages\setuptools\config\_apply_pyprojecttoml.py:81: SetuptoolsWarning:
      `extras_require` overwritten in `pyproject.toml` (optional-dependencies)
        corresp(dist, value, root_dir)
      error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools":
      https://visualstudio.microsoft.com/visual-cpp-build-tools/

      hint: This usually indicates a problem with the package or the build environment.

Workaround solution - install a binary prebuilt wheel instead of pypi package:

  1. Open geospatial-wheels binary release page https://github.com/cgohlke/geospatial-wheels/releases/latest and copy url for:
  2. Find the binary matching your python version, cp311 is python 3.11, cp313 is py 3.13, etc.
  3. ...and matching hardware, win32, arm64, amd64
  4. feed the matching url to uv pip install
uv run python -m pip install https://github.com/cgohlke/geospatial-wheels/releases/download/v2025.1.20/GDAL-3.10.1-cp311-cp311-win_amd64.whl

Collecting GDAL==3.10.1
  Downloading https://github.com/cgohlke/geospatial-wheels/releases/download/v2025.1.20/GDAL-3.10.1-cp311-cp311-win_amd64.whl (43.9 MB)
     ---------------------------------------- 43.9/43.9 MB 17.2 MB/s eta 0:00:00
Installing collected packages: GDAL
Successfully installed GDAL-3.10.1

What could/should uv do for this scenario?

  • don't attempt to build on Windows where there isn't a tool chain (?)
  • and/or offer an info message about what to do (but maybe the setuptools message with Get it with "Microsoft C++ Build Tools" serves that well enough)
  • cache pip installs so that downloads aren't repeated

Sources:

Platform

MSYS_NT-10.0-19045 3.4.10-2e2ef940.x86_64 x86_64 Msy

Version

uv 0.5.30 (ddbc6e3 2025-02-10)

Python version

Python 3.11.11

@maphew maphew added the bug Something isn't working label Feb 12, 2025
@zanieb
Copy link
Member

zanieb commented Feb 13, 2025

Can you share verbose logs? e.g., uv pip install -v ...?

@zanieb
Copy link
Member

zanieb commented Feb 13, 2025

Oh I see, they don't publish wheels to PyPi there are just prebuilt ones elsewhere?

You can add a platform specific source URL source if you want this to work with uv sync:

I think what you're doing for uv pip install is sort of "the solution" unless you want to install the prerequisites necessary to build from source. I don't think our error message there could really be any clearer.

Ideally the project would publish wheels to PyPi, or that other project would publish the wheels under a different name or static package index.

@zanieb zanieb added question Asking for clarification or support external The problem is with another package or dependency (not uv) and removed bug Something isn't working labels Feb 13, 2025
@maphew
Copy link
Author

maphew commented Feb 13, 2025

Thanks for the feedback! Can the dependency by url be used in a pep723 style script header? I love the uv run workflow, not having to build a .toml, resulting in single file tool scripts.

@JacobJeppesen
Copy link

JacobJeppesen commented Feb 16, 2025

Edit: Realized https://girder.github.io/large_image_wheels only hosts wheels for Linux, so it doesn't work on Windows.


Generally, I think it's easier to install gdal from https://girder.github.io/large_image_wheels. I got it working with uv add --find-links https://girder.github.io/large_image_wheels gdal. However, it doesn't add the --find-links https://girder.github.io/large_image_wheels part to pyproject.toml, so it also has to be manually added when running uv sync (i.e., uv sync --find-links https://girder.github.io/large_image_wheels).

Would be great if there was a way to add the find-links part to script headers or pyproject.toml. I tried following the guide for using uv with PyTorch, but that required me to hardcode the specific .whl url. I used to use pip-tools, where find-links could be added to requirements.in like this:

--find-links=https://girder.github.io/large_image_wheels
GDAL

Would be great to see something similar with uv. Could of course also be that it's already added, and it's just me who didn't manage to get it to work 🙂

@zanieb
Copy link
Member

zanieb commented Feb 16, 2025

Can the dependency by url be used in a pep723 style script header? I love the uv run workflow, not having to build a .toml, resulting in single file tool scripts.

Yes we'll read [tool.uv] sections from those scripts too.

Would be great if there was a way to add the find-links part to script headers or pyproject.toml

https://docs.astral.sh/uv/reference/settings/#find-links

@jsmariegaard
Copy link

We would like to move all our Python users to uv instead of conda-forge. The only thing missing on Windows is GDAL which is a requirement for a lot of our users. Would be great to find a solution!

@jsmariegaard
Copy link

We would like to move all our Python users to uv instead of conda-forge. The only thing missing on Windows is GDAL which is a requirement for a lot of our users. Would be great to find a solution!

GDAL binary wheels can be found on https://github.com/cgohlke/geospatial-wheels and you can use this low-level solution

$ uv pip install https://github.com/cgohlke/geospatial-wheels/releases/download/v2025.1.20/GDAL-3.10.1-cp313-cp313-win_amd64.whl

But how do you get a better uv-native solution using uv add/sync etc?

@zanieb
Copy link
Member

zanieb commented Feb 17, 2025

As mentioned above, it sounds like

[tool.uv]
find-links = "https://girder.github.io/large_image_wheels"

should work?

@JacobJeppesen
Copy link

Sorry, that was my fault. They only host wheels for Linux on https://girder.github.io/large_image_wheels. I thought they hosted for more platforms. It does work really well on Linux when adding find-links to pyproject.toml though 👍

@zanieb
Copy link
Member

zanieb commented Feb 17, 2025

I see. I'm sorry to say this is a problem with the package — there's not much we can do here.

See #11466 (comment) for adding the link to the wheel to your pyproject.toml

@jsmariegaard
Copy link

I wonder if @cgohike could create a flat list of links to package files as requires by https://docs.astral.sh/uv/reference/settings/#find-links 🤔 Then I guess we would be good to go. @zanieb, the regular release assets in https://github.com/cgohlke/geospatial-wheels/releases cannot be used in find-links, right? (I could not get it to work)

@maphew
Copy link
Author

maphew commented Feb 17, 2025

The 2nd script below will build the flat list of links from a Github assets list, uv run list_github_assets.py > asset-links.txt, but I haven't figured out how to feed that to uv run.

re: #11466 (comment), what is the syntax using [uv.tool] in the script header? This is closest I've gotten is below, but it emits "expected struct ToolUv". I get zero internet search results on that phrase and don't know what to do with it.

test-gdal.py:

# /// script
# requires-python = ">=3.8"
# dependencies = [
#   "gdal",
# ]
# tool.uv = [
#    "find-links = file://asset-links.txt"
#    ]
# ///
print('hi!')

yields:

 uv run test-gdal.py
error: TOML parse error at line 5, column 11
  |
5 | tool.uv = "find-links = file://asset-links.txt"
  |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
invalid type: string "find-links = file://asset-links.txt", expected struct ToolUv

list_github_assets.py:

# /// script
# requires-python = ">=3.8"
# dependencies = [
#     "httpx",
# ]
# ///
import sys
import httpx

def fetch_assets(repo: str):
    """Fetch asset URLs from the latest GitHub release."""
    url = f"https://api.github.com/repos/{repo}/releases/latest"

    response = httpx.get(url, timeout=10)
    response.raise_for_status()
    assets = response.json().get("assets", [])

    for asset in assets:
        print(asset["browser_download_url"])

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage:  uv run list_github_assets.py <PROJECT/REPO>\n\t", file=sys.stderr)
        print("uv run list_github_assets.py cgohlke/geospatial-wheels", file=sys.stderr)
        sys.exit(1)

    fetch_assets(sys.argv[1])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
external The problem is with another package or dependency (not uv) question Asking for clarification or support
Projects
None yet
Development

No branches or pull requests

4 participants