-
-
Notifications
You must be signed in to change notification settings - Fork 267
Support building phobos against a system copy of zlib #4742
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
Conversation
I have now seen that #4716 already existed, but compared to it, this PR correctly handles linking to static phobos and it doesn't affect the druntime libraries at the cost of slightly changing the compiler linker code. |
I think it would be beneficial to add a changelog entry and a CI run for this option. Is circleci the preferred runner? |
Thanks for doing this; LGTM after a superficial glance. Yeah some CI coverage would be great; CircleCI is just kept because it doesn't hurt/get in the way; Cirrus is unfortunately not a sufficient free option anymore, so in essence it's all GitHub's own CI now, they managed to kill all competitors (for open-source projects) unfortunately (edit: and with the help of crypto-kiddies). You could e.g. select one of the jobs in https://github.com/ldc-developers/ldc/blob/master/.github/workflows/supported_llvm_versions.yml; we use them for testing some CMake permutations too. |
@@ -61,6 +61,10 @@ if (RT_SUPPORT_SANITIZERS) | |||
list(APPEND D_FLAGS -d-version=SupportSanitizers) | |||
endif() | |||
|
|||
if(PHOBOS_SYSTEM_ZLIB) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, we'd bake this into the ldc-build-runtime
CMake invocations too, in
ldc/runtime/ldc-build-runtime.d.in
Lines 152 to 157 in 0cc531e
string[] args = [ | |
"cmake", | |
"-DLDC_EXE_FULL=" ~ config.ldcExecutable, | |
"-DDMDFE_MINOR_VERSION=@DMDFE_MINOR_VERSION@", | |
"-DDMDFE_PATCH_VERSION=@DMDFE_PATCH_VERSION@", | |
]; |
CHANGELOG.md
Outdated
@@ -5,6 +5,7 @@ | |||
- LLVM for prebuilt packages bumped to v18.1.8 (incl. macOS arm64). (#4712) | |||
- Android: NDK for prebuilt package bumped from r26d to r27. (#4711) | |||
- ldc2.conf: %%ldcconfigpath%% placeholder added - specifies the directory where current configuration file is located. (#4717) | |||
- Add support for building against a system copy of zlib through `-DPHOBOS_SYSTEM_ZLIB=ON` (#4742) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you're revising this PR, please add a trailing full stop here.
CMakeLists.txt
Outdated
@@ -149,6 +149,9 @@ set(LDC_ENABLE_ASSERTIONS "${LLVM_ENABLE_ASSERTIONS}" CACHE BOOL "Enable LDC ass | |||
# Allow user to specify mimalloc.o location, to be linked with `ldc2` only | |||
set(ALTERNATIVE_MALLOC_O "" CACHE STRING "If specified, adds ALTERNATIVE_MALLOC_O object file to LDC link, to override the CRT malloc.") | |||
|
|||
# Most linux distributions have a policy of not bundling dependencies like zlib | |||
set(PHOBOS_SYSTEM_ZLIB OFF CACHE BOOL "Use the system copy of zlib when building phobos") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd probably slightly rephrase this, something like 'use system zlib instead of Phobos' vendored version'.
Note that the D bindings have hardcoded zlib version numbers which might be off then: https://github.com/dlang/phobos/blob/f7e523bc3c69506c3e7b4da7e78af93ed8547910/etc/c/zlib.d#L45-L47
The actual API has been pretty stable AFAIK, so I don't think this matters in practice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've asked in the Gentoo irc rooms what would are the appropriate version of zlib that we can use given that we hardcode the headers to a certain version and the response was that, given it's zlib, so long as we link against libz.so.1
it should be fine.
If we want to restrict the version we can do that inside the find_package
call so if we end up with an incompatible version of zlib in the future we can fail during configuration. For now I think that we shouldn't overly restrict the check unless we know for certain that a zlib version doesn't work.
This is achieved by linking the dynamic variant of phobos against zlib and having the compiler add -lz when linking an application that embeds the static variant of phobos. Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Signed-off-by: Andrei Horodniceanu <[email protected]>
Rebased onto master to fix the macos xcode failure. |
Just had a meeting about this with DLF. I think this doesn't go far enough. If you call any I have been running into this problem for years from my raylib-d install script, without knowing the cause! I would suggest that instead of linking against -lz only for static builds, you link against -lz always (when the |
Yeah that should be doable. FWIW, I didn't think anyone would really use the |
std.zlib is not good for streaming. e.g. in iopipe, I have a in other words, std.zip does not expose well enough the capabilities of zlib. |
I'll write here my concerns as well. If people want to use If it matters adding |
There is no transitive link dependency -- official phobos currently includes zlib statically. That is, phobos defines these functions, and that is expected and supported. The non-standard case here is the decision not to include zlib in phobos. If you are going to do this, the installation should compensate for it -- by adding the necessary link directives that you normally wouldn't need. |
Alright, neither of us seems to be willing to change their views. Your belief is that because phobos has been compiled so far in a way that embeds zlib then it should be guaranteed to all consumers that the C functions are available as well. It is my belief that the current way phobos embeds zlib is simply a happenstance and no one actually made a conscious decision from the angle of whether the C symbols would be available to consumers, whoever made the choice simply wanted to make sure that phobos could use zlib for But whatever the actual reason is, is outside of our beliefs. Right now what needs to happen is for
If it matters I can try to take a look at doing this for |
It's not a matter of opinion or intent. It's a matter of facts. zlib is included with phobos, including linkable symbols from etc.c. This means that a valid D install should be able to link without explicit -lz parameters. Note that I'm not really in favor of this method of distribution for zlib. It's just, that's what we have now. Contrast that with std.net.curl, which has no statically linkable symbols. If you use std.net.curl without providing a curl library to run against, your code will fail. That is a very different experience from std.zip. If we did not include zlib, then users of std.zip would be required to link against -lz. I'm perfectly fine if that's the way we want to go. I've even advocated for it! But what I don't agree with is a state where some compiler distributions have made it so you cannot link applications which build just fine with other distributions of the same compiler. This leads to very puzzling bug reports, without much evidence of why it is happening. That is my experience. This entire PR is evidence of the requirement! Without this mechanism, you had to add -lz for static builds. Now, the compiler does it for you. Why can't the compiler do this for builds against dynamic phobos? |
Ok, I don't think it's a good use of both of our time so I'll try to refrain from commenting much:
phobos needs zlib => a way to solve this is embed zlib
Where is this documented?
This is the whole discussion. You can use
Yes, the lack of a clearly stated and written documentation about whether this is should be supported is a reason for this argument.
It's not a matter of if it can, it's a matter of why should it (outside of staying consistent with previous behavior) when phobos works without it. |
Well, I don't see the point of hiding the symbols on purpose, when you are including them. But in any case, there are better arguments to have. I think the best path forward is to add -lz to all these adjusted packages, either through the compiler or the .ini file. |
@@ -583,6 +583,10 @@ void ArgsBuilder::build(llvm::StringRef outputPath, | |||
for (const auto &name : defaultLibNames) { | |||
args.push_back("-l" + name); | |||
} | |||
#ifdef PHOBOS_SYSTEM_ZLIB | |||
if (!defaultLibNames.empty() && !linkAgainstSharedDefaultLibs()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC, to enable what Steven wants, we'd just remove the !linkAgainstSharedDefaultLibs()
condition here. Meaning that if the compiler was configured with PHOBOS_SYSTEM_ZLIB, and the user hasn't cleared the -defaultlib
list, it implicitly adds -lz
for linking on Posix.
On Windows, we'd actually have to export all zlib symbols from the Phobos DLL in order to enable user code to use the etc.c.zlib
bindings directly when using -link-defaultlib-shared
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std.zip or std.zlib? The latter has 2 helper classes for chunked (de)compression, looking suitable for streams. If insufficient, I guess that module should be extended to accomodate for such usage, so that almost noone should have to resort to |
Some projects use the zlib C function directly and, given that those symbols are available when phobos embeds zlib (the default) and when linking the stdlib statically, the projects often don't include a `-lz` in their build settings. This omission then prevents a successful build with PHOBOS_SYSTEM_ZLIB=on and -link-defaultlib-shared. Until a permanent decision is made if those projects should change their build scripts or if the compiler should always add `-lz`, add the library anyway, to minimize breakages. This also makes the behavior consistent with gdc which also adds an unconditional `-lz` when zlib is not embedded. See-Also: ldc-developers#4742 Signed-off-by: Andrei Horodniceanu <[email protected]>
Some projects use the zlib C function directly and, given that those symbols are available when phobos embeds zlib (the default) and when linking the stdlib statically, the projects often don't include a `-lz` in their build settings. This omission then prevents a successful build with PHOBOS_SYSTEM_ZLIB=on and -link-defaultlib-shared. Until a permanent decision is made if those projects should change their build scripts or if the compiler should always add `-lz`, add the library anyway, to minimize breakages. This also makes the behavior consistent with gdc which also adds an unconditional `-lz` when zlib is not embedded. See-Also: #4742 Signed-off-by: Andrei Horodniceanu <[email protected]>
Many Linux distributions including Debian, Fedora, and, Gentoo, have a policy of unbundling 3rd party dependencies like zlib from software projects. This PR implements support for this so that distributions don't have to implement the same logic individually.
Currently Debian does remove the zlib code but they leave the static variants of libphobos with undefined symbols to zlib functions making
-link-defaultlib-shared=false
require the additional-lz
switch when specified by users. Fedora tried a patch but it resulted in the build being broken so it has been reverted. Gentoo doesn't do anything currently but I am making this PR instead.These changes are all behind the
-DPHOBOS_SYSTEM_ZLIB=TRUE
cmake argument so the current code will continue to behave the same and the dependency on zlib is strictly opt-in. A possible unwanted interaction is that, when cross-compiling, ldc2 will try to link-lz
just like it would when building for the build host but zlib may not exist on the target system. The only solution for this is specifying-defaultlib= -L-l:libphobos2-ldc.a -L-l:libdruntime-ldc.a
which is a mouthful but it is either this or complicating the linker code more.An implementation downside of the code is that the phobos config option is placed inside the root CMakeLists.txt because the compiler needs to know whether it needs to links zlib when building statically and, since it is built with a custom_target its target compile arguments can not be modified through something like
target_compile_definitions
after the runtime subdirectory has been included.What this PR doesn't support is
MULTILIB=ON
andPHOBOS_SYSTEM_ZLIB=TRUE
simultaneously because cmake, or any other build system that I know of, doesn't allow to specify the ABI when looking for a package. The standard way of compiling for multiple ABIs is to setup a different build directory and configuring cmake for that ABI which is done by setting PKG_CONFIG_PATH to point to the correct libdir and setting environment variables for the toolchain similar toCC="gcc -m32" CXX="g++ -m32" DMD="ldmd -m32"
. The current cmake code worked for this with only minor changes but I didn't dive in too deeply yet.I've made plenty of last minute improvements that ended up breaking something so it's fine if this PR waits for the new upcoming release to happen first and then be merged.