-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
dependency types #378
dependency types #378
Conversation
I'll just leave my two cents for the analysis part of this feature :
Then : should build dependencies be part of the computed hash? On the one hand I think we should permit to upgrade build tools seamlessly, i.e. without spack complaining that installed packages depends on the older version (and for that I would say 'no'). On the other hand it would be nice to keep track in a weaker way of the tools used in the build for the sake of reproducibility. Are there already some thoughts on how to handle this? |
The build dependencies should be logged in the installed package's |
Not necessarily. NumPy might be a runtime-used bit, but not needed to build and install.
Right. Package A needing Python to build does not mean that B (which depends on A) needs Python available as well.
This, I think, is tied to the SDK/platform question raised elsewhere. If those build dependencies can alter the ABI, yes, otherwise, no. The only situations I can think of where this would happen are contrived, so I'd lean towards "no" unless someone can come up with a use case where the ABI would be affected (other than toolchain builddeps). |
@mathstuf : hmm, I am not sure I got your point. Let's say I package extends(python)
depends_on(numpy) From my perspective |
Ah, true, it would need to be there for hash computation. I was thinking of ParaView which calls NumPy from C++ code and does not need it during the build, but it does need to advertize which NumPy is expected (though it only cares that it is compatible, not a specific version). |
@mathstuf: I'll add some notes to the spots you marked, but I wanted to get an answer out here before the conversation drops out of my inbox (sigh).
It's worth considering this from the perspective of what Spack would do differently for different dependency types. Spack could do these things for deps:
Currently Spack does all of those for all deps. As a first cut I might break that down like so:
We could debate whether you also want a "header-only" dependency for things like boost, that would only do 2, 3. I think it's not worth the extra complexity. We could also debate about hashing build and run deps -- I talk a bit more about that below.
I think we're on the same page here, and this is exactly why compilers are treated specially in Spack. They're build deps that directly affect the ABI. Spack doesn't (yet) do any ABI checking when it builds, but it does try to keep the compilers consistent by looking up in the DAG. We also allow different compilers for different packages in the same build and we've thought about better ABI checking. Build deps are similar in that they can be different on different nodes in the DAG. Some packages might need Python but only to run a build script (PETSc). Another package might link with PETSc, but it shouldn't have to use an entirely different version of Python just because PETSc ran its build system using another. This will have interesting ramifications for concretization. Currently when you load up a dependency spec from a So, my take is that the build deps for package A should be documented in I haven't fully thought through run dependencies, but an example would be that FWIW, Maven has a decent taxonomy of dependency types that is more extensive than the one above. It calls them dependency scope. Note that I don't advocate adopting Maven's XML syntax, but the model is decent and I like the term "scope" for this. Maven's That said, to make externals more usable, it would be nice to generalize detection of external build and run dependencies from the current way compilers are detected. #309 adds support for multiple compiler detection strategies -- perhaps we could add system package detection strategies in a similar way. Thoughts? |
On Wed, Jan 20, 2016 at 12:08:11 -0800, Todd Gamblin wrote:
I know that story :) .
Any reason for rpath and
It only does this for directories that exist right? For example, don't
Build deps should probably lose #5 (they'll pick up that step if they're
The only use case which differentiates link and run dependencies are
The only tools which I can think which do this:
Everything else is, if it's only a build dependency, irrelevant to the
Correct. My thought was to only look up runtime deps when generating the
The yaml file will have to specify the kind of dependency, so this is
I think we're on the same page here too: build-only deps are invisible
These tools tend to be "just have one available" rather than any kind of
Yeah, that sounds better.
+1
Packages could have methods which detect if a version of the package is |
Down to 9 test failures… |
Down to 8 errors now. It seems to be something about concretizing the specs where the concrete version of the spec is a duplicate dependency when added. I can't seem to find where in the diff something changed related to this; specs are copied where they used to be copied, deleted where they used to be deleted, and so on. Where else are such bits manipulated? |
Tests all pass locally. Any comments on implementation before I go back and edit commit messages? Any TODO items which can be removed? |
@mathstuf: I'm going to try to get around to reviewing this before the telcon tomorrow, but if I don't then I'll definitely get to it before Friday. |
Successfully built qhull after changing its dependency type to |
Updated with some bug fixes (now putting them into separate commits, but can squash them back if wanted). I've also gone through and update dependencies to be more accurate (Python module dependencies are build and run deps, but not install deps; autotools and cmake are build deps; Python modules from C++ programs are run deps (ParaView)). |
@tgamblin Ping? :) |
Reviewing it this afternoon! 😄 |
ok so by this afternoon I meant late tonight, but here goes. |
m.cmake = which("cmake") | ||
def _cmake(*args, **kwargs): | ||
which('cmake')(*args, **kwargs) | ||
m.cmake = _cmake |
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.
Could also just do m.cmake = Executable('cmake')
here.
@mathstuf: also I can make the change if you want. |
if deptypes is None: | ||
# The default deptype is build and link because the common case is to | ||
# build against a library which then turns into a runtime dependency | ||
# due to the linker. |
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.
looks like an outdated comment. From the description of run
and link
, i got an impression that run
is primarily for extensions of python and alike.
i suppose mpi
would be build
+link
+run
?
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.
Probably not, actually. The package itself does not call mpirun
at runtime. The user calls that before the app runs. So, MPI is just a build and link dependency of the application. A run dependency would be something like curl
for git
.
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.
curl
and git
are probably build
dependencies?
I think for distant observer like me it is not clear what run
dependencies are in the context of package manager like Spack? You don't normally use/run application using Spack? Maybe this could be clarified in the description of run
at the top.
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.
An easier way to think about this is whether, when A
-> B
, B
needs to be in the PATH
when you module load A
in order for A
to work.
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.
If I am not mistaken run
is thereby used exclusively in spack load
and should not affect environment of spack install
at all? I think example you mentioned will be helpful for package developers to understand the difference. So i would mention it in the description.
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.
Yep.
To understand this you have to distinguish runtime from build time. run
dependencies are for when a user runs the installed package. build
dependencies are for when spack builds the package. Those are two different environments. This is the same reason why things like Package.setup_environment()
distinguish between spack_env
and run_env
.
In that way you'll mask builtin |
Only within the In a package, |
When var/spack/stage is a symlink, the tests fail since realpath is used on the resulting path, but not the original path, so the string compare fails. Smarter path testing might be a better option.
deptypes: allow for different queries For things like Python modules, they are required for the build and runtime, but rather than adding a new parameter for what to query across the dependency DAG, just expose the recursive query parameter.
We want the run dependencies of all build and run dependencies of the current package.
Unsure about this, but this is probably true.
The sundials doesn't use CMake directly, but it is referenced in the patch step. I suspect it calls CMake somewhere else in its build system.
@tgamblin Last commit fixes the "Can only install concrete packages" error. |
(Still building Qt.) |
Qt built successfully. |
Version updates for spack-stack-1.6.0: [email protected], [email protected], [email protected], [email protected]
So here are my current notes for where things need to be changed to facilitate different types of dependencies. By no means exhaustive since this is a breadth-first search from
depends_on
to one or two levels for what needs modification/inspection. The API seems to make lines easy to draw (pkg.dependencies
will need to be a method, but there aren't too many uses of that).Looking through, it looks as though the best storage is
Dict[name, (spec, reason)]
rather thanDict[reason, Dict[name, spec]]
(as I started in the one commit when playing around with thedepends_on
code).Are there any other dep types that would matter other than build-time and run-time (run-time for a library being a dep from netcdf onto hdf5 due to a link dependency)? The only bits I saw were "we need it to build" and "we need it to use it" dependencies.
@tgamblin