How to fix PlatformIO pio remote agent start: fatal error: ffi.h: No such file or directory
Problem:
When running pio remote agent start
, during the package installation process, you see an error log like
ERROR: Command errored out with exit status 1:
command: /home/pi/.platformio/penv/bin/python /tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip install --ignore-installed --no-user --prefix /tmp/pip-build-env-z_7hwbt9/overlay --no-warn-script-location --no-binary :all: --only-binary :none: -i https://pypi.org/simple --extra-index-url https://www.piwheels.org/simple -- 'setuptools>=40.6.0' wheel 'cffi>=1.12; platform_python_implementation != '"'"'PyPy'"'"'' 'setuptools-rust>=0.11.4'
cwd: None
Complete output (284 lines):
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple, https://www.piwheels.org/simple
Collecting setuptools>=40.6.0
Using cached setuptools-59.3.0.tar.gz (2.3 MB)
Getting requirements to build wheel: started
Getting requirements to build wheel: finished with status 'done'
Installing backend dependencies: started
Installing backend dependencies: finished with status 'done'
Preparing metadata (pyproject.toml): started
Preparing metadata (pyproject.toml): finished with status 'done'
Collecting wheel
Using cached wheel-0.37.0.tar.gz (65 kB)
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting cffi>=1.12
Using cached cffi-1.15.0.tar.gz (484 kB)
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting setuptools-rust>=0.11.4
Using cached setuptools-rust-1.0.0.tar.gz (279 kB)
Installing build dependencies: started
Installing build dependencies: still running...
Installing build dependencies: still running...
Installing build dependencies: still running...
Installing build dependencies: still running...
Installing build dependencies: still running...
Installing build dependencies: finished with status 'done'
Getting requirements to build wheel: started
Getting requirements to build wheel: finished with status 'done'
Installing backend dependencies: started
Installing backend dependencies: finished with status 'done'
Preparing metadata (pyproject.toml): started
Preparing metadata (pyproject.toml): finished with status 'done'
Collecting pycparser
Using cached pycparser-2.21.tar.gz (170 kB)
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting tomli>=1.2.1
Using cached tomli-1.2.2.tar.gz (15 kB)
Installing build dependencies: started
Installing build dependencies: finished with status 'error'
ERROR: Command errored out with exit status 2:
command: /home/pi/.platformio/penv/bin/python /tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip install --ignore-installed --no-user --prefix /tmp/pip-build-env-e79tjyp1/overlay --no-warn-script-location --no-binary :all: --only-binary :none: -i https://pypi.org/simple --extra-index-url https://www.piwheels.org/simple --extra-index-url https://www.piwheels.org/simple -- 'flit_core>=3.2.0,<4'
cwd: None
Complete output (60 lines):
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple, https://www.piwheels.org/simple, https://www.piwheels.org/simple
Collecting flit_core<4,>=3.2.0
Using cached flit_core-3.5.1.tar.gz (27 kB)
Getting requirements to build wheel: started
Getting requirements to build wheel: finished with status 'done'
Preparing metadata (pyproject.toml): started
Preparing metadata (pyproject.toml): finished with status 'done'
Collecting tomli
Using cached tomli-1.2.2.tar.gz (15 kB)
ERROR: Exception:
Traceback (most recent call last):
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/cli/base_command.py", line 164, in exc_logging_wrapper
status = run_func(*args)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/cli/req_command.py", line 205, in wrapper
return func(self, options, args)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/commands/install.py", line 338, in run
requirement_set = resolver.resolve(
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/resolver.py", line 92, in resolve
result = self._result = resolver.resolve(
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_vendor/resolvelib/resolvers.py", line 482, in resolve
state = resolution.resolve(requirements, max_rounds=max_rounds)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_vendor/resolvelib/resolvers.py", line 374, in resolve
failure_causes = self._attempt_to_pin_criterion(name)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_vendor/resolvelib/resolvers.py", line 214, in _attempt_to_pin_criterion
criteria = self._get_updated_criteria(candidate)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_vendor/resolvelib/resolvers.py", line 205, in _get_updated_criteria
self._add_to_criteria(criteria, requirement, parent=candidate)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_vendor/resolvelib/resolvers.py", line 173, in _add_to_criteria
if not criterion.candidates:
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_vendor/resolvelib/structs.py", line 151, in __bool__
return bool(self._sequence)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/found_candidates.py", line 155, in __bool__
return any(self)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/found_candidates.py", line 143, in <genexpr>
return (c for c in iterator if id(c) not in self._incompatible_ids)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/found_candidates.py", line 47, in _iter_built
candidate = func()
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/factory.py", line 201, in _make_candidate_from_link
self._link_candidate_cache[link] = LinkCandidate(
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/candidates.py", line 281, in __init__
super().__init__(
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/candidates.py", line 156, in __init__
self.dist = self._prepare()
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/candidates.py", line 225, in _prepare
dist = self._prepare_distribution()
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/candidates.py", line 292, in _prepare_distribution
return preparer.prepare_linked_requirement(self._ireq, parallel_builds=True)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/operations/prepare.py", line 482, in prepare_linked_requirement
return self._prepare_linked_requirement(req, parallel_builds)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/operations/prepare.py", line 546, in _prepare_linked_requirement
dist = _get_prepared_distribution(
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/operations/prepare.py", line 57, in _get_prepared_distribution
with req_tracker.track(req):
File "/usr/lib/python3.9/contextlib.py", line 117, in __enter__
return next(self.gen)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/req/req_tracker.py", line 122, in track
self.add(req)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/req/req_tracker.py", line 92, in add
raise LookupError(message)
LookupError: https://files.pythonhosted.org/packages/aa/5b/62165da80cbc6e1779f342234c7ddc6c6bc9e64cef149046a9c0456f912b/tomli-1.2.2.tar.gz#sha256=c6ce0015eb38820eaf32b5db832dbc26deb3dd427bd5f6556cf0acac2c214fee (from https://pypi.org/simple/tomli/) (requires-python:>=3.6) is already being built: tomli>=1.2.1 from https://files.pythonhosted.org/packages/aa/5b/62165da80cbc6e1779f342234c7ddc6c6bc9e64cef149046a9c0456f912b/tomli-1.2.2.tar.gz#sha256=c6ce0015eb38820eaf32b5db832dbc26deb3dd427bd5f6556cf0acac2c214fee (from setuptools-rust>=0.11.4)
----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/aa/5b/62165da80cbc6e1779f342234c7ddc6c6bc9e64cef149046a9c0456f912b/tomli-1.2.2.tar.gz#sha256=c6ce0015eb38820eaf32b5db832dbc26deb3dd427bd5f6556cf0acac2c214fee (from https://pypi.org/simple/tomli/) (requires-python:>=3.6). Command errored out with exit status 2: /home/pi/.platformio/penv/bin/python /tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip install --ignore-installed --no-user --prefix /tmp/pip-build-env-e79tjyp1/overlay --no-warn-script-location --no-binary :all: --only-binary :none: -i https://pypi.org/simple --extra-index-url https://www.piwheels.org/simple --extra-index-url https://www.piwheels.org/simple -- 'flit_core>=3.2.0,<4' Check the logs for full command output.
Using cached tomli-1.2.1.tar.gz (14 kB)
Installing build dependencies: started
Installing build dependencies: finished with status 'error'
ERROR: Command errored out with exit status 2:
command: /home/pi/.platformio/penv/bin/python /tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip install --ignore-installed --no-user --prefix /tmp/pip-build-env-zwmgu3x5/overlay --no-warn-script-location --no-binary :all: --only-binary :none: -i https://pypi.org/simple --extra-index-url https://www.piwheels.org/simple --extra-index-url https://www.piwheels.org/simple -- 'flit_core>=3.2.0,<4'
cwd: None
Complete output (60 lines):
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple, https://www.piwheels.org/simple, https://www.piwheels.org/simple
Collecting flit_core<4,>=3.2.0
Using cached flit_core-3.5.1.tar.gz (27 kB)
Getting requirements to build wheel: started
Getting requirements to build wheel: finished with status 'done'
Preparing metadata (pyproject.toml): started
Preparing metadata (pyproject.toml): finished with status 'done'
Collecting tomli
Using cached tomli-1.2.2.tar.gz (15 kB)
ERROR: Exception:
Traceback (most recent call last):
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/cli/base_command.py", line 164, in exc_logging_wrapper
status = run_func(*args)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/cli/req_command.py", line 205, in wrapper
return func(self, options, args)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/commands/install.py", line 338, in run
requirement_set = resolver.resolve(
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/resolver.py", line 92, in resolve
result = self._result = resolver.resolve(
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_vendor/resolvelib/resolvers.py", line 482, in resolve
state = resolution.resolve(requirements, max_rounds=max_rounds)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_vendor/resolvelib/resolvers.py", line 374, in resolve
failure_causes = self._attempt_to_pin_criterion(name)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_vendor/resolvelib/resolvers.py", line 214, in _attempt_to_pin_criterion
criteria = self._get_updated_criteria(candidate)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_vendor/resolvelib/resolvers.py", line 205, in _get_updated_criteria
self._add_to_criteria(criteria, requirement, parent=candidate)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_vendor/resolvelib/resolvers.py", line 173, in _add_to_criteria
if not criterion.candidates:
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_vendor/resolvelib/structs.py", line 151, in __bool__
return bool(self._sequence)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/found_candidates.py", line 155, in __bool__
return any(self)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/found_candidates.py", line 143, in <genexpr>
return (c for c in iterator if id(c) not in self._incompatible_ids)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/found_candidates.py", line 47, in _iter_built
candidate = func()
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/factory.py", line 201, in _make_candidate_from_link
self._link_candidate_cache[link] = LinkCandidate(
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/candidates.py", line 281, in __init__
super().__init__(
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/candidates.py", line 156, in __init__
self.dist = self._prepare()
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/candidates.py", line 225, in _prepare
dist = self._prepare_distribution()
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/resolution/resolvelib/candidates.py", line 292, in _prepare_distribution
return preparer.prepare_linked_requirement(self._ireq, parallel_builds=True)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/operations/prepare.py", line 482, in prepare_linked_requirement
return self._prepare_linked_requirement(req, parallel_builds)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/operations/prepare.py", line 546, in _prepare_linked_requirement
dist = _get_prepared_distribution(
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/operations/prepare.py", line 57, in _get_prepared_distribution
with req_tracker.track(req):
File "/usr/lib/python3.9/contextlib.py", line 117, in __enter__
return next(self.gen)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/req/req_tracker.py", line 122, in track
self.add(req)
File "/tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip/_internal/req/req_tracker.py", line 92, in add
raise LookupError(message)
LookupError: https://files.pythonhosted.org/packages/aa/5b/62165da80cbc6e1779f342234c7ddc6c6bc9e64cef149046a9c0456f912b/tomli-1.2.2.tar.gz#sha256=c6ce0015eb38820eaf32b5db832dbc26deb3dd427bd5f6556cf0acac2c214fee (from https://pypi.org/simple/tomli/) (requires-python:>=3.6) is already being built: tomli>=1.2.1 from https://files.pythonhosted.org/packages/aa/5b/62165da80cbc6e1779f342234c7ddc6c6bc9e64cef149046a9c0456f912b/tomli-1.2.2.tar.gz#sha256=c6ce0015eb38820eaf32b5db832dbc26deb3dd427bd5f6556cf0acac2c214fee (from setuptools-rust>=0.11.4)
----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/75/50/973397c5ba854445bcc396b593b5db1958da6ab8d665b27397daa1497018/tomli-1.2.1.tar.gz#sha256=a5b75cb6f3968abb47af1b40c1819dc519ea82bcc065776a866e8d74c5ca9442 (from https://pypi.org/simple/tomli/) (requires-python:>=3.6). Command errored out with exit status 2: /home/pi/.platformio/penv/bin/python /tmp/pip-standalone-pip-sgkbdzl6/__env_pip__.zip/pip install --ignore-installed --no-user --prefix /tmp/pip-build-env-zwmgu3x5/overlay --no-warn-script-location --no-binary :all: --only-binary :none: -i https://pypi.org/simple --extra-index-url https://www.piwheels.org/simple --extra-index-url https://www.piwheels.org/simple -- 'flit_core>=3.2.0,<4' Check the logs for full command output.
Collecting setuptools-rust>=0.11.4
Using cached setuptools-rust-0.12.1.tar.gz (282 kB)
Installing build dependencies: started
Installing build dependencies: still running...
Installing build dependencies: finished with status 'done'
Getting requirements to build wheel: started
Getting requirements to build wheel: finished with status 'done'
Installing backend dependencies: started
Installing backend dependencies: finished with status 'done'
Preparing metadata (pyproject.toml): started
Preparing metadata (pyproject.toml): finished with status 'done'
Collecting semantic-version>=2.6.0
Using cached semantic_version-2.8.5.tar.gz (50 kB)
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting toml>=0.9.0
Using cached toml-0.10.2.tar.gz (22 kB)
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Skipping wheel build for wheel, due to binaries being disabled for it.
Skipping wheel build for cffi, due to binaries being disabled for it.
Skipping wheel build for semantic-version, due to binaries being disabled for it.
Skipping wheel build for toml, due to binaries being disabled for it.
Skipping wheel build for pycparser, due to binaries being disabled for it.
Building wheels for collected packages: setuptools-rust, setuptools
Building wheel for setuptools-rust (pyproject.toml): started
Building wheel for setuptools-rust (pyproject.toml): finished with status 'done'
Created wheel for setuptools-rust: filename=setuptools_rust-0.12.1-py3-none-any.whl size=22068 sha256=592ee8d73230f07f4d3a4dcdcac471d9774d5fdf6cb510dfd4e1c5c85defe013
Stored in directory: /home/pi/.cache/pip/wheels/0d/74/4c/815dea1b32e070a03f3bdebc2ac66dec872e2f4f98873de7f1
Building wheel for setuptools (pyproject.toml): started
Building wheel for setuptools (pyproject.toml): finished with status 'done'
Created wheel for setuptools: filename=setuptools-59.3.0-py3-none-any.whl size=952222 sha256=71c50c4701d693604255b3207d628d6be5b2a1c11735779cc532b8b4fad526b0
Stored in directory: /home/pi/.cache/pip/wheels/b3/8b/0d/a37778f8f97ff4a4f7d1464a2f71fe824647a93b6407036e4f
Successfully built setuptools-rust setuptools
Installing collected packages: toml, setuptools, semantic-version, pycparser, wheel, setuptools-rust, cffi
Running setup.py install for toml: started
Running setup.py install for toml: finished with status 'done'
Running setup.py install for semantic-version: started
Running setup.py install for semantic-version: finished with status 'done'
Running setup.py install for pycparser: started
Running setup.py install for pycparser: finished with status 'done'
Running setup.py install for wheel: started
Running setup.py install for wheel: finished with status 'done'
Running setup.py install for cffi: started
Running setup.py install for cffi: finished with status 'error'
ERROR: Command errored out with exit status 1:
command: /home/pi/.platformio/penv/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-d0sgr43l/cffi_1f03051e252344d59bd5ebdf4f5e0f48/setup.py'"'"'; __file__='"'"'/tmp/pip-install-d0sgr43l/cffi_1f03051e252344d59bd5ebdf4f5e0f48/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-hy0iyr4f/install-record.txt --single-version-externally-managed --prefix /tmp/pip-build-env-z_7hwbt9/overlay --compile --install-headers /tmp/pip-build-env-z_7hwbt9/overlay/include/site/python3.9/cffi
cwd: /tmp/pip-install-d0sgr43l/cffi_1f03051e252344d59bd5ebdf4f5e0f48/
Complete output (58 lines):
Package libffi was not found in the pkg-config search path.
Perhaps you should add the directory containing `libffi.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libffi' found
Package libffi was not found in the pkg-config search path.
Perhaps you should add the directory containing `libffi.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libffi' found
Package libffi was not found in the pkg-config search path.
Perhaps you should add the directory containing `libffi.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libffi' found
Package libffi was not found in the pkg-config search path.
Perhaps you should add the directory containing `libffi.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libffi' found
Package libffi was not found in the pkg-config search path.
Perhaps you should add the directory containing `libffi.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libffi' found
running install
/home/pi/.platformio/penv/lib/python3.9/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
warnings.warn(
running build
running build_py
creating build
creating build/lib.linux-armv7l-3.9
creating build/lib.linux-armv7l-3.9/cffi
copying cffi/commontypes.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/cparser.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/setuptools_ext.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/pkgconfig.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/__init__.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/model.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/verifier.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/recompiler.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/ffiplatform.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/error.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/vengine_cpy.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/backend_ctypes.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/vengine_gen.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/lock.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/cffi_opcode.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/api.py -> build/lib.linux-armv7l-3.9/cffi
copying cffi/_cffi_include.h -> build/lib.linux-armv7l-3.9/cffi
copying cffi/parse_c_type.h -> build/lib.linux-armv7l-3.9/cffi
copying cffi/_embedding.h -> build/lib.linux-armv7l-3.9/cffi
copying cffi/_cffi_errors.h -> build/lib.linux-armv7l-3.9/cffi
running build_ext
building '_cffi_backend' extension
creating build/temp.linux-armv7l-3.9
creating build/temp.linux-armv7l-3.9/c
arm-linux-gnueabihf-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -ffile-prefix-map=/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -ffile-prefix-map=/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DUSE__THREAD -DHAVE_SYNC_SYNCHRONIZE -I/usr/include/ffi -I/usr/include/libffi -I/home/pi/.platformio/penv/include -I/usr/include/python3.9 -c c/_cffi_backend.c -o build/temp.linux-armv7l-3.9/c/_cffi_backend.o
c/_cffi_backend.c:15:10: fatal error: ffi.h: No such file or directory
15 | #include <ffi.h>
| ^~~~~~~
compilation terminated.
error: command '/usr/bin/arm-linux-gnueabihf-gcc' failed with exit code 1
----------------------------------------
ERROR: Command errored out with exit status 1: /home/pi/.platformio/penv/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-d0sgr43l/cffi_1f03051e252344d59bd5ebdf4f5e0f48/setup.py'"'"'; __file__='"'"'/tmp/pip-install-d0sgr43l/cffi_1f03051e252344d59bd5ebdf4f5e0f48/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-hy0iyr4f/install-record.txt --single-version-externally-managed --prefix /tmp/pip-build-env-z_7hwbt9/overlay --compile --install-headers /tmp/pip-build-env-z_7hwbt9/overlay/include/site/python3.9/cffi Check the logs for full command output.
----------------------------------------
Solution
Install libffi-dev
in order for the dependencies to install properly:
sudo apt -y install libffi-dev