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

Add plugins support #1854

Merged
merged 1 commit into from Feb 13, 2018
Merged

Add plugins support #1854

merged 1 commit into from Feb 13, 2018

Conversation

shlevy
Copy link
Member

@shlevy shlevy commented Feb 8, 2018

Alternative solution to #1841 / #1844.

@shlevy shlevy requested a review from edolstra February 8, 2018 16:40
@@ -64,6 +65,8 @@ int main (int argc, char * * argv)

settings.maxBuildJobs.set("1"); // hack to make tests with local?root= work

initPlugins();
Copy link
Member

Choose a reason for hiding this comment

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

Why are all these initPlugins() calls necessary? Can't that be done in initNix() or some other common location?

Copy link
Member Author

@shlevy shlevy Feb 8, 2018

Choose a reason for hiding this comment

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

It needs to be called after --option flags are parsed, which is done in a bunch of different ways by different programs.

state.addPrimOp("fetchMercurial", 1, prim_fetchMercurial);
}

static RegisterPlugin r(Plugin(PluginTag<PluginType::EvalPlugin>(), reg));
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand why these changes are necessary. Doesn't the RegisterPrimOp constructor run automatically when the plugin is loaded? Why the need for a RegisterPlugin with a lot of template crap?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's not necessary, this is all contained in the second commit that I explicitly said could be dropped ;) This was just to drop duplicate capabilities.

Also, a single template is hardly "a lot of template crap".

Copy link
Member Author

Choose a reason for hiding this comment

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

... Though I just realized an easy way to avoid the template altogether, patch incoming.

Copy link
Member

Choose a reason for hiding this comment

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

Well, I don't understand the need for all this over-engineering (e.g. Plugin(PluginTag<PluginType::EvalPlugin>()), plus all that complexity in plugins.hh, which for some reason has a forward-decl to EvalState...

Copy link
Member Author

Choose a reason for hiding this comment

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

I removed the tag stuff, was a holdover from an earlier approach. plugins.hh needs to reference EvalState & to definte the EvalPlugin type, but #including eval.hh this low in the header chain could easily lead to accidental references to libnixexpr in libnixstore, if it even worked otherwise.

@shlevy
Copy link
Member Author

shlevy commented Feb 8, 2018

@edolstra Template crap deleted, second commit simplified (though still not needed)

@@ -238,6 +237,11 @@ static void prim_fetchGit(EvalState & state, const Pos & pos, Value * * args, Va
state.allowedPaths->insert(gitInfo.storePath);
}

static RegisterPrimOp r("fetchGit", 1, prim_fetchGit);
static void reg(EvalState & state)
Copy link
Member Author

Choose a reason for hiding this comment

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

This could be inlined with a lambda if desired.

@shlevy
Copy link
Member Author

shlevy commented Feb 8, 2018

@edolstra Continuing out of the source comments: plugins.hh is ready to support multiple plugin types for two reasons: 1) You mentioned wanting to move s3binarycachestore to plugins and 2) it's very cheap forward compatibility.

@edolstra
Copy link
Member

edolstra commented Feb 8, 2018

Well, I still don't understand why RegisterPlugin is needed at all (and why plugin.cc needs to know about EvalState). The only thing that should be needed for plugin support is to do dlopen on the .so files, the RegisterPrimOp and RegisterStoreImplementation constructors should take care of the registration.

@shlevy
Copy link
Member Author

shlevy commented Feb 8, 2018

OK, I'll switch tothat approach.

@@ -135,6 +136,7 @@ int main(int argc, char ** argv)
{
return handleExceptions(argv[0], [&]() {
initNix();
initPlugins();
Copy link
Member

Choose a reason for hiding this comment

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

buildenv should not need plugins.

@@ -158,6 +158,7 @@ int main(int argc, char ** argv)
{
return handleExceptions(argv[0], [&]() {
initNix();
initPlugins();
Copy link
Member

Choose a reason for hiding this comment

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

This command probably does not need plugins.

All plugins in plugin-files will be dlopened, allowing them to
statically construct instances of the various Register* types Nix
supports.
@shlevy
Copy link
Member Author

shlevy commented Feb 8, 2018

@edolstra updated

@edolstra edolstra merged commit 88cd2d4 into NixOS:master Feb 13, 2018
@edolstra
Copy link
Member

Merged, thanks!

Feature request: it would be useful to support loading all .so's in a directory, e.g.

plugin-files = ${config.system.path}/lib/nix/plugins

to load all plugins provided by installed packages.

@shlevy
Copy link
Member Author

shlevy commented Feb 13, 2018

@edolstra OK, will do! Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants