Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Adding a command to generate the env information for linking #8021

wants to merge 1 commit into from

8 participants

John Harrison Charlie Sharpsteen Adam Vandenberg Mike McQuaid William Woodall Jack Nagel Samuel John Max Howell
John Harrison

Adding a command to generate the env information for linking for linking aginst a library. This is useful for keg_only formula and for generating the correct -I and -L information for any formula including its dependencies.

Basically, if I have an external project that I don't want to put in homebrew but I would like to link against a keg_only formula, this script could help me generate the env variables needed to build my project.

Charlie Sharpsteen

Looks useful---I will review when I get the chance.

John Harrison

So, an example of how one might use this. For instance, say I want to use brew's keg only libiconv for whatever reason. I could install it as per usual, then do:

$ cd /path/to/my/project
$ brew env-info libiconv | xargs env make

It will set:
CFLAGS="-O3 -march=core2 -msse4.1 -w -pipe"
CXXFLAGS="-O3 -march=core2 -msse4.1 -w -pipe"

So now my include path should include libiconv from the keg as well as the right lib directory for linking. It would still be up to me to link against the library and deal with any issues when a keg is shadowing a built-in library. It should also be pretty easy to parse this output and append it to a Makefile.

Anyway, just thought I would show a bit of the motivation for this command. I'll try to write a --help for it as well.

@@ -0,0 +1,89 @@
+require 'formula'
+require 'extend/ENV'
+require 'hardware'
Jack Nagel Owner

The HOMEBREW_ environment variables aren't really useful in this context, no?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
John Harrison

@jacknagel Good point, they really are not useful for this command. I just copied the whole list from the cmd/--env.rb file. I'll take those out.

William Woodall wjwwood referenced this pull request from a commit
John Harrison ashgti Adding in the ability to specify the specific flags you want to print…
…. In case you only need a subset of the ENV variables.

Closes #8021.

Signed-off-by: William Woodall <>
Adam Vandenberg

Probably needs to be squashed to a single commit for review

John Harrison

Squashed the commits.

Mike McQuaid

Does brew --env not already pretty much do this? We could either edit the output of that command or add another option to output in a format suitable for source or eval.

William Woodall

brew --env doesn't give the keg paths like CPPFLAGS="-I/usr/local/Cellar/libiconv/1.14/include" for example.

When I run something like this:

∫ brew info readline
readline 6.2.2

This formula is keg-only.
OS X provides the BSD libedit library, which shadows libreadline.
In order to prevent conflicts when programs look for libreadline we are
defaulting this GNU Readline installation to keg-only.

/usr/local/Cellar/readline/6.2.2 (30 files, 1.7M)

∫ brew --env readline
CC: /usr/bin/clang
CXX: /usr/bin/clang++ => /usr/bin/clang
LD: /usr/bin/clang
CFLAGS: -Os -w -pipe -march=native -Qunused-arguments
CXXFLAGS: -Os -w -pipe -march=native -Qunused-arguments

This doesn't tell me anything about how to compile and link against the keg-only readline formula.

The use case as I understood it was to provide an easy mechanism for having your source projects find the flags needed to compile and link against keg-only formulae outside of Homebrew.

Mike McQuaid

Perhaps we should modify brew --env to work the way that is useful rather than adding another very similar command.

John Harrison

I could work my changes into brew --env, should I make a new branch/pull request or should I just modify this one?

Jack Nagel

Anything that goes into brew --env would have to be much less complex than this; I don't think we want 15 options to the --env switch. I think brew --env <formula> is about as far as we'd want to go.

IMO an external command is the place to start with this, and the most useful things can be ported to brew --env eventually.

Mike McQuaid

@jacknagel Is there any reason we can't use the same output format? The only difference I see is the LDFLAGS, CPPFLAGS and output format. If we change the output format then we don't need any flag changes; brew --env formula could do what is desired here and brew --env could either just output what it currently does or output what it currently does in the new shell-friendly format.

Jack Nagel

brew --env already gives output suitable for machine consumption when stdout is not a tty, e.g. so it can be sourced.

Mike McQuaid

Neat. Then I definitely think we just want support for brew --env <formula> and that should match the functionality here.

@ashgti Just modify this pull request, thanks. As said you probably just need to add the LDFLAGS and CPPFLAGS when you specify a formula.

Samuel John

@ashgti would be cool if you could do that!

John Harrison

I squashed this into a simple extension of brew --env so you can add formula to brew --env. If you do brew --env readline (which is keg only), it now extends CPPFLAGS and LDFLAGS to include the paths to the keg, which was the main objective of this command to begin with.

Samuel John

It displays
CPPFLAGS: /usr/local/Cellar/readline/6.2.2/include
shoudn't there be an "-I" in front?
Similar for LDFLAGS.

Samuel John

@jacknagel how would I source the output of brew --env? Piping it so source doesn't work. I am too stupid.

Samuel John

Further, the CPPFLAGS and LDFLAGS from homebrew are overwritten by your changes. Compare brew --env with brew --env readline on a homebre not at /usr/local or on a homebrew without the command line tools . Could you append instead of replacing the CPPFLAGS and LDFLAGS?

Something along the lines:

    ARGV.formulae.each do |f|
      ENV.append "CPPFLAGS", "-I#{f.include}"
      ENV.append "LDFLAGS", "-L#{f.lib}"
Jack Nagel
$ brew --env >/tmp/foo
$ source /tmp/foo
Samuel John

Ok, thanks :-)

John Harrison

I updated it to append instead of override LDFLAGS and CPPFLAGS

John Harrison

I added a guard if formula.keg_only? and made it prepend the path instead of append, this way, if you say, for example, brew --env readline it puts readline in front so you get it instead of the system version. Otherwise you still have the system path listed before the keg path.

Samuel John

Great. Is prepending the action that is done when I add a keg-only formula, too?

John Harrison

It only appends keg only formula, if its not keg only then just having /usr/local/include and /usr/local/lib is enough for you to find and link to the libraries. The path /usr/local is at the end of the list, here's a better example:

$ brew --env readline sdl > /tmp/my-flags
$ cat /tmp/my-flags
export CC="/usr/bin/clang"
export CXX="/usr/bin/clang++"
export LD="/usr/bin/clang"
export CFLAGS="-Os -w -pipe -march=native -Qunused-arguments -mmacosx-version-min=10.7"
export CXXFLAGS="-Os -w -pipe -march=native -Qunused-arguments -mmacosx-version-min=10.7"
export CPPFLAGS="-I/usr/local/Cellar/readline/6.2.2/include -isystem /usr/local/include"
export LDFLAGS="-L/usr/local/Cellar/readline/6.2.2/lib -L/usr/local/lib"
export MAKEFLAGS="-j8"
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig/:/usr/local/share/pkgconfig:"

Here if you wanted to link your project against say readline (which is keg only) and sdl (which is not) it will give you this set of CPPFLAGS/LDFLAGS. Then, you can either export these flags or add them to a make file and things should hopefully work correctly. All of the SDL includes should be in /usr/local/include since its not keg-only.

Samuel John

I just want to make sure that the content of the env flags are ordered the same way as homebrew uses internally, otherwise it may be bad for debugging linking errors etc..

Adam Vandenberg

In fact code should be refactored to ensure that they are the same, though that's perhaps a bigger piece of work.

John Harrison In the build.rb file ENV.prepend is used if its keg_only?. So, thats what I am trying to copy. I only added the CPPFLAGS and LDFLAGS, but there are a few other options that are set for normal dependency builds, such as PKG_CONFIG_PATH, ACLOCAL_PATH and PATH.

Samuel John
John Harrison ashgti Extending `brew --env` to include formula info
Extending `brew --env` to include formula include paths so you can easily find keg only formula from outside of brew.
Samuel John

The new commit looks good. For now, this is what we want to have. For the future, we want to refactor the code ... but until then... :-)

Max Howell

brew --env sort of supports this now. But only for superenv. It wouldn't be hard to make it work for std-env.

For superenv you can also do:

brew sh

And it will start a shell with all keg-only kegs set up in the environment for building.

Adam Vandenberg

@mxcl - reject this?

Mike McQuaid

Rejecting as it's supported by brew sh.

Mike McQuaid mikemcquaid closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 16, 2012
  1. John Harrison

    Extending `brew --env` to include formula info

    ashgti authored John Harrison committed
    Extending `brew --env` to include formula include paths so you can easily find keg only formula from outside of brew.
This page is out of date. Refresh to see the latest.
Showing with 15 additions and 0 deletions.
  1. +15 −0 Library/Homebrew/cmd/--env.rb
15 Library/Homebrew/cmd/--env.rb
@@ -6,6 +6,21 @@ def __env
ENV.universal_binary if ARGV.build_universal?
+ ARGV.formulae.each do |f|
+ # NOTE: Copied from build.rb def install (line ~63)
+ # TODO: Refactor to have a single instance of this code.
+ if dep.keg_only?
+ ENV.prepend 'LDFLAGS', "-L#{dep.lib}"
+ ENV.prepend 'CPPFLAGS', "-I#{dep.include}"
+ ENV.prepend 'PATH', "#{dep.bin}", ':'
+ pcdir = dep.lib/'pkgconfig'
+ ENV.prepend 'PKG_CONFIG_PATH', pcdir, ':' if
+ acdir = dep.share/'aclocal'
+ ENV.prepend 'ACLOCAL_PATH', acdir, ':' if
+ end
+ end
if $stdout.tty?
dump_build_env ENV
Something went wrong with that request. Please try again.