Repository: pyodide/pyodide

Issue:
BLD Provide a way to easily specify library paths in `meta.yaml`
## Problem

When building Python packages that are dependent on some C/C++libraries,
we often hard-code paths of library headers (.h) / static binaries (.a).

This is annoying because when we update a library, all hard-coded paths need to be updated.

For example, in `lxml` package, there are a bunch of hard-coded paths.

https://github.com/pyodide/pyodide/blob/3f9ae2ed1e1aee688251af86a4dc23d3d867740c/packages/lxml/meta.yaml#L8-L22 
## Possible solutions

1. Put every library headers / binaries into a specific build directory.

e.g. put headers to `e.g. ${PYODIDE_ROOT}/build/pyodide/include` and static binaries to `${PYODIDE_ROOT}/build/pyodide/lib`.

Then inside `meta.yaml`, those can be easily specified such as

```
-I$(PYODIDE_INCLUDE_PATH)
-L$(PYODIDE_LIBRARY_PATH)
-lxml
```

2. Add a variable for each library.

For example,

```
-I$(LIBRARY_libxml)/include
```

instead of,

```
-I$(PYODIDE_ROOT)/packages/libxml/build/libxml-2.9.10/include
```


Discussion:

Resolving patch:
diff --git a/pyodide-build/pyodide_build/buildpkg.py b/pyodide-build/pyodide_build/buildpkg.py
--- a/pyodide-build/pyodide_build/buildpkg.py
+++ b/pyodide-build/pyodide_build/buildpkg.py
@@ -145,12 +145,18 @@ def get_bash_runner():
             "SIDE_MODULE_CFLAGS",
             "SIDE_MODULE_LDFLAGS",
             "STDLIB_MODULE_CFLAGS",
-            "OPEN_SSL_ROOT",
             "UNISOLATED_PACKAGES",
+            "WASM_LIBRARY_DIR",
+            "WASM_PKG_CONFIG_PATH",
         ]
     } | {"PYODIDE": "1"}
     if "PYODIDE_JOBS" in os.environ:
         env["PYODIDE_JOBS"] = os.environ["PYODIDE_JOBS"]
+
+    env["PKG_CONFIG_PATH"] = env["WASM_PKG_CONFIG_PATH"]
+    if "PKG_CONFIG_PATH" in os.environ:
+        env["PKG_CONFIG_PATH"] += f":{os.environ['PKG_CONFIG_PATH']}"
+
     with BashRunnerWithSharedEnvironment(env=env) as b:
         b.run(
             f"source {PYODIDE_ROOT}/emsdk/emsdk/emsdk_env.sh", stderr=subprocess.DEVNULL


Test patch:
diff --git a/packages/lxml/test_lxml.py b/packages/lxml/test_lxml.py
new file mode 100644
--- /dev/null
+++ b/packages/lxml/test_lxml.py
@@ -0,0 +1,18 @@
+from pyodide_test_runner import run_in_pyodide
+
+
+@run_in_pyodide(packages=["lxml"])
+def test_lxml():
+    from lxml import etree
+
+    root = etree.XML(
+        """<root>
+        <TEXT1 class="myitem">one</TEXT1>
+        <TEXT2 class="myitem">two</TEXT2>
+        <TEXT3 class="myitem">three</TEXT3>
+        <v-TEXT4 class="v-list">four</v-TEXT4>
+    </root>"""
+    )
+
+    items = root.xpath("//*[@class='myitem']")
+    assert ["one", "two", "three"] == [item.text for item in items]
diff --git a/packages/pyyaml/test_pyyaml.py b/packages/pyyaml/test_pyyaml.py
new file mode 100644
--- /dev/null
+++ b/packages/pyyaml/test_pyyaml.py
@@ -0,0 +1,16 @@
+from pyodide_test_runner import run_in_pyodide
+
+
+@run_in_pyodide(packages=["pyyaml"])
+def test_pyyaml():
+    import yaml
+    from yaml import CLoader as Loader
+
+    document = """
+    - Hesperiidae
+    - Papilionidae
+    - Apatelodidae
+    - Epiplemidae
+    """
+    loaded = yaml.load(document, Loader=Loader)
+    assert loaded == ["Hesperiidae", "Papilionidae", "Apatelodidae", "Epiplemidae"]