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

make O=build out-of-tree #12463

Merged
merged 37 commits into from
Sep 14, 2015
Merged

make O=build out-of-tree #12463

merged 37 commits into from
Sep 14, 2015

Conversation

vtjnash
Copy link
Sponsor Member

@vtjnash vtjnash commented Aug 5, 2015

this implements out-of-tree builds (without requiring cmake 😄)

inspired by the linux kernel kbuild system, this uses make O= to setup a target directory. it then creates dummy makefiles in the out-of-tree build directories so that the user can more easily do incremental build work. the user can place independent Make.user files in each build tree to override the global Make.user file in the toplevel source directory.

additionally, it moves all source-file related content into deps/srccache for easier tracking (and build sharing).

@vtjnash vtjnash force-pushed the jn/makefile_o branch 5 times, most recently from 0e9f22d to e5f062f Compare August 5, 2015 04:54
@tkelman
Copy link
Contributor

tkelman commented Aug 5, 2015

-1, would rather get further on cmake which just does this for you. If this can be made to work without breaking the CI, then maybe, but right now it's adding even more complication to the makefiles and seems like a really strange thing to be working on right this second.

@tkelman tkelman added the domain:building Build system, or building Julia or its dependencies label Aug 5, 2015
@@ -47,7 +47,7 @@ export File,
import Base: uvtype, uvhandle, eventloop, fd, position, stat, close, write, read, read!, readbytes, isopen,
_sizeof_uv_fs, uv_error

include("file_constants.jl")
include(string(length(Core.ARGS)>=2?Core.ARGS[2]:"","file_constants.jl")) # include($BUILDROOT/base/file_constants.jl)
Copy link
Contributor

Choose a reason for hiding this comment

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

Well, this is a bit that is necessary in the cmake port for proper out-of-tree build as well. I'm currently adding this capability using a fallback path (which can be removed with stringreplace on the binary) in jl_load (the main advantage being not having to change anything in the julia code).

I'm at least interested in which way people prefer.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why not think about populating these lists of constants in some other way? There's some really godawfully messy perl going on in the makefiles right now to generate these, no one would miss those lines if they went away.

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

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

i would rather stick with the minimal change (this) in this PR, but can certainly entertain other ideas for implementation in a separate PR. the most logical change would probably to change this to a ccall to a method that has a big case statement to pick the right answer for the input string.

Copy link
Contributor

Choose a reason for hiding this comment

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

I still don't get what is going on here, or why some of these need vcat and .data. Let's not rush this with ugly confusing code.

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

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

some of these are early enough that strings are defined yet, so they need vcat and .data. it should be possible to make that more opaque in a future PR, but that would take a bit more restructuring and is unrelated to this PR. (this change, or something equivalent also needs to go in to make the cmake build work, so it isn't wasted work)

@vtjnash vtjnash force-pushed the jn/makefile_o branch 2 times, most recently from a4307bb to 2144ea6 Compare August 5, 2015 15:25
fenv_constants.jl: ../src/fenv_constants.h
@$(PRINT_PERL) $(CPP_STDOUT) -DJULIA -I../deps/openlibm/include ../src/fenv_constants.h | tail -n 8 | perl -ple 's/\sFE_UN\w+/ 0x10/g; s/\sFE_O\w+/ 0x08/g; s/\sFE_DI\w+/ 0x04/g; s/\sFE_INV\w+/ 0x01/g; s/\sFE_TON\w+/ 0x00/g; s/\sFE_UP\w+/ 0x800/g; s/\sFE_DO\w+/ 0x400/g; s/\sFE_TOW\w+/ 0xc00/g' > $@
$(BUILDDIR)/fenv_constants.jl: $(SRCDIR)/../src/fenv_constants.h
@$(PRINT_PERL) $(CPP_STDOUT) -DJULIA -I$(SRCDIR)/../deps/openlibm/include $< | tail -n 8 | perl -ple 's/\sFE_UN\w+/ 0x10/g; s/\sFE_O\w+/ 0x08/g; s/\sFE_DI\w+/ 0x04/g; s/\sFE_INV\w+/ 0x01/g; s/\sFE_TON\w+/ 0x00/g; s/\sFE_UP\w+/ 0x800/g; s/\sFE_DO\w+/ 0x400/g; s/\sFE_TOW\w+/ 0xc00/g' > $@
Copy link
Contributor

Choose a reason for hiding this comment

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

the openlibm path strikes me as though it would be broken in a NO_GIT build - do we need it?

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

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

only on windows, IIRC

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, whoops, I added that in #6230. So only with MSVC I think, which I believe is broken in a NO_GIT build. Possibly for reasons other than this too.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Aug 5, 2015

If this can be made to work without breaking the CI

Of course (also done now)

would rather get further on cmake which just does this for you

sure. the benefit in my mind here is that we can merge this now (since it doesn't change the build system much to add), and keep working on the cmake rewrite

@tkelman
Copy link
Contributor

tkelman commented Aug 5, 2015

Would rather wait until after branching release-0.4 to merge this. It should theoretically be non-disruptive, but some of these build configurations don't get tested very often.

@yuyichao
Copy link
Contributor

yuyichao commented Aug 5, 2015

FWIW, I do prefer merging the necessary bits for out-of-source build of sysimg first. It has been the part that introduce the most conflict...

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Aug 5, 2015

Would rather wait until after branching release-0.4 to merge this. It should theoretically be non-disruptive, but some of these build configurations don't get tested very often.

I'm actually thinking that if we can get this in before v0.4, it'll make it easier to keep a build tree around for v0.4, so that developers can test against many branches more easily.

aside from moving a lot of source files out of deps into deps/srccache, the way i implemented these build options, they are usually set to the empty string, so that this has very minimal impact on the in-tree build.

the src directories have supported this option for quite some time, this just finishes that work by extending support to deps, ui, base, etc.

@tkelman
Copy link
Contributor

tkelman commented Aug 5, 2015

The ARGS thing feels really hacky, and this breaks Cygwin cross-compile. This is supposed to be minimal impact, but it isn't as minimal as you think it is. It needs to be reviewed and tested, and we're trying to get master into an RC state. I don't think this is high enough priority to worry about right now.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Aug 5, 2015

The ARGS thing feels really hacky, and this breaks Cygwin cross-compile

thanks for point that out. i think i've fixed it (still waiting for my cross-compile build of llvm to finish): 4bba411#diff-b67911656ef5d18c4ae36cb6741b7965R193

@tkelman
Copy link
Contributor

tkelman commented Aug 5, 2015

Are you cross compiling from cygwin or linux? The line you pointed to isn't the issue, it's the failure to find the stdlibs. You're undoing part of #5965, the difference now is breaking the Cygwin cross-compile means no Windows binaries.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Aug 5, 2015

Are you cross compiling from cygwin or linux? The line you pointed to isn't the issue, it's the failure to find the stdlibs. You're undoing part of #5965, the difference now is breaking the Cygwin cross-compile means no Windows binaries.

my cygwin build is further behind. i didn't realize the mingw64-cygwin compiler was lying about it's paths, i've put that line back.

@tkelman
Copy link
Contributor

tkelman commented Aug 5, 2015

LLVM patches are still broken on cygwin here

/bin/sh: -c: line 0: syntax error near unexpected token `newline'
/bin/sh: -c: line 0: `cd /home/Tony/julia/deps/srccache/llvm-3.3 && patch -p1 < '
Makefile:669: recipe for target '/home/Tony/julia/deps/srccache/llvm-3.3/llvm-3.3.patch-applied' failed
make[1]: *** [/home/Tony/julia/deps/srccache/llvm-3.3/llvm-3.3.patch-applied] Error 1
Makefile:60: recipe for target 'julia-deps' failed

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Aug 5, 2015

ah, that didn't actually work anywhere.

@tkelman
Copy link
Contributor

tkelman commented Aug 6, 2015

still doesn't?

/bin/sh: line 0: cd: /home/Tony/julia/deps/srccache/llvm-3.3: No such file or directory
Makefile:669: recipe for target '/home/Tony/julia/deps/srccache/llvm-3.3/llvm-3.3.patch-applied' failed
make[1]: *** [/home/Tony/julia/deps/srccache/llvm-3.3/llvm-3.3.patch-applied] Error 1
Makefile:60: recipe for target 'julia-deps' failed
make: *** [julia-deps] Error 2

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Aug 6, 2015

oh, right. i guess it would also help if the patch files depended on the source actually existing too.
thanks for checking all of these.

@@ -77,9 +77,11 @@ When compiled the first time, it will automatically download and build its [exte
This takes a while, but only has to be done once. If the defaults in the build do not work for you, and you need to set specific make parameters, you can save them in `Make.user`. The build will automatically check for the existence of `Make.user` and use it if it exists.
Building Julia requires 1.5GiB of disk space and approximately 700MiB of virtual memory.

For release-0.4 and newer builds of Julia, you can create out-of-tree builds of Julia by specifying `make O=<build-directory> configure` on the command line. This will create a directory mirror, with all of the necessary Makefiles to build Julia, in the specified directory. These builds will share the source files in Julia and `deps/srccache`. Each out-of-tree build directory can have its own `Make.user` file to override the global `Make.user` file in the toplevel folder.
Copy link
Contributor

Choose a reason for hiding this comment

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

0.5. If we backport this it won't be for a month or so.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Sep 14, 2015

I'm waiting for CI on master to be green again before merging this. In the meantime, here's my email draft:

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Sep 14, 2015

I'm waiting for CI on master to be green again before merging this. In the meantime, here's my email draft:

I've recently merged #12463 which enables out-of-tree builds. What this means for you is:

  1. deps will rebuild. All external source files are now in deps/srccache, all external build files are now in deps/build.
  2. make O=output will start an out-of-tree build in the folder "output"
  3. dummy Makefiles are setup in the out-of-tree build folders for easier incremental building from any directory
  4. The new makefile target configure will create these dummy Makefiles
  5. by placing a Make.user file at output/Make.user, you can override the behavior of the global Make.user file for that directory, allowing testing for a wider range of systems (windows, 32-bit, llvm-versions, etc), all from the same source tree. Note that the global Make.user file is included in every build folder, but is run prior to the Make.user file to allow overrides.
  6. unlike most other out-of-tree build systems, this system does not care if you also have an in-tree build present

(this is all mentioned in https://github.com/JuliaLang/julia/blob/jn/makefile_o/README.md#source-download-and-compilation also)

@tkelman
Copy link
Contributor

tkelman commented Sep 14, 2015

Cool, there's a new conflict here but +1 from me on merging once that's resolved.

I'd add that if people plan on switching branches to release-0.4, it would be safer to leave existing build trees in place for release-0.4 (to avoid rebuilding) and doing new clones for master. Hopefully the previous issue with switching branches won't recur but it might.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Sep 14, 2015

as long as you rm -rf julia/usr between switching branches, you should be fine to stay in the same build tree

@vtjnash vtjnash merged commit bd22c1e into master Sep 14, 2015
@vtjnash vtjnash deleted the jn/makefile_o branch September 14, 2015 20:05
@tkelman
Copy link
Contributor

tkelman commented Sep 15, 2015

Good call. The issue that I hit earlier with switching between branches with vs without this change looks fixed now.

The buildbots are having some trouble though:

@Keno
Copy link
Member

Keno commented Sep 15, 2015

Something seems wrong. On a fresh checkout, I get:

make: *** No rule to make target 'jltypes.o', needed by '/Users/kfischer/Projects/julia-sa/usr/lib/libjulia.dylib'.  Stop.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Sep 15, 2015

that means it was missing one of the dependencies, so it couldn't figure out how to build it. i usually see that if libuv.a or llvm-config is missing

@Keno
Copy link
Member

Keno commented Sep 15, 2015

Could we get a better error message for that?

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Sep 15, 2015

was that the actual issue? i would have to hard-code a test for them, but it is possible.

@Keno
Copy link
Member

Keno commented Sep 15, 2015

It worked fine after rm -rfing usr. It doesn't have to be a very specific error message, just telling the user to delete usr is enough.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Sep 15, 2015

that should have been overkill. make at the toplevel should have invoked make -C deps, which should have targets to ensure all of the dependencies are installed before it invoked make -C src

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Sep 15, 2015

@tkelman: this seems suspicious to me:

make[3]: '/home/Administrator/buildbot/slave/package_win6_2-x64/build/usr/lib/julia/inference.ji' is up to date.

why would that file be up-to-date without having built it? is it possible there is old build state stuck around in the form of a file called usr/.examples that is inhibiting updating of usr/share/docs/julia?

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Sep 15, 2015

(there's also an empty cygpath -w in there causing warnings, RELBUILDROOT should maybe be . instead of empty?)

the warning only affects cygwin, and is non-fatal, so i don't care

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Sep 15, 2015

Good call. The issue that I hit earlier with switching between branches with vs without this change looks fixed now.

you definitely would still need to rm -rf usr to switch very reliably, but the whole point of moving the build to deps/build was that it makes that transition cleaner and simpler

@tkelman
Copy link
Contributor

tkelman commented Sep 15, 2015

why would that file be up-to-date without having built it? is it possible there is old build state stuck around in the form of a file called usr/.examples that is inhibiting updating of usr/share/docs/julia?

Potentially. The buildbots generally do incremental builds unless we manually clear them out. I just did so, but it'll be more time-consuming if every time we go back and forth between building release-0.4 and master we need to completely clean them out. Can probably switch them to doing rm -rf usr instead of the make cleanall that they're doing now.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Sep 15, 2015

maybe not a bad idea to do rm -rf usr anyways, but i see the make clean rule that got lost in the rebase attempts.

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Sep 15, 2015

fixed in 5b40f2b

(backport tag)

tkelman added a commit that referenced this pull request Sep 15, 2015
fixes a cygwin warning from #12463 due to `cygpath -w `
tkelman added a commit that referenced this pull request Sep 15, 2015
fixes a cygwin warning from #12463 due to `cygpath -w `
@mbauman
Copy link
Sponsor Member

mbauman commented Sep 23, 2015

Did this change the location of JULIA_HOME for local (non-installed) source builds? I keep editing files in ./usr/share/julia/base instead of ./base. It's not a big deal, but surely others have run into this, too. Any workarounds?

@vtjnash
Copy link
Sponsor Member Author

vtjnash commented Sep 23, 2015

usr/share/julia/base is a symlink to base, so the exact path shouldn't matter. the former is a more stable location, however, for working with out-of-tree builds.

@mbauman
Copy link
Sponsor Member

mbauman commented Sep 23, 2015

Should have looked a little closer. That's great. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:building Build system, or building Julia or its dependencies
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants