pythonmakefilealpine-linuxpsutil

use 'pip install psutil' on docker image python:3.9.13-alpine3.16 error: linux/ethtool.h not found


I tried to install python module psutil in docker python:3.9.13-alpine3.16
But it reported the following mistake:

Building wheels for collected packages: psutil
  Building wheel for psutil (pyproject.toml) ... error
  error: subprocess-exited-with-error
  
  × Building wheel for psutil (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [51 lines of output]
      /tmp/tmpb62wij4i.c:1:10: fatal error: linux/ethtool.h: No such file or directory
          1 | #include <linux/ethtool.h>
            |          ^~~~~~~~~~~~~~~~~
      compilation terminated.
      running bdist_wheel
      running build
      running build_py
      creating build
      creating build/lib.linux-x86_64-cpython-39
      creating build/lib.linux-x86_64-cpython-39/psutil
      copying psutil/__init__.py -> build/lib.linux-x86_64-cpython-39/psutil
      copying psutil/_common.py -> build/lib.linux-x86_64-cpython-39/psutil
      copying psutil/_compat.py -> build/lib.linux-x86_64-cpython-39/psutil
      copying psutil/_psaix.py -> build/lib.linux-x86_64-cpython-39/psutil
      copying psutil/_psbsd.py -> build/lib.linux-x86_64-cpython-39/psutil
      copying psutil/_pslinux.py -> build/lib.linux-x86_64-cpython-39/psutil
      copying psutil/_psosx.py -> build/lib.linux-x86_64-cpython-39/psutil
      copying psutil/_psposix.py -> build/lib.linux-x86_64-cpython-39/psutil
      copying psutil/_pssunos.py -> build/lib.linux-x86_64-cpython-39/psutil
      copying psutil/_pswindows.py -> build/lib.linux-x86_64-cpython-39/psutil
      creating build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/__init__.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/__main__.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/foo.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/runner.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_aix.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_bsd.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_connections.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_contracts.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_linux.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_memleaks.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_misc.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_osx.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_posix.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_process.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_sunos.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_system.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_testutils.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_unicode.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      copying psutil/tests/test_windows.py -> build/lib.linux-x86_64-cpython-39/psutil/tests
      running build_ext
      building 'psutil._psutil_linux' extension
      creating build/temp.linux-x86_64-cpython-39
      creating build/temp.linux-x86_64-cpython-39/psutil
      gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -DTHREAD_STACK_SIZE=0x100000 -fPIC -DPSUTIL_POSIX=1 -DPSUTIL_SIZEOF_PID_T=4 -DPSUTIL_VERSION=591 -DPSUTIL_LINUX=1 -DPSUTIL_ETHTOOL_MISSING_TYPES=1 -I/usr/local/include/python3.9 -c psutil/_psutil_common.c -o build/temp.linux-x86_64-cpython-39/psutil/_psutil_common.o
      gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -DTHREAD_STACK_SIZE=0x100000 -fPIC -DPSUTIL_POSIX=1 -DPSUTIL_SIZEOF_PID_T=4 -DPSUTIL_VERSION=591 -DPSUTIL_LINUX=1 -DPSUTIL_ETHTOOL_MISSING_TYPES=1 -I/usr/local/include/python3.9 -c psutil/_psutil_linux.c -o build/temp.linux-x86_64-cpython-39/psutil/_psutil_linux.o
      psutil/_psutil_linux.c:19:10: fatal error: linux/version.h: No such file or directory
         19 | #include <linux/version.h>
            |          ^~~~~~~~~~~~~~~~~
      compilation terminated.
      error: command '/usr/bin/gcc' failed with exit code 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for psutil
Failed to build psutil
ERROR: Could not build wheels for psutil, which is required to install pyproject.toml-based projects

Recurrence process:

  1. docker pull python:3.9.13-alpine3.16
  2. docker run --name alpine-python3 -it [image-id] /bin/sh
  3. (In container)# apk add build-base
  4. (In container)# pip install psutil

Key Error:

/tmp/tmpb62wij4i.c:1:10: fatal error: linux/ethtool.h: No such file or directory  
          1 | #include <linux/ethtool.h>  
            |          ^~~~~~~~~~~~~~~~~  
  
psutil/_psutil_linux.c:19:10: fatal error: linux/version.h: No such file or directory  
         19 | #include <linux/version.h>  
            |          ^~~~~~~~~~~~~~~~~  
      compilation terminated.  
      error: command '/usr/bin/gcc' failed with exit code 1  

So, what do I need to pre-install in advance to fix? Thanks!


Solution

  • You need to add the linux-headers package.

    apk add build-base linux-headers
    python -m pip install psutil
    

    Update 0

    Great, you need the linux-headers package. But, why do you need the linux-headers package?

    This package provides data structures and the signatures for functions in the kernel source. This information is required in order to compile modules which call these functions. We don't need the actual source code, just the specification, the interface, if you will. This is the information psutil needs in order to use the host OS's network utility, for instance.

    Why separate this from the implementation? Today, for personal computers, it's largely unnecessary. But, this was very useful back when storage was much smaller and much more expensive. No need to keep the entire kernel source around when all you're doing is building a module which calls some function in ethtool.

    Generally, any time you're building a module which interacts with the linux OS, you're going to need linux-headers installed.