Repository: conda/conda-build

Issue:
Build seems to be caching overlinking check information
### Checklist

- [X] I added a descriptive title
- [X] I searched open reports and couldn't find a duplicate

### What happened?

During the build of https://github.com/conda-forge/staged-recipes/pull/22323, I noticed that the sequential builds seem to cache linking information incorrectly. See: https://github.com/conda-forge/staged-recipes/pull/22323#issuecomment-1475022229

from @isuruf:

```
https://github.com/conda/conda-build/blob/c5146a02c1b86033a7989718b1511969838db5dd/conda_build/os_utils/liefldd.py#L936-L977

caches by file contents, but does not cache the file name itself. Please open an issue in conda-build.
```


Discussion:

Resolving patch:
diff --git a/conda_build/os_utils/liefldd.py b/conda_build/os_utils/liefldd.py
--- a/conda_build/os_utils/liefldd.py
+++ b/conda_build/os_utils/liefldd.py
@@ -1173,6 +1173,10 @@ def __call__(self, *args, **kw):
                         if not data:
                             break
                         sha1.update(data)
+                # update with file name, if its a different
+                # file with the same contents, we don't want
+                # to treat it as cached
+                sha1.update(os.path.realpath(arg).encode("utf-8"))
                 arg = sha1.hexdigest()
             if isinstance(arg, list):
                 newargs.append(tuple(arg))


Test patch:
diff --git a/tests/test-recipes/split-packages/_test-file-hash/build.sh b/tests/test-recipes/split-packages/_test-file-hash/build.sh
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/split-packages/_test-file-hash/build.sh
@@ -0,0 +1,8 @@
+echo "int main() {}" > main.c
+mkdir -p $PREFIX/bin
+$CC main.c -o $PREFIX/bin/_file_hash
+
+echo "int foo() {return 2;}" > foo.c
+echo "int foo(); int bar() {return foo()*2;}" > bar.c
+$CC -shared foo.c -o libupstream.so
+$CC -shared bar.c -o libdownstream.so -L$PWD -lupstream '-Wl,-rpath,$ORIGIN'
diff --git a/tests/test-recipes/split-packages/_test-file-hash/conda_build_config.yaml b/tests/test-recipes/split-packages/_test-file-hash/conda_build_config.yaml
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/split-packages/_test-file-hash/conda_build_config.yaml
@@ -0,0 +1,3 @@
+python:
+- 3.10
+- 3.11
diff --git a/tests/test-recipes/split-packages/_test-file-hash/install-py.sh b/tests/test-recipes/split-packages/_test-file-hash/install-py.sh
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/split-packages/_test-file-hash/install-py.sh
@@ -0,0 +1,4 @@
+mkdir -p $SP_DIR/_py_file_hash
+cp libdownstream.so $SP_DIR/_py_file_hash/
+cp libupstream.so $SP_DIR/_py_file_hash/
+
diff --git a/tests/test-recipes/split-packages/_test-file-hash/meta.yaml b/tests/test-recipes/split-packages/_test-file-hash/meta.yaml
new file mode 100644
--- /dev/null
+++ b/tests/test-recipes/split-packages/_test-file-hash/meta.yaml
@@ -0,0 +1,30 @@
+package:
+  name: _file_hash-split
+  version: 0.0.1
+
+build:
+  number: 0
+  skip: True  # [not linux64]
+  error_overlinking: true
+
+requirements:
+  build:
+    - {{ compiler('c') }}
+  host:
+  run:
+
+outputs:
+  - name: py-file-hash
+    script: install-py.sh
+    requirements:
+      build:
+        - {{ compiler('c') }}
+      host:
+        - python
+      run:
+        - python
+
+  - name: _file_hash
+    requirements:
+      build:
+        - {{ compiler('c') }}
diff --git a/tests/test_post.py b/tests/test_post.py
--- a/tests/test_post.py
+++ b/tests/test_post.py
@@ -18,7 +18,7 @@
     package_has_file,
 )
 
-from .utils import add_mangling, metadata_dir
+from .utils import add_mangling, metadata_dir, subpackage_path
 
 
 @pytest.mark.skipif(
@@ -156,6 +156,26 @@ def test_menuinst_validation_fails_bad_json(testing_config, caplog, tmp_path):
     assert "JSONDecodeError" in captured_text
 
 
+def test_file_hash(testing_config, caplog, tmp_path):
+    "check that the post-link check caching takes the file path into consideration"
+    recipe = Path(subpackage_path, "_test-file-hash")
+    recipe_tmp = tmp_path / "test-file-hash"
+    shutil.copytree(recipe, recipe_tmp)
+
+    variants = {"python": ["3.11", "3.12"]}
+    testing_config.ignore_system_config = True
+    testing_config.activate = True
+
+    with caplog.at_level(logging.INFO):
+        api.build(
+            str(recipe_tmp),
+            config=testing_config,
+            notest=True,
+            variants=variants,
+            activate=True,
+        )
+
+
 @pytest.mark.skipif(on_win, reason="rpath fixup not done on Windows.")
 def test_rpath_symlink(mocker, testing_config):
     if on_linux: