craftr-build / craftr-build-4.x

Frontend for the Craftr build framework.
https://craftr-build.github.io/craftr/
Other
60 stars 14 forks source link

setdefault() should accepted dotted names, introduce setoption() function #13

Closed NiklasRosenstein closed 9 years ago

NiklasRosenstein commented 9 years ago

The setdefault() function would be more useful if it would also accept dotted names and resolve it in the modules global variables. Also, a setoption() function that would basically do the same but always set the value instead of only if it is not already present. This would make it easier to set options before a module is loaded. Compare:

some = get_namespace('some_fancy_module')
some.debug = True
load_module(some)
setoption('some_fancy_module.debug', True)
some = load_module('some_fancy_module')
winksaville commented 9 years ago

Which is more Pythoinc? How do people discover the options?

What about: some = load_module('some_fancy_module', debug = true)

On Sun, Sep 6, 2015, 7:16 PM Niklas Rosenstein notifications@github.com wrote:

The setdefault() function would be more useful if it would also accept dotted names and resolve it in the modules global variables. Also, a setoption() function that would basically do the same but always set the value instead of only if it is not already present. This would make it easier to set options before a module is loaded. Compare:

some = get_namespace('some_fancy_module') some.debug = True load_module(some)

setoption('some_fancy_module.debug', True) some = load_module('some_fancy_module')

— Reply to this email directly or view it on GitHub https://github.com/craftr-build/craftr/issues/13.

NiklasRosenstein commented 9 years ago

That ain't bad, Wink! Nice idea. I'm still thinking about what would happen if you load a module and want to pre-define some parameters but the module was already loaded elsewhere. Should it error? Should it be silent? Should it re-load the module into a different object?

About discovering, do you mean how people would know about which options they can specify?

winksaville commented 9 years ago

Regarding: Should it error? Should it be silent? Should it re-load the module into a different object?

My answer is that it should "re-load the module into a different object", which is related to my question in (https://github.com/craftr-build/craftr/commit/e4947f8c9fe4668df98ef9a85e49a7a7a5d93592).

Regarding: About discovering, do you mean how people would know about which options they can specify?

My answer: "Yes"

NiklasRosenstein commented 9 years ago

Hey Wink! If it would be reloaded into a different module, it would also declare the targets again. If the options that are different have no influence on the filenames that are being generated, you will end up with multiple (maybe different) build rules for building the same file.

Module-level options should really only be used for majorly important settings, eg. whether the module should export a debug build rather than a release build (as you will usually use a different output directory for a debug build than for a release [remember that Craftr is different in that the output build directory is defined in the Scripts, not from the current working directory as with CMake or Meson]).

The best example I can think of is related to the Cinema 4D API that I use with Craftr to compile Cinema 4D C++ plugins. There's a "Legacy API" mode which will enable the old naming scheme from a few releases ago. While I have to globally specify that I want to build a debug version, I only want to enable the Legacy API locally for my plugin.

c4d = load_module('maxon.c4d', debug=True)
# ...
c4d.cxx_objects('Objects',
  sources = glob(join(project_dir, 'src/**/*.cpp')),
  legacy_api = True,
)
c4d.cxx_plugin('Plugin',
  inputs = [Objects],
)

In general, I'd say that global module settings should only be used where they are have global effects and can't be changed locally for a single target (I can't link some objects with the debug version of the API and others with the release version). So in the same project, there must be no conflict in the global module configurations, that's why it raises an error. What do you think?

By the way, I'm working on implementing rule-functions as you can see above also for the built-in compiler modules.

About discovering options: The options available should be documented somewhere of course (eg. in the Craftfile header or a README or whatever). The options for a build rule can be documented in the docstrings of the Python function (see for example https://github.com/craftr-build/craftr-c4d/blob/574ac73fe5a3d4b6d15a427bb36c9477bca92a82/maxon.c4d.craftr#L322-L334)

winksaville commented 9 years ago

OK, lets see how it goes.

On Sat, Oct 10, 2015, 5:54 AM Niklas Rosenstein notifications@github.com wrote:

Hey Wink! If it would be reloaded into a different module, it would also declare the targets again. If the options that are different have no influence on the filenames that are being generated, you will end up with multiple (maybe different) build rules for building the same file.

Module-level options should really only be used for majorly important settings, eg. whether the module should export a debug build rather than a release build (as you will usually use a different output directory for a debug build than for a release [remember that Craftr is different in that the output build directory is defined in the Scripts, not from the current working directory as with CMake or Meson]).

The best example I can think of is related to the Cinema 4D API that I use with Craftr to compile Cinema 4D C++ plugins. There's a "Legacy API" mode which will enable the old naming scheme from a few releases ago. While I have to globally specify that I want to build a debug version, I only want to enable the Legacy API locally for my plugin.

c4d = load_module('maxon.c4d', debug=True)# ... c4d.cxx_objects('Objects', sources = glob(join(projectdir, 'src/*/_.cpp')), legacy_api = True, )

In general, I'd say that global module settings should only be used where they are have global effects and can't be changed locally for a single target (I can't link some objects with the debug version of the API and others with the release version). So in the same project, there must be no conflict in the global module configurations, that's why it raises an error. What do you think?

By the way, I'm working on implementing rule-functions as you can see above also for the built-in compiler modules.

About discovering options: The options available should be documented somewhere of course (eg. in the Craftfile header or a README or whatever). The options for a build rule can be documented in the docstrings of the Python function (see for example https://github.com/craftr-build/craftr-c4d/blob/574ac73fe5a3d4b6d15a427bb36c9477bca92a82/maxon.c4d.craftr#L322-L334 )

— Reply to this email directly or view it on GitHub https://github.com/craftr-build/craftr/issues/13#issuecomment-147087251.