Skip to content

cargo run exports bad DYLD_LIBRARY_PATH on macOS #3366

Description

@casey

I've been going down the rabbit hole for a while on this one. Thankfully though, it seems like it's actually hopefully a pretty simple fix. Or, if it isn't, at least maybe I'm reporting the issue in the right repo ^_^

I originally thought it was a git2-rs issue, and reported it in https://github.com/alexcrichton/git2-rs/issues/175. Then I thought it was a rustc issue, and reported it here: rust-lang/rust#36250.

Finally though, I've gotten to the bottom of it, and it appears to be a cargo bug.

A few things need to happen to trigger the issue:

  1. We are linking ina dynamic library that is not provided by the system, for example something from homebrew in /usr/local/lib, or from macports in /opt/local/lib.

  2. We are also linking in a system framework.

  3. In the nonstandard location in 1., there is a dynamically linked library which the system framework from 2. needs. However, this library in 1. is not the version that the framework expects.

  4. We run the binary with cargo run.

To make everything concrete, let's say that we're linking in openssl provided by macports in /opt/local/lib, the framework we're using is the ApplicationServices framework, and we also happen to have libiconv installed in /opt/local/lib.

Cargo will export DYLD_LIBRARY_PATH=/opt/local/lib:..., and we'll get the following error:

: cargo run
Compiling rust-dynamic-linker-error v0.0.0 (file:///Users/rodarmor/src/rust-dynamic-linker-error)
Finished debug [unoptimized + debuginfo] target(s) in 0.34 secs
Running `target/debug/rust-dynamic-linker-error`
dyld: Symbol not found: _iconv
Referenced from: /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
Expected in: /opt/local/lib/libiconv.2.dylib
in /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling

What's happening is that the LanguageModeling framework, which is a transitive dependency of the ApplicationServices framework also depends on libiconv. Normally it finds it in /usr/lib/libiconv.dylib. However, because of the value of DYLD_LIBRARY_PATH, it finds it in /usr/local/lib/libiconv.dylib, and we get the error because it is the wrong version with a missing symbol.

If we run the binary directly, without the environment variable, it works:

: ./target/debug/rust-dynamic-linker-error
Hello, world!

Although the conditions needed to trigger this bug may seem esoteric, they are actually very common on mac development machines. Developers often have a ton of stuff installed via macports or homebrew.

There are a few ways that this might be resolved:

The DYLD_LIBRARY_PATH value seems to be unnecessary at least in this case, since the binary works when run directly. If so, perhaps we can avoid exporting it so as not to cause this breakage? However, perhaps there are other situations where the variable is necessary to find libraries? What's the purpose of the export?

If the DYLD_LIBRARY_PATH value is necessary, then we need to communicate that to developers somehow. It would be very frustrating to have a binary which runs with cargo run, but which cannot be run directly.

And, if we do need DYLD_LIBRARY_PATH, then we should consider if DYLD_FALLBACK_LIBRARY_PATH might suffice. DYLD_FALLBACK_LIBRARY_PATH does not disrupt the normal order of dynamic library lookup, but instead is only consulted if the dynamic linker cannot find a library in the normal places.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
       blocks
      (function() {
      function addCopyButtons() {
      document.querySelectorAll('pre code').forEach(function(codeBlock) {
      if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
      codeBlock.parentElement.setAttribute('data-copy-added', 'true');
      var btn = document.createElement('button');
      btn.textContent = 'Copy';
      btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
      btn.onmouseover = function() { this.style.opacity = '1'; };
      btn.onmouseout = function() { this.style.opacity = '0.7'; };
      btn.onclick = function() {
      navigator.clipboard.writeText(codeBlock.textContent).then(function() {
      btn.textContent = 'Copied!';
      setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
      });
      };
      codeBlock.parentElement.style.position = 'relative';
      codeBlock.parentElement.appendChild(btn);
      });
      }
      addCopyButtons();
      // Re-run on dynamic content
      var observer = new MutationObserver(addCopyButtons);
      observer.observe(document.body, { childList: true, subtree: true });
      })();
      }
      } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
      })();
      (function(){
      try {
      var __m = "github.com";
      var __re = new RegExp('^' + "github\\.com" + '
      `cargo run` exports bad DYLD_LIBRARY_PATH on macOS · Issue #3366 · rust-lang/cargo · GitHub
      Skip to content

      cargo run exports bad DYLD_LIBRARY_PATH on macOS #3366

      Description

      @casey

      I've been going down the rabbit hole for a while on this one. Thankfully though, it seems like it's actually hopefully a pretty simple fix. Or, if it isn't, at least maybe I'm reporting the issue in the right repo ^_^

      I originally thought it was a git2-rs issue, and reported it in https://github.com/alexcrichton/git2-rs/issues/175. Then I thought it was a rustc issue, and reported it here: rust-lang/rust#36250.

      Finally though, I've gotten to the bottom of it, and it appears to be a cargo bug.

      A few things need to happen to trigger the issue:

      1. We are linking ina dynamic library that is not provided by the system, for example something from homebrew in /usr/local/lib, or from macports in /opt/local/lib.

      2. We are also linking in a system framework.

      3. In the nonstandard location in 1., there is a dynamically linked library which the system framework from 2. needs. However, this library in 1. is not the version that the framework expects.

      4. We run the binary with cargo run.

      To make everything concrete, let's say that we're linking in openssl provided by macports in /opt/local/lib, the framework we're using is the ApplicationServices framework, and we also happen to have libiconv installed in /opt/local/lib.

      Cargo will export DYLD_LIBRARY_PATH=/opt/local/lib:..., and we'll get the following error:

      : cargo run
      Compiling rust-dynamic-linker-error v0.0.0 (file:///Users/rodarmor/src/rust-dynamic-linker-error)
      Finished debug [unoptimized + debuginfo] target(s) in 0.34 secs
      Running `target/debug/rust-dynamic-linker-error`
      dyld: Symbol not found: _iconv
      Referenced from: /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
      Expected in: /opt/local/lib/libiconv.2.dylib
      in /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
      

      What's happening is that the LanguageModeling framework, which is a transitive dependency of the ApplicationServices framework also depends on libiconv. Normally it finds it in /usr/lib/libiconv.dylib. However, because of the value of DYLD_LIBRARY_PATH, it finds it in /usr/local/lib/libiconv.dylib, and we get the error because it is the wrong version with a missing symbol.

      If we run the binary directly, without the environment variable, it works:

      : ./target/debug/rust-dynamic-linker-error
      Hello, world!
      

      Although the conditions needed to trigger this bug may seem esoteric, they are actually very common on mac development machines. Developers often have a ton of stuff installed via macports or homebrew.

      There are a few ways that this might be resolved:

      The DYLD_LIBRARY_PATH value seems to be unnecessary at least in this case, since the binary works when run directly. If so, perhaps we can avoid exporting it so as not to cause this breakage? However, perhaps there are other situations where the variable is necessary to find libraries? What's the purpose of the export?

      If the DYLD_LIBRARY_PATH value is necessary, then we need to communicate that to developers somehow. It would be very frustrating to have a binary which runs with cargo run, but which cannot be run directly.

      And, if we do need DYLD_LIBRARY_PATH, then we should consider if DYLD_FALLBACK_LIBRARY_PATH might suffice. DYLD_FALLBACK_LIBRARY_PATH does not disrupt the normal order of dynamic library lookup, but instead is only consulted if the dynamic linker cannot find a library in the normal places.

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        No labels
        No labels

        Type

        No type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' `cargo run` exports bad DYLD_LIBRARY_PATH on macOS · Issue #3366 · rust-lang/cargo · GitHub
          Skip to content

          cargo run exports bad DYLD_LIBRARY_PATH on macOS #3366

          Description

          @casey

          I've been going down the rabbit hole for a while on this one. Thankfully though, it seems like it's actually hopefully a pretty simple fix. Or, if it isn't, at least maybe I'm reporting the issue in the right repo ^_^

          I originally thought it was a git2-rs issue, and reported it in https://github.com/alexcrichton/git2-rs/issues/175. Then I thought it was a rustc issue, and reported it here: rust-lang/rust#36250.

          Finally though, I've gotten to the bottom of it, and it appears to be a cargo bug.

          A few things need to happen to trigger the issue:

          1. We are linking ina dynamic library that is not provided by the system, for example something from homebrew in /usr/local/lib, or from macports in /opt/local/lib.

          2. We are also linking in a system framework.

          3. In the nonstandard location in 1., there is a dynamically linked library which the system framework from 2. needs. However, this library in 1. is not the version that the framework expects.

          4. We run the binary with cargo run.

          To make everything concrete, let's say that we're linking in openssl provided by macports in /opt/local/lib, the framework we're using is the ApplicationServices framework, and we also happen to have libiconv installed in /opt/local/lib.

          Cargo will export DYLD_LIBRARY_PATH=/opt/local/lib:..., and we'll get the following error:

          : cargo run
          Compiling rust-dynamic-linker-error v0.0.0 (file:///Users/rodarmor/src/rust-dynamic-linker-error)
          Finished debug [unoptimized + debuginfo] target(s) in 0.34 secs
          Running `target/debug/rust-dynamic-linker-error`
          dyld: Symbol not found: _iconv
          Referenced from: /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
          Expected in: /opt/local/lib/libiconv.2.dylib
          in /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
          

          What's happening is that the LanguageModeling framework, which is a transitive dependency of the ApplicationServices framework also depends on libiconv. Normally it finds it in /usr/lib/libiconv.dylib. However, because of the value of DYLD_LIBRARY_PATH, it finds it in /usr/local/lib/libiconv.dylib, and we get the error because it is the wrong version with a missing symbol.

          If we run the binary directly, without the environment variable, it works:

          : ./target/debug/rust-dynamic-linker-error
          Hello, world!
          

          Although the conditions needed to trigger this bug may seem esoteric, they are actually very common on mac development machines. Developers often have a ton of stuff installed via macports or homebrew.

          There are a few ways that this might be resolved:

          The DYLD_LIBRARY_PATH value seems to be unnecessary at least in this case, since the binary works when run directly. If so, perhaps we can avoid exporting it so as not to cause this breakage? However, perhaps there are other situations where the variable is necessary to find libraries? What's the purpose of the export?

          If the DYLD_LIBRARY_PATH value is necessary, then we need to communicate that to developers somehow. It would be very frustrating to have a binary which runs with cargo run, but which cannot be run directly.

          And, if we do need DYLD_LIBRARY_PATH, then we should consider if DYLD_FALLBACK_LIBRARY_PATH might suffice. DYLD_FALLBACK_LIBRARY_PATH does not disrupt the normal order of dynamic library lookup, but instead is only consulted if the dynamic linker cannot find a library in the normal places.

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            No labels
            No labels

            Type

            No type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' `cargo run` exports bad DYLD_LIBRARY_PATH on macOS · Issue #3366 · rust-lang/cargo · GitHub
              Skip to content

              cargo run exports bad DYLD_LIBRARY_PATH on macOS #3366

              Description

              @casey

              I've been going down the rabbit hole for a while on this one. Thankfully though, it seems like it's actually hopefully a pretty simple fix. Or, if it isn't, at least maybe I'm reporting the issue in the right repo ^_^

              I originally thought it was a git2-rs issue, and reported it in https://github.com/alexcrichton/git2-rs/issues/175. Then I thought it was a rustc issue, and reported it here: rust-lang/rust#36250.

              Finally though, I've gotten to the bottom of it, and it appears to be a cargo bug.

              A few things need to happen to trigger the issue:

              1. We are linking ina dynamic library that is not provided by the system, for example something from homebrew in /usr/local/lib, or from macports in /opt/local/lib.

              2. We are also linking in a system framework.

              3. In the nonstandard location in 1., there is a dynamically linked library which the system framework from 2. needs. However, this library in 1. is not the version that the framework expects.

              4. We run the binary with cargo run.

              To make everything concrete, let's say that we're linking in openssl provided by macports in /opt/local/lib, the framework we're using is the ApplicationServices framework, and we also happen to have libiconv installed in /opt/local/lib.

              Cargo will export DYLD_LIBRARY_PATH=/opt/local/lib:..., and we'll get the following error:

              : cargo run
              Compiling rust-dynamic-linker-error v0.0.0 (file:///Users/rodarmor/src/rust-dynamic-linker-error)
              Finished debug [unoptimized + debuginfo] target(s) in 0.34 secs
              Running `target/debug/rust-dynamic-linker-error`
              dyld: Symbol not found: _iconv
              Referenced from: /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
              Expected in: /opt/local/lib/libiconv.2.dylib
              in /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
              

              What's happening is that the LanguageModeling framework, which is a transitive dependency of the ApplicationServices framework also depends on libiconv. Normally it finds it in /usr/lib/libiconv.dylib. However, because of the value of DYLD_LIBRARY_PATH, it finds it in /usr/local/lib/libiconv.dylib, and we get the error because it is the wrong version with a missing symbol.

              If we run the binary directly, without the environment variable, it works:

              : ./target/debug/rust-dynamic-linker-error
              Hello, world!
              

              Although the conditions needed to trigger this bug may seem esoteric, they are actually very common on mac development machines. Developers often have a ton of stuff installed via macports or homebrew.

              There are a few ways that this might be resolved:

              The DYLD_LIBRARY_PATH value seems to be unnecessary at least in this case, since the binary works when run directly. If so, perhaps we can avoid exporting it so as not to cause this breakage? However, perhaps there are other situations where the variable is necessary to find libraries? What's the purpose of the export?

              If the DYLD_LIBRARY_PATH value is necessary, then we need to communicate that to developers somehow. It would be very frustrating to have a binary which runs with cargo run, but which cannot be run directly.

              And, if we do need DYLD_LIBRARY_PATH, then we should consider if DYLD_FALLBACK_LIBRARY_PATH might suffice. DYLD_FALLBACK_LIBRARY_PATH does not disrupt the normal order of dynamic library lookup, but instead is only consulted if the dynamic linker cannot find a library in the normal places.

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                No labels
                No labels

                Type

                No type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' `cargo run` exports bad DYLD_LIBRARY_PATH on macOS · Issue #3366 · rust-lang/cargo · GitHub
                  Skip to content

                  cargo run exports bad DYLD_LIBRARY_PATH on macOS #3366

                  Description

                  @casey

                  I've been going down the rabbit hole for a while on this one. Thankfully though, it seems like it's actually hopefully a pretty simple fix. Or, if it isn't, at least maybe I'm reporting the issue in the right repo ^_^

                  I originally thought it was a git2-rs issue, and reported it in https://github.com/alexcrichton/git2-rs/issues/175. Then I thought it was a rustc issue, and reported it here: rust-lang/rust#36250.

                  Finally though, I've gotten to the bottom of it, and it appears to be a cargo bug.

                  A few things need to happen to trigger the issue:

                  1. We are linking ina dynamic library that is not provided by the system, for example something from homebrew in /usr/local/lib, or from macports in /opt/local/lib.

                  2. We are also linking in a system framework.

                  3. In the nonstandard location in 1., there is a dynamically linked library which the system framework from 2. needs. However, this library in 1. is not the version that the framework expects.

                  4. We run the binary with cargo run.

                  To make everything concrete, let's say that we're linking in openssl provided by macports in /opt/local/lib, the framework we're using is the ApplicationServices framework, and we also happen to have libiconv installed in /opt/local/lib.

                  Cargo will export DYLD_LIBRARY_PATH=/opt/local/lib:..., and we'll get the following error:

                  : cargo run
                  Compiling rust-dynamic-linker-error v0.0.0 (file:///Users/rodarmor/src/rust-dynamic-linker-error)
                  Finished debug [unoptimized + debuginfo] target(s) in 0.34 secs
                  Running `target/debug/rust-dynamic-linker-error`
                  dyld: Symbol not found: _iconv
                  Referenced from: /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
                  Expected in: /opt/local/lib/libiconv.2.dylib
                  in /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
                  

                  What's happening is that the LanguageModeling framework, which is a transitive dependency of the ApplicationServices framework also depends on libiconv. Normally it finds it in /usr/lib/libiconv.dylib. However, because of the value of DYLD_LIBRARY_PATH, it finds it in /usr/local/lib/libiconv.dylib, and we get the error because it is the wrong version with a missing symbol.

                  If we run the binary directly, without the environment variable, it works:

                  : ./target/debug/rust-dynamic-linker-error
                  Hello, world!
                  

                  Although the conditions needed to trigger this bug may seem esoteric, they are actually very common on mac development machines. Developers often have a ton of stuff installed via macports or homebrew.

                  There are a few ways that this might be resolved:

                  The DYLD_LIBRARY_PATH value seems to be unnecessary at least in this case, since the binary works when run directly. If so, perhaps we can avoid exporting it so as not to cause this breakage? However, perhaps there are other situations where the variable is necessary to find libraries? What's the purpose of the export?

                  If the DYLD_LIBRARY_PATH value is necessary, then we need to communicate that to developers somehow. It would be very frustrating to have a binary which runs with cargo run, but which cannot be run directly.

                  And, if we do need DYLD_LIBRARY_PATH, then we should consider if DYLD_FALLBACK_LIBRARY_PATH might suffice. DYLD_FALLBACK_LIBRARY_PATH does not disrupt the normal order of dynamic library lookup, but instead is only consulted if the dynamic linker cannot find a library in the normal places.

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Labels

                    No labels
                    No labels

                    Type

                    No type

                    Projects

                    No projects

                      Milestone

                      No milestone

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' `cargo run` exports bad DYLD_LIBRARY_PATH on macOS · Issue #3366 · rust-lang/cargo · GitHub
                      Skip to content

                      cargo run exports bad DYLD_LIBRARY_PATH on macOS #3366

                      Description

                      @casey

                      I've been going down the rabbit hole for a while on this one. Thankfully though, it seems like it's actually hopefully a pretty simple fix. Or, if it isn't, at least maybe I'm reporting the issue in the right repo ^_^

                      I originally thought it was a git2-rs issue, and reported it in https://github.com/alexcrichton/git2-rs/issues/175. Then I thought it was a rustc issue, and reported it here: rust-lang/rust#36250.

                      Finally though, I've gotten to the bottom of it, and it appears to be a cargo bug.

                      A few things need to happen to trigger the issue:

                      1. We are linking ina dynamic library that is not provided by the system, for example something from homebrew in /usr/local/lib, or from macports in /opt/local/lib.

                      2. We are also linking in a system framework.

                      3. In the nonstandard location in 1., there is a dynamically linked library which the system framework from 2. needs. However, this library in 1. is not the version that the framework expects.

                      4. We run the binary with cargo run.

                      To make everything concrete, let's say that we're linking in openssl provided by macports in /opt/local/lib, the framework we're using is the ApplicationServices framework, and we also happen to have libiconv installed in /opt/local/lib.

                      Cargo will export DYLD_LIBRARY_PATH=/opt/local/lib:..., and we'll get the following error:

                      : cargo run
                      Compiling rust-dynamic-linker-error v0.0.0 (file:///Users/rodarmor/src/rust-dynamic-linker-error)
                      Finished debug [unoptimized + debuginfo] target(s) in 0.34 secs
                      Running `target/debug/rust-dynamic-linker-error`
                      dyld: Symbol not found: _iconv
                      Referenced from: /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
                      Expected in: /opt/local/lib/libiconv.2.dylib
                      in /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
                      

                      What's happening is that the LanguageModeling framework, which is a transitive dependency of the ApplicationServices framework also depends on libiconv. Normally it finds it in /usr/lib/libiconv.dylib. However, because of the value of DYLD_LIBRARY_PATH, it finds it in /usr/local/lib/libiconv.dylib, and we get the error because it is the wrong version with a missing symbol.

                      If we run the binary directly, without the environment variable, it works:

                      : ./target/debug/rust-dynamic-linker-error
                      Hello, world!
                      

                      Although the conditions needed to trigger this bug may seem esoteric, they are actually very common on mac development machines. Developers often have a ton of stuff installed via macports or homebrew.

                      There are a few ways that this might be resolved:

                      The DYLD_LIBRARY_PATH value seems to be unnecessary at least in this case, since the binary works when run directly. If so, perhaps we can avoid exporting it so as not to cause this breakage? However, perhaps there are other situations where the variable is necessary to find libraries? What's the purpose of the export?

                      If the DYLD_LIBRARY_PATH value is necessary, then we need to communicate that to developers somehow. It would be very frustrating to have a binary which runs with cargo run, but which cannot be run directly.

                      And, if we do need DYLD_LIBRARY_PATH, then we should consider if DYLD_FALLBACK_LIBRARY_PATH might suffice. DYLD_FALLBACK_LIBRARY_PATH does not disrupt the normal order of dynamic library lookup, but instead is only consulted if the dynamic linker cannot find a library in the normal places.

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Labels

                        No labels
                        No labels

                        Type

                        No type

                        Projects

                        No projects

                          Milestone

                          No milestone

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' `cargo run` exports bad DYLD_LIBRARY_PATH on macOS · Issue #3366 · rust-lang/cargo · GitHub
                          Skip to content

                          cargo run exports bad DYLD_LIBRARY_PATH on macOS #3366

                          Description

                          @casey

                          I've been going down the rabbit hole for a while on this one. Thankfully though, it seems like it's actually hopefully a pretty simple fix. Or, if it isn't, at least maybe I'm reporting the issue in the right repo ^_^

                          I originally thought it was a git2-rs issue, and reported it in https://github.com/alexcrichton/git2-rs/issues/175. Then I thought it was a rustc issue, and reported it here: rust-lang/rust#36250.

                          Finally though, I've gotten to the bottom of it, and it appears to be a cargo bug.

                          A few things need to happen to trigger the issue:

                          1. We are linking ina dynamic library that is not provided by the system, for example something from homebrew in /usr/local/lib, or from macports in /opt/local/lib.

                          2. We are also linking in a system framework.

                          3. In the nonstandard location in 1., there is a dynamically linked library which the system framework from 2. needs. However, this library in 1. is not the version that the framework expects.

                          4. We run the binary with cargo run.

                          To make everything concrete, let's say that we're linking in openssl provided by macports in /opt/local/lib, the framework we're using is the ApplicationServices framework, and we also happen to have libiconv installed in /opt/local/lib.

                          Cargo will export DYLD_LIBRARY_PATH=/opt/local/lib:..., and we'll get the following error:

                          : cargo run
                          Compiling rust-dynamic-linker-error v0.0.0 (file:///Users/rodarmor/src/rust-dynamic-linker-error)
                          Finished debug [unoptimized + debuginfo] target(s) in 0.34 secs
                          Running `target/debug/rust-dynamic-linker-error`
                          dyld: Symbol not found: _iconv
                          Referenced from: /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
                          Expected in: /opt/local/lib/libiconv.2.dylib
                          in /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
                          

                          What's happening is that the LanguageModeling framework, which is a transitive dependency of the ApplicationServices framework also depends on libiconv. Normally it finds it in /usr/lib/libiconv.dylib. However, because of the value of DYLD_LIBRARY_PATH, it finds it in /usr/local/lib/libiconv.dylib, and we get the error because it is the wrong version with a missing symbol.

                          If we run the binary directly, without the environment variable, it works:

                          : ./target/debug/rust-dynamic-linker-error
                          Hello, world!
                          

                          Although the conditions needed to trigger this bug may seem esoteric, they are actually very common on mac development machines. Developers often have a ton of stuff installed via macports or homebrew.

                          There are a few ways that this might be resolved:

                          The DYLD_LIBRARY_PATH value seems to be unnecessary at least in this case, since the binary works when run directly. If so, perhaps we can avoid exporting it so as not to cause this breakage? However, perhaps there are other situations where the variable is necessary to find libraries? What's the purpose of the export?

                          If the DYLD_LIBRARY_PATH value is necessary, then we need to communicate that to developers somehow. It would be very frustrating to have a binary which runs with cargo run, but which cannot be run directly.

                          And, if we do need DYLD_LIBRARY_PATH, then we should consider if DYLD_FALLBACK_LIBRARY_PATH might suffice. DYLD_FALLBACK_LIBRARY_PATH does not disrupt the normal order of dynamic library lookup, but instead is only consulted if the dynamic linker cannot find a library in the normal places.

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Labels

                            No labels
                            No labels

                            Type

                            No type

                            Projects

                            No projects

                              Milestone

                              No milestone

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); `cargo run` exports bad DYLD_LIBRARY_PATH on macOS · Issue #3366 · rust-lang/cargo · GitHub
                              Skip to content

                              cargo run exports bad DYLD_LIBRARY_PATH on macOS #3366

                              Description

                              @casey

                              I've been going down the rabbit hole for a while on this one. Thankfully though, it seems like it's actually hopefully a pretty simple fix. Or, if it isn't, at least maybe I'm reporting the issue in the right repo ^_^

                              I originally thought it was a git2-rs issue, and reported it in https://github.com/alexcrichton/git2-rs/issues/175. Then I thought it was a rustc issue, and reported it here: rust-lang/rust#36250.

                              Finally though, I've gotten to the bottom of it, and it appears to be a cargo bug.

                              A few things need to happen to trigger the issue:

                              1. We are linking ina dynamic library that is not provided by the system, for example something from homebrew in /usr/local/lib, or from macports in /opt/local/lib.

                              2. We are also linking in a system framework.

                              3. In the nonstandard location in 1., there is a dynamically linked library which the system framework from 2. needs. However, this library in 1. is not the version that the framework expects.

                              4. We run the binary with cargo run.

                              To make everything concrete, let's say that we're linking in openssl provided by macports in /opt/local/lib, the framework we're using is the ApplicationServices framework, and we also happen to have libiconv installed in /opt/local/lib.

                              Cargo will export DYLD_LIBRARY_PATH=/opt/local/lib:..., and we'll get the following error:

                              : cargo run
                              Compiling rust-dynamic-linker-error v0.0.0 (file:///Users/rodarmor/src/rust-dynamic-linker-error)
                              Finished debug [unoptimized + debuginfo] target(s) in 0.34 secs
                              Running `target/debug/rust-dynamic-linker-error`
                              dyld: Symbol not found: _iconv
                              Referenced from: /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
                              Expected in: /opt/local/lib/libiconv.2.dylib
                              in /System/Library/PrivateFrameworks/LanguageModeling.framework/Versions/A/LanguageModeling
                              

                              What's happening is that the LanguageModeling framework, which is a transitive dependency of the ApplicationServices framework also depends on libiconv. Normally it finds it in /usr/lib/libiconv.dylib. However, because of the value of DYLD_LIBRARY_PATH, it finds it in /usr/local/lib/libiconv.dylib, and we get the error because it is the wrong version with a missing symbol.

                              If we run the binary directly, without the environment variable, it works:

                              : ./target/debug/rust-dynamic-linker-error
                              Hello, world!
                              

                              Although the conditions needed to trigger this bug may seem esoteric, they are actually very common on mac development machines. Developers often have a ton of stuff installed via macports or homebrew.

                              There are a few ways that this might be resolved:

                              The DYLD_LIBRARY_PATH value seems to be unnecessary at least in this case, since the binary works when run directly. If so, perhaps we can avoid exporting it so as not to cause this breakage? However, perhaps there are other situations where the variable is necessary to find libraries? What's the purpose of the export?

                              If the DYLD_LIBRARY_PATH value is necessary, then we need to communicate that to developers somehow. It would be very frustrating to have a binary which runs with cargo run, but which cannot be run directly.

                              And, if we do need DYLD_LIBRARY_PATH, then we should consider if DYLD_FALLBACK_LIBRARY_PATH might suffice. DYLD_FALLBACK_LIBRARY_PATH does not disrupt the normal order of dynamic library lookup, but instead is only consulted if the dynamic linker cannot find a library in the normal places.

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Labels

                                No labels
                                No labels

                                Type

                                No type

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions