Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bindings for iconv calls #2037

Merged
merged 1 commit into from Feb 11, 2021
Merged

Add bindings for iconv calls #2037

merged 1 commit into from Feb 11, 2021

Conversation

Minoru
Copy link
Contributor

@Minoru Minoru commented Jan 17, 2021

No description provided.

@rust-highfive
Copy link

r? @JohnTitor

(rust-highfive has picked a reviewer for you, use r? to override)

@Minoru
Copy link
Contributor Author

Minoru commented Jan 17, 2021

Already looking into the macOS failure!

@Minoru
Copy link
Contributor Author

Minoru commented Jan 17, 2021

Sorry, I need a bit of help with this ­— I either misunderstand cfg_if! macro or target_os attribute.

The original commit, ac6ec1c, failed to build on macOS because it didn't link with iconv library. The next commit, e906ef7, added an appropriate link attribute, but the build still failed — and I don't see -liconv anywhere in the output. Adding a link attribute unconditionally works on macOS, but not other platforms (ddddc18), the latter being expected.

macOS build links with m and c libraries, and the only other place where those could come from is the "Android or OpenBSD" branch. But if I add iconv there, still no -liconv in the output (8d7a53c).

It feels like I'm adding the link attribute to the wrong place. Can anyone point me to the right one?

@Minoru
Copy link
Contributor Author

Minoru commented Jan 25, 2021

99202f7 implements a new approach: build.rs emits rustc-link-lib=iconv on Apple platforms. This works, but might be confusing to future programmers, since all the other libraries are configured via the link attributes.

src/unix/mod.rs Outdated
@@ -298,6 +299,7 @@ cfg_if! {
} else if #[cfg(feature = "std")] {
// cargo build, don't pull in anything extra as the libstd dep
// already pulls in all libs.
extern {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you clarify why you've added this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, sorry, it's a leftover from one of the experiments, 3553014. Will remove this in a second.

@Minoru
Copy link
Contributor Author

Minoru commented Jan 29, 2021

Even though this PR passes CI, I'd really like some discussion on whether this even belongs to libc.

On one hand it definitely does, since iconv calls are part of POSIX, and are widely implemented.

On the other hand, the situation is a bit complicated since BDSs can have two implementations at once: one from libc.so (implementing POSIX), the other from libiconv.so (GNU libiconv implementing POSIX plus GNU extensions). libiconv uses different symbol names (libiconv_open() etc.), but the function names are the same, so the caller is none the wiser — the decision is made at linking time. (musl might not implement the GNU extensions either, I didn't check.)

I doubt it's the crate's job to decide which iconv implementation my app should link to, and so there are a few possible solutions:

  1. don't provide these bindings at all, let some other crate do it;
  2. provide a feature flag to pick between "libc iconv" and "libiconv iconv", regardless of the platform;
  3. provide a feature flag to pick between "libc iconv" and "libiconv iconv", just on systems that don't use glibc (I believe the libc "type" is a part of a platform triple);
  4. link to "libc iconv" unconditionally, let someone else provide libiconv bindings;
  5. link to "libiconv iconv" unconditionally, let someone else provide libc.so bindings.

I only discovered all these complications once I opened the PR; if I knew of them in advance, I'd open an issue first. Sorry about that! Happy to close this and re-report as an issue if that's what you'd prefer.

@semarie
Copy link
Contributor

semarie commented Jan 29, 2021

at least on OpenBSD (but I think it is true for several others OS), iconv isn't part of system libc (neither part of libraries provided by the system). iconv is only available as third party library.

@bors
Copy link
Contributor

bors commented Feb 2, 2021

☔ The latest upstream changes (presumably #2052) made this pull request unmergeable. Please resolve the merge conflicts.

@Minoru
Copy link
Contributor Author

Minoru commented Feb 2, 2021

I still want to have the discussion, so I'll hold off making any changes until it's decided if these bindings have a place in this crate.

@JohnTitor
Copy link
Member

Thanks for clarifying, hmm, then I doubt we should this to the UNIX module. And the tweak for Apple targets is tricky, as you said, so it should have some comments at least, I believe.

/cc @Amanieu Any thoughts on this?

@Amanieu
Copy link
Member

Amanieu commented Feb 10, 2021

I'm thinking option 4 might be the best:

link to "libc iconv" unconditionally, let someone else provide libiconv bindings;

However we should only provide bindings if this API is actually provided by libc. So for example this wouldn't be present on OpenBSD.

EDIT: Just to clarify, by "libc" I mean that the library is provided as part of the base OS. So we would still support it on Apple even though it is in libiconv instead of libc.

@Minoru
Copy link
Contributor Author

Minoru commented Feb 10, 2021

All done, please take a look.

@Amanieu
Copy link
Member

Amanieu commented Feb 10, 2021

@bors r+

@bors
Copy link
Contributor

bors commented Feb 10, 2021

📌 Commit 3e4d684 has been approved by Amanieu

@bors
Copy link
Contributor

bors commented Feb 10, 2021

⌛ Testing commit 3e4d684 with merge 2a2196d...

@bors
Copy link
Contributor

bors commented Feb 11, 2021

☀️ Test successful - checks-actions, checks-cirrus-freebsd-11, checks-cirrus-freebsd-12, checks-cirrus-freebsd-13
Approved by: Amanieu
Pushing 2a2196d to master...

@bors bors merged commit 2a2196d into rust-lang:master Feb 11, 2021
@@ -360,6 +361,7 @@ fn test_openbsd(target: &str) {
"pthread_np.h",
"sys/syscall.h",
"sys/shm.h",
"iconv.h",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this break the test on OpenBSD : no iconv.h file here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just made #2067 to unbreak OpenBSD

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, sorry — that's leftovers from the time when the bindings were in the unix mod. The similar problem affects Android, Solari-sh, Redox and a few other targets, I'll submit a PR fixing that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done: #2068

@Minoru Minoru deleted the feature/iconv branch February 11, 2021 11:50
bors added a commit that referenced this pull request Feb 12, 2021
Remove unused iconv.h includes

These are left over from 3e4d684, which
added includes to *all* platforms despite adding bindings only to *some*
of them. This already broke OpenBSD which doesn't have iconv.h (fixed by
915d8fa), and is just distasteful, so
down with those unused includes.

(This is a continuation to #2037 and #2067.)
bors added a commit that referenced this pull request Apr 29, 2021
Don't unconditionally link libiconv on macOS.

This adds `#[link(name = "iconv")]` to just the iconv symbols so that the
library is only linked if the symbols are used.

#2037 added a build.rs directive to always link libiconv on Apple platforms,
but that shouldn't be necessary. With this change, we can see using `otool -L`
that a binary that uses an `iconv` symbol links libiconv, but other binaries
don't.

Note that this can only be seen with a rustc prior to nightly-2021-03-09, as
nightly-2021-03-10 includes rust-lang/rust#82731 which
includes #2037, therefore unconditionally linking all Rust binaries to
libiconv.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants