Closed railwaycat closed 4 years ago
Quote from release notes of Xcode 10:
The Command Line Tools package installs the macOS system headers inside the macOS SDK. Software that compiles with the installed tools will search for headers within the macOS SDK provided by either Xcode at:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk
or the Command Line Tools at:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
depending on which is selected usingxcode-select
.
I think we can make the modification in each *.pc
file under Library/Homebrew/os/mac/pkgconfig/10.14
to use one of the paths above instead of /user/include
.
But the question is which one should we pick? Can we assume all Homebrew users have Xcode or have Command Line tools?
It says xcode-select
will gives the path of current using, unfortunately we cannot run external command in *.pc
files.
Can we assume all Homebrew users have Xcode or have Command Line tools?
We cannot assume either. It may be we need separate files for each.
I did discover I could do this as a work around. It certainly isn't a final solution, but for people who are stuck, this adds files to /usr/include
.
sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
@tomkrouper Unfortunately that package isn't recommended by Apple and is likely to break things in future in Homebrew 😭
@tomkrouper Thanks for the update! Yes, this is the workaround in release notes of Xcode, and these words are also mentioned:
If you are the maintainer of such software, we encourage you to update your project to work with the SDK or file a bug report for issues that are preventing you from doing so. As a workaround, an extra package is provided which will install the headers to the base system. In a future release, this package will no longer be provided.
So even it works for now, soon or later we still need a fix..
This is causing build failure in root
: https://github.com/Homebrew/homebrew-core/issues/32949#issuecomment-431289362
This issue is actually not limited to libxml2. All .pc
files in Library/Homebrew/os/mac/pkgconfig/10.14
assume that headers are in /usr/include
, which is definitely not true anymore. This is only manifesting in libxml2 because its headers are in /usr/include/libxml2
, while other headers are all directly in /usr/include
and pkg-config appears to filter that one out…
I think PKG_CONFIG_SYSROOT_DIR
is a possible solution here.
brew
would set PKG_CONFIG_SYSROOT_DIR
in the environment to point to the right directory.pc
files can be rewritten to use pc_sysrootdir
@fxcoudert Sounds good 👍
Hello-
I have just run into this issue using homebrew on macOS High Sierra v10.13.4 to install root and I am wondering how I should go about fixing this error. I am fairly new with mac and do not follow the above comment enough to know what commands I'd need to run. Any suggestions would be greatly appreciated!
@bmlett The details of a possible fix are in @fxcoudert's comment above.
@fxcoudert's solution is an excellent one, with one caveat - when setting the sysroot, brew
should verify that the SDK in use corresponds to the current OS version. While, for example, using the 10.13 SDK to target 10.14 (as might happen if the user has Xcode 9.4 installed and selected on Mojave) will work most of the time, it's obviously not ideal. Whether an SDK/OS mismatch should be a hard error (with override possible), a warning, or a note in brew doctor
, I'm not sure. (Though since the selected Xcode (and thus available SDKs) can change at any time, I imagine it's probably better as at least a warning.)
I just tested this a bit and the PKG_CONFIG_SYSROOT_DIR
environment variable and pc_sysrootdir
variable inside .pc
files, seems like a good fit. I tried the following patch:
diff --git a/Library/Homebrew/os/mac/pkgconfig/10.14/libxml-2.0.pc b/Library/Homebrew/os/mac/pkgconfig/10.14/libxml-2.0.pc
index c297c6b454..7e467b9fc6 100644
--- a/Library/Homebrew/os/mac/pkgconfig/10.14/libxml-2.0.pc
+++ b/Library/Homebrew/os/mac/pkgconfig/10.14/libxml-2.0.pc
@@ -1,7 +1,7 @@
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
-includedir=${prefix}/include
+includedir=${pc_sysrootdir}${prefix}/include
modules=1
Name: libXML
along with export PKG_CONFIG_SYSROOT_DIR=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
and got the following:
$ export PKG_CONFIG_SYSROOT_DIR=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
$ $ pkg-config --cflags --libs "libxml-2.0 > 2.6.17"
-I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/libxml2 -lxml2
Are we intending to set this environment variable in super.rb
? We may need to add a caveat or some other messaging for people hoping to use pkg-config
outside of a brew
command that they need to set this variable themselves.
Also, setting PKG_CONFIG_SYSROOT_DIR
globally can cause other pkg-config files to fail, as I just noticed as I moved on to another task in the same terminal that I did this testing:
CMake Error in src/CMakeLists.txt:
Imported target "ignition-common3::requested" includes non-existent path
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/Cellar/ossp-uuid/1.6.2_2/include/ossp"
in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:
@fxcoudert any thoughts on how the environment variable should be set? super.rb
?
I don’t think setting the environment variable is a good option if it fixes things sometimes and breaks things other times.
Apparently PKG_CONFIG_SYSROOT_DIR
has two effects: it sets pc_sysrootdir
(which we want), but also inserts that value as a new root in all -I
and -L
flags, which we definitely don't want.
Another option is to use superenv to always pass --define-variable=
to define our own variable, which we will then use in Homebrew's .pc
files.
Another option is to use superenv to always pass
--define-variable=
to define our own variable, which we will then use in Homebrew's.pc
files.
This could work. Would we need a pkg-config
shim?
Honestly I'm still pretty tempted by the "have duplicates" option; the overhead isn't bad, it doesn't exceed the rule of three and is the simplest to edit/debug/etc.
Thoughts?
Would we need a pkg-config shim?
Yeah, and that's an added cost in terms of complexity, sadly.
Honestly I'm still pretty tempted by the "have duplicates" option
That work for CLT, where things are in /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
. But how would it work for non-CLT users, where things are in Xcode.app
?
We assume a default Xcode location or fail the build, I think.
Using a default Xcode location will definitely fail for a large number of common scenarios - the only guaranteed correct behavior is to use the result of running xcrun -sdk macosx -show-sdk-path
at the time of invocation (i.e. don't cache the result). Despite the complexity, a pkg-config
shim seems the best option to me; "have duplicates" runs afoul of too many common configurations.
This is only in the Xcode-only case on certain OSs so is not a widespread problem.
At this point it's pretty much "whoever can first create a PR to solve the problem(s) here will probably get their approach merged". I think we're probably reaching the end of discussion being more valuable than (any) code approach.
This is only in the Xcode-only case on certain OSs so is not a widespread problem.
Or, to be more exact, would not be a problem for the majority of our users.
As said in the release notes, the CLT are going away, which means it will probably eventually be everyone's problem.
@gwynne As I've said to the other Apple employees that have raised this with me previously (and feel free to email me at mike@mikemcquaid.com if you want to be in the Slack private room for Apple employees and Homebrew maintainers to talk): I don't see a solution to problems that led Homebrew maintainers (among others) to campaign for the CLTs creation such as:
mas
)If all of the above were resolved I'd be more confident in Homebrew being able to move to "Xcode-only" being a well supported configuration and eventually primary one. Even now we get backlash from both sides because some people don't want to install Xcode (see reasons above) and others claim the CLT is identical to Xcode so there's no reason they should ever have it installed (which is not the case when using Homebrew).
@gwynne As a more meta-complaint that's not specific to you but is more a comment on stuff like this in general: it'd be really great if the relevant teams in Apple could figure out how it wants to provide information and have discussions with Homebrew. If the private Slack room we currently have doesn't work: can someone suggest something that will?
For those watching: we've figured out some ways for Apple and us to talk.
Sounds like the pkg-config
shim is now the best option.
I’d be interested in helping out here if desired. It looks like y’all are well on your way to a solution, but on the off chance that you still need a hand, please let me know.
@manchicken Yes, thanks. A PR would be welcome.
Is there an doc on the build process you all use that you could link me to? I can’t find it, and it seems a bad idea to install on my regular box.
~ Michael D. Stemle, Jr.
On Feb 23, 2019, at 07:50, Mike McQuaid notifications@github.com wrote:
@manchicken Yes, thanks. A PR would be welcome.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
Is there an doc on the build process you all use that you could link me to? I can’t find it, and it seems a bad idea to install on my regular box.
@manchicken I don't understand the question, sorry. It's fine to do Homebrew development on your normal Homebrew installation if that's what you mean.
Closing this out as we don't seem to have agreement on an approach that won't break current workflows. This will likely be handled by later macOS versions getting rid of some of these paths.
I think a/the workaround for this is that we use Homebrew dependencies for stuff that requires pkg-config files rather than creating our own for macOS/Xcode provided libraries that don't provide then.
I think that makes sense, though it does mean potentially more double libs. That seems like the only way to make sure that we don’t break every time we have an update.
Not only does this break stuff for repo packages, but folks who rely on pkg-config for building modules with C bindings for dynamic language (like npm modules, or eggs, or gems, or Perl modules) also have to deal with this stuff.
~ Michael D. Stemle, Jr.
On Apr 19, 2019, at 00:29, Mike McQuaid notifications@github.com wrote:
I think a/the workaround for this is that we use Homebrew dependencies for stuff that requires png-config files rather than creating our own for macOS/Xcode provided libraries that don't provide then.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
Reopening as @pcr910303 opened https://github.com/Homebrew/brew/issues/6656 to address this.
The potential solutions I see:
From my POV as an Emacs dev I'd be happy to have these removed as they completely break our build, which is supposed to detect the headers itself if it can't find them with pkg-config. I understand that that might break other applications, though.
Is there a good reason to prefer the Apple provided headers/libs over Homebrew's own packages?
@alanthird My understanding is that brew prefers using macOS-provided packages for everything. AFAIK it was the core differences between brew & macports.
Just want to share my thoughts here. Hopefully I can perhaps try and get this moving and help towards picking a direction.
Firstly,
- fix these paths to mandate Xcode and mandate its installation (I'm pretty 👎 on this)
I am also :-1:, not necessarily because of Xcode being mandated but because this, from a technical sense, would not work correctly on anything that is not the latest OS. For example, the latest version of Xcode on Mojave does not ship with Mojave system headers. This is almost certainly intentional. Though in those cases, I think Homebrew does require the CLT anyway (except if you use an older Xcode) unless I'm mistaken.
So for anything less than the latest macOS, it is perfectly fine, and expected, to mandate the CLT. As for the latest macOS, you do have a choice of what to use.
I however want to take a slight detour and raise a separate, but very much relevant, issue about pkg-config: the default search path. I'll explain why it plays a part in this dicussion in a moment.
Homebrew's pkg-config files are baked into the search path at compile time here. This works great except for one thing - when the user upgrades macOS. Homebrew does not deliver updates to pkg-config when upgrading macOS so until they reinstall pkg-config, it will continue to search at the path matching their previous macOS version. This behaviour is not clear at all and can cause some head scratches, but due to the lack of any real changes to the pkg-config files between macOS versions prior to now it hasn't really yet.
Now why is that relevant? Because this behaviour will start becoming a problem because there will be changes every macOS version. For simplicity sake, I'm going to ignore Xcode for now. If we focus on the CLT, we will have /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk
for 10.14, /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk
for 10.15 and so on. We will want to ensure that people using pkg-config don't end up using the wrong SDK for their system. The SDK might also not even be available. Previously it was easy as /usr/include
would always point to the correct headers.
Note that /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
is not sufficient. To demonstrate this, this is how the symlinks are mapped on a (non-broken) CLT 11.2 install on 10.14:
$ ls -l /Library/Developer/CommandLineTools/SDKs
total 0
lrwxr-xr-x 1 root wheel 15 Nov 15 21:28 MacOSX.sdk -> MacOSX10.15.sdk
drwxr-xr-x 7 root wheel 224 Aug 27 07:28 MacOSX10.14.sdk
drwxr-xr-x 8 root wheel 256 Oct 17 13:19 MacOSX10.15.sdk
You must change the include location for every version of macOS.
So if we go the static route, we should also have measures in place to have the pkg-config binary reinstalled if the macOS version mismatches what it is built for.
An alternative approach discussed in this issue was a dynamic-based approach, which I'll now discuss.
In terms of shims: we need to remember that the pkg-config files offered are not exclusively used in a Homebrew environment. But currently shims are pretty much exclusively for that environment. For as long as Homebrew's pkg-config files are supported outside the Homebrew envornment, any shim would need apply globally. So ideally, you would want to make it so that invoking /usr/local/bin/pkg-config would go through the shim and have the real binary elsewhere.
Alternatively you could withdraw support for these pkg-config files outside a Homebrew environment if you desire, which would avoid the need of that complication. I suppose it comes down to a balance of feasibility, time, effort and reward. Personally, it would be nice if we didn't have to, but I realise it may ultimately become the only option.
Just to put it out, with the goal of covering all possible options here, introducing the dynamic element via forking/patching pkg-config itself is also an option. An option I suspect I already know what the answer would be, but something I nevertheless wanted to make mention to (and will help out with if pursued) so that every possible direction can be said to have been considered.
I think I've covered everything. If there's a direction I forgot to mention, let me know. Regardless of which approach is taken here, I am willing to help in drafting up a proof of concept of it.
Apologies for the length of this - I've tried to be comprehensive here. Hopefully something I've said here will have been useful.
Hopefully I can perhaps try and get this moving and help towards picking a direction.
That would be great 🎉
Homebrew does not deliver updates to pkg-config when upgrading macOS so until they reinstall pkg-config, it will continue to search at the path matching their previous macOS version.
This is a good point. It's something we should probably add some sort of check to the formula for so when pkg-config
is used as a dependency it can automatically reinstall. Presumably this also means we should never use or_later
bottles for png-config
? Alternatively, I wonder if we should specify multiple OS paths in this case and have them effectively just fall back if they don't exist 🤔
Alternatively you could withdraw support for these pkg-config files outside a Homebrew environment if you desire, which would avoid the need of that complication.
I'm not aware of our explicit support for this but, yeh, I think we should keep on the table that these files are unsupported outside of our environment.
Just to put it out, with the goal of covering all possible options here, introducing the dynamic element via forking/patching pkg-config itself is also an option.
Definitely don't want to fork but if we could have a small patch (particularly done with inreplace
) and that results in a much less complicated solution over all: we should consider it.
Apologies for the length of this - I've tried to be comprehensive here. Hopefully something I've said here will have been useful.
Lots useful said, please don't apologise! Thanks for your thoughts on this and, hopefully, future PRs 😉
I've seen several pull requests recently which could have found it useful to have this working so let's try progress this.
Firstly, what I propose the *.pc files look like is this:
prefix=${homebrew_sdkroot}/usr
exec_prefix=/usr
libdir=${exec_prefix}/lib
includedir=${prefix}/include
To fully solve this we need to:
homebrew_sdkroot
to equal the SDK we want. Again this needs to be done at runtime (such as fetching the HOMEBREW_SDKROOT
environment variable).It turns out this isn't that complex. The approach here on depends on how much we care about pkg-config outside of the Homebrew superenv.
To make it work outside the Homebrew superenv, a patch is required. Here's one that should cover everything. All that's needed is to apply the patch, add ENV.append_to_cflags "-DHOMEBREW_LIBRARY=\\\"#{HOMEBREW_LIBRARY}\\\""
and remove the aforementioned existing *.pc path line. Nothing else required:
$ pkg-config --cflags libxml-2.0
-I/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/libxml2
Alternatively, we can avoid a patch by withdrawing the capability to use Homebrew's *.pc files outside of the Homebrew superenv. I've not fully tested this, but basically we would need to:
pkg-config
. This should supply --define-variable=homebrew_sdkroot=$HOMEBREW_SDKROOT
to pkg-config.However, doing this would also be dropping support for Homebrew *.pc files for the std env (alongside outside of Homebrew altogether - though support isn't explicit there). This is because we don't shim in the std env. I know this isn't used in homebrew-core, but it could be a breaking change for some taps.
It turns out this isn't that complex. The approach here on depends on how much we care about pkg-config outside of the Homebrew superenv.
I would say: we don't care about it until we get (multiple) complaints.
However, doing this would also be dropping support for Homebrew *.pc files for the std env (alongside outside of Homebrew altogether - though support isn't explicit there). This is because we don't shim in the std env. I know this isn't used in homebrew-core, but it could be a breaking change for some taps.
I think this is reasonable given the unresolved issues in this issue.
Good call @Bo98, happy to help review a PR!
Removing support for the Homebrew supplied *.pc files in pkg-config
is going to be problematic I think: I am experiencing a problem already trying to build some software manually against glib (which provides gio-2.0
):
configure: error: Package requirements (gtkmm-3.0 >= 3.0.0) were not met:
Package 'zlib', required by 'gio-2.0', not found
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
Alternatively, you may set the environment variables gtkmm_CFLAGS
and gtkmm_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
I think it's fair to say this will affect quite a few people, since lots of formulas depend on zlib
.
It is still available in the superenv. Is this for outside the Homebrew environment?
Yep: this is just for compiling a package manually using ./configure, make, make install
using Homebrew provided packages.
I kinda consider Homebrew packages using Homebrew's superenv at runtime to be a bit of a smell.
I suppose the Homebrew *.pc files never were explicitly part of the superenv. They're not even in the superenv folder. It probably predates the superenv but I haven't checked Git history.
I cannot see anything further than can be done beyond patching pkg-config, or somehow convincing Apple to ship *.pc files in the SDK (not going to happen).
Using brew sh
is a workaround, but I know that's not really appropriate for all cases.
Patching pkg-config
looks necessary I think. The patch you mentioned before looks good to me.
I don't want us carrying a pkg-config
patch indefinitely that will never be upstreamed.
Note that Xcode-only means that all these uses of pkg-config
would have already been broken. I don't think we should be worrying too/as much about how we change behaviour for stuff outside the Homebrew ecosystem. The pkg-config
files we've been providing are effectively nice hacks to more easily use system libraries when you have the CLT installed. If that gets scoped to being only used for our use-case: I think the short-term pain is worth the long-term decrease in support surface.
That said: if we get large numbers of complaints/issues: we can consider another option.
I appreciate that carrying that patch around indefinitely is not ideal, but something definitely needs to happen.
Now that pkg-config no longer looks for Homebrew provided *.pc
files, it will be very hard for lots of people to compile software manually using autotools, cmake, meson and others, as soon as a Homebrew library is required that drags in zlib
or any of its friends.
When using pkg-config
standalone, problems can be solved by passing --define-variable=homebrew_sdkroot=my-sdkroot
, but to the best of my knowledge this same effect cannot be achieved with the aforementioned build tools.
Autotools lets you circumvent using pkg-config
by specifying _CFLAGS
and _LIBS
flags but this is not very user friendly. I am not aware of similar workarounds being available for CMake and meson.
Assuming you're not willing to drop Apple provided libraries in favour of their Homebrew counterparts, the only solution I see is patching pkg-config
. 😢
Been thinking through this a bit. There is one alternative but would require some groundwork in place first. It would involve all of the following occurring:
homebrew_sdkroot
to the *.pc files. This would be the CLT so Xcode-only systems would not be supported.
pkg-config
is marked as outdated if it was built on a different major OS version than it was installed. I'm not talking about HOMEBREW_SKIP_OR_LATER_BOTTLES
(though that would be a part of it), but rather if at any point a user upgrades macOS (excluding minor updates) then brew will immediately mark pkg-config as outdated. This would require to somewhere store the version of macOS used to build pkg-config
- which may have been installed from source or from a bottle.
pkg-config
specific though. That said, I am sure there are other formulae where this may be useful. For example, python3-config --cflags
looks problematic for macOS upgrades due to the SDK path & Tk version being baked in, so python
could be a potential candidate for using such feature. llvm
would definitely be another one. I imagine it becomes quite broken on macOS upgrades.
Please note we will close your issue without comment if you delete, do not read or do not fill out the issue checklist below and provide ALL the requested information. If you repeatedly fail to use the issue template, we will block you from ever submitting issues to Homebrew again.
brew
command and reproduced the problem with multiple formulae? If it's a problem with a single, official formula (not cask) please file this issue at Homebrew/homebrew-core: https://github.com/Homebrew/homebrew-core/issues/new/choose. If it's abrew cask
problem please file this issue at https://github.com/Homebrew/homebrew-cask/issues/new/choose. If it's a tap (e.g. Homebrew/homebrew-php) problem please file this issue at the tap.brew update
and can still reproduce the problem?brew doctor
, fixed all issues and can still reproduce the problem?brew config
andbrew doctor
and included their output with your issue?Warning: The following directories do not exist: /usr/local/sbin
You should create these directories and change their ownership to your account. sudo mkdir -p /usr/local/sbin sudo chown -R $(whoami) /usr/local/sbin % brew config HOMEBREW_VERSION: 1.7.6-143-gc6acab6 ORIGIN: https://github.com/Homebrew/brew HEAD: c6acab66feb63743fe69b38dab7dc7b90710e838 Last commit: 2 hours ago Core tap ORIGIN: https://github.com/Homebrew/homebrew-core Core tap HEAD: 537f3703aa41c550edbaaf28dd280c6ec929f946 Core tap last commit: 34 minutes ago HOMEBREW_PREFIX: /usr/local HOMEBREW_DEV_CMD_RUN: 1 CPU: octa-core 64-bit kabylake Homebrew Ruby: 2.3.7 => /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby Clang: 10.0 build 1000 Git: 2.17.1 => /Applications/Xcode.app/Contents/Developer/usr/bin/git Curl: 7.54.0 => /usr/bin/curl macOS: 10.14-x86_64 CLT: 10.0.0.0.1.1535735448 Xcode: 10.0 XQuartz: 2.7.11 => /opt/X11
fatal error: 'libxml/tree.h' file not found
include <libxml/tree.h>
1 error generated.
% which pkg-config /usr/local/bin/pkg-config
% pkg-config --cflags --libs "libxml-2.0 > 2.6.17" -I/usr/include/libxml2 -lxml2
% pkg-config --variable pcfiledir "libxml-2.0 > 2.6.17" /usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/10.14
% cat /usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/10.14/libxml-2.0.pc prefix=/usr exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include modules=1
Name: libXML Version: 2.9.4 Description: libXML library version2. Requires: Libs: -L${libdir} -lxml2 Libs.private: -lz -lpthread -licucore -lm Cflags: -I${includedir}/libxml2
% pkg-config --cflags --libs "libxml-2.0 > 2.6.17"