Skip to content
This repository has been archived by the owner on Jul 4, 2023. It is now read-only.

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

Closed
wants to merge 1 commit into from

Conversation

ashgti
Copy link
Contributor

@ashgti ashgti commented Oct 8, 2011

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.

@Sharpie
Copy link
Contributor

Sharpie commented Oct 8, 2011

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

@ashgti
Copy link
Contributor Author

ashgti commented Oct 9, 2011

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:
CC="/usr/llvm-gcc-4.2/bin/llvm-gcc-4.2"
CXX="/usr/llvm-gcc-4.2/bin/llvm-g++-4.2"
LD="/usr/llvm-gcc-4.2/bin/llvm-gcc-4.2"
CFLAGS="-O3 -march=core2 -msse4.1 -w -pipe"
CXXFLAGS="-O3 -march=core2 -msse4.1 -w -pipe"
CPPFLAGS="-I/usr/local/Cellar/libiconv/1.14/include"
LDFLAGS="-L/usr/local/Cellar/libiconv/1.14/lib"
MAKEFLAGS="-j2"

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.

ENV_VARIABLES = %w[ CC CXX LD CFLAGS CXXFLAGS CPPFLAGS LDFLAGS MAKEFLAGS
MACOSX_DEPLOYMENT_TARGET PKG_CONFIG_PATH HOMEBREW_DEBUG
HOMEBREW_VERBOSE HOMEBREW_USE_CLANG HOMEBREW_USE_GCC
HOMEBREW_USE_LLVM HOMEBREW_SVN PATH CMAKE_LIBRARY_PATH ]
Copy link
Contributor

Choose a reason for hiding this comment

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

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

@ashgti
Copy link
Contributor Author

ashgti commented Oct 12, 2011

@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.

@adamv
Copy link
Contributor

adamv commented Feb 4, 2012

Probably needs to be squashed to a single commit for review

@ashgti
Copy link
Contributor Author

ashgti commented Feb 4, 2012

Squashed the commits.

@MikeMcQuaid
Copy link
Member

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.

@wjwwood
Copy link
Contributor

wjwwood commented May 3, 2012

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
http://tiswww.case.edu/php/chet/readline/rltop.html

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)
https://github.com/mxcl/homebrew/commits/master/Library/Formula/readline.rb

∫ 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
MAKEFLAGS: -j4

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.

@MikeMcQuaid
Copy link
Member

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

@ashgti
Copy link
Contributor Author

ashgti commented May 4, 2012

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

@jacknagel
Copy link
Contributor

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.

@MikeMcQuaid
Copy link
Member

@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.

@jacknagel
Copy link
Contributor

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

@MikeMcQuaid
Copy link
Member

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.

@samueljohn
Copy link
Contributor

@ashgti would be cool if you could do that!

@ashgti
Copy link
Contributor Author

ashgti commented Jun 18, 2012

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.

@samueljohn
Copy link
Contributor

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

@samueljohn
Copy link
Contributor

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

@samueljohn
Copy link
Contributor

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}"
    end

@jacknagel
Copy link
Contributor

$ brew --env >/tmp/foo
$ source /tmp/foo

@samueljohn
Copy link
Contributor

Ok, thanks :-)

@ashgti
Copy link
Contributor Author

ashgti commented Jul 16, 2012

I updated it to append instead of override LDFLAGS and CPPFLAGS

@ashgti
Copy link
Contributor Author

ashgti commented Jul 16, 2012

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.

@samueljohn
Copy link
Contributor

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

@ashgti
Copy link
Contributor Author

ashgti commented Jul 16, 2012

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 MACOSX_DEPLOYMENT_TARGET="10.7"
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.

@samueljohn
Copy link
Contributor

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..

@adamv
Copy link
Contributor

adamv commented Jul 16, 2012

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

@ashgti
Copy link
Contributor Author

ashgti commented Jul 16, 2012

https://github.com/mxcl/homebrew/blob/master/Library/Homebrew/build.rb#L64 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.

@samueljohn
Copy link
Contributor

Then prepend is the right thing!

The other vars should be added too, I guess. And @adam is right,
eventually we should reuse code instead of trying to reproduce the
same setup twice. But that task is probably too difficult for this
pull request and I'd be happy with your solution right now. Could have
saved me some hours of debugging formulae for my xcode-only change.

Extending `brew --env` to include formula include paths so you can easily find keg only formula from outside of brew.
@samueljohn
Copy link
Contributor

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... :-)

@mxcl
Copy link
Contributor

mxcl commented Aug 31, 2012

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.

@adamv
Copy link
Contributor

adamv commented Nov 11, 2012

@mxcl - reject this?

@MikeMcQuaid
Copy link
Member

Rejecting as it's supported by brew sh.

@MikeMcQuaid MikeMcQuaid closed this Feb 1, 2013
@Homebrew Homebrew locked and limited conversation to collaborators Feb 16, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants