Skip to content

Fix link/bundle failures on rebuilds and output-path collisions#141

Open
gbaraldi wants to merge 3 commits into
mainfrom
fix-issue-132-and-rebuild
Open

Fix link/bundle failures on rebuilds and output-path collisions#141
gbaraldi wants to merge 3 commits into
mainfrom
fix-issue-132-and-rebuild

Conversation

@gbaraldi
Copy link
Copy Markdown
Member

Summary

  • Reject linker output paths that resolve to an existing directory; fixes the cryptic ld: open() failed, errno=21 (EISDIR) when --output-exe <pkgname> collides case-insensitively with the package directory on macOS APFS / Windows NTFS (closes Can't name executable the same as the package "linker command failed with exit code 1" #132).
  • Only emit -install_name/-soname/--out-implib for shared outputs — they were being applied to executables too.
  • Make bundle_products re-runnable: drop the buggy deferred dirs_to_remove rm (it was wiping the freshly-moved libs), and clear bundle-owned subdirs at the start so PackageCompiler's non-idempotent bundle_cert/bundle_artifacts (cp without force=true) don't fail on the second build, and stale libs aren't kept across Julia upgrades. The wipe is scoped to bin/, lib/, share/julia/ and skips any subdir that contains the link output (programmatic API pattern).

Closes #132.

Test plan

  • Pkg.test() passes (all suites green, including the Library has install_name (MacOS) test)
  • Fresh end-to-end build of test/AppProject via the CLI produces a working bundle and the executable runs
  • Two back-to-back CLI builds into the same --bundle build directory both succeed and the resulting binary runs
  • Verified on Linux / Windows (only tested on macOS aarch64)

🤖 Generated with Claude Code

- linking: reject output paths that resolve to an existing directory.
  On case-insensitive filesystems this catches `--output-exe <pkgname>`
  run from the package's parent dir (issue #132), which previously
  produced a confusing `ld: open() failed, errno=21` (EISDIR).
- linking: only emit `-install_name`/`-soname`/`--out-implib` for shared
  outputs. These flags are dylib/import-lib concepts and were being
  appended for executables as well.
- bundling: drop the deferred `dirs_to_remove` rm. The pre-existing
  `dest_julia_dir` was added to it and then `mv(force=true)` placed
  the fresh libs at that path, so the deferred rm would wipe the
  freshly-bundled libs on a second run.
- bundling: clear bundle-owned subdirs (`bin/`, `lib/`, `share/julia/`)
  at the start so re-runs are idempotent, working around
  PackageCompiler's `bundle_cert`/`bundle_artifacts` cp-without-force
  and `bundle_julia_libraries`'s skip-if-exists (which can leave stale
  libs across Julia upgrades). Subdirs containing the link output are
  preserved for the programmatic API.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@gbaraldi gbaraldi requested a review from topolarity May 13, 2026 19:30
gbaraldi and others added 2 commits May 14, 2026 10:47
Avoids hardcoding `bin`/`lib`/`share/julia` and also cleans up any other
stale top-level content. Same skip rule: preserve any entry that holds
the link output (programmatic API allows outname inside output_dir).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous wipe loop also removed top-level files, which on Windows
deleted the `.dll.a` import library that `link_products` emits next to
the main artifact (via -Wl,--out-implib). Limit the wipe to directories:
all bundle-managed state (bin/, lib/, share/julia/) lives in subdirs,
and link products at the top level (the main artifact and, on Windows,
its sibling import library) are preserved for bundle_products to move.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can't name executable the same as the package "linker command failed with exit code 1"

1 participant