mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.54k stars 1.61k forks source link

Discussion: "Run configurations" for Meson #1314

Open doraskayo opened 7 years ago

doraskayo commented 7 years ago

As discussed in IRC, I'm opening this issue to follow the current implementation status and further discussion and design of proper "run configurations" for Meson executables.

We basically want to be able to support the functionality of the "run button" that most IDEs have, which is intended to launch an executable with a customized configuration. The configuration can include the ability to change environment variables before the executable runs, specify command-line arguments when it runs and change its working directory. This is only the most basic (and essential) set of features I can think of, so please mention anything else you have in mind.

This would allow us to setup an IDE project in a way that works "out of the box" for executables that expect (or support) those kinds of configurations. Here are a few use cases from the top of my head:

Most applications could be developed (or be used in development) far more easily in IDEs when using Meson than with any other cross-platform build system, if we had the ability configure each IDE to use the appropriate configurations when running executable targets. It's also important to note that this feature would also benefit command-line build environments (such as Ninja), because each "run configuration" would be a target that be can be executed individually with its own specified configuration.

In my opinion, the best approach to this to expand the current feature-set of run_target(). While providing a great start, it is currently lacking a few key features. At its current state, it can only be used to pass command-line arguments to executables. It would be a good idea to allow it set environment variables and working directory as well.

While this feature can certainly improve Meson's support of specific IDEs (Visual Studio included), without explicit support from IDEs, it would require Meson to add support for each IDE individually. Therefore, it's important to continue to encourage IDEs to use the JSON-formatted introspection data that Meson provides. Obviously, more flexible configurations is just as useful for the IDEs that already use the introspection data, but will require them to add explicit support for it.

For reference, when Visual Studio 2017 added explicit support for CMake, they had to come up with their own Visual Studio-only concept of "run configurations". This is an unfortunate situation for CMake, to say the least. Meson would rather not get there, and be better off providing its own universal solution before an impatient third party does.

Please share any ideas, use cases, notes, design suggestions and criticisms you have on the matter. Hopefully we can come up with a good plan for this feature.

TingPing commented 7 years ago

Just an FYI on how Gnome-Builder does this: Run simply always installs the application as it would be normally and then runs it as expected. The benefit to this is it exactly replicates real world usage and a normal environment (though this may be in jhbuild or flatpak).

With that said sometimes I do make a target to run locally for quick testing and for that I have been using scripts that set up the environment I need be it setting env vars, runtime properties, or even copying around files. This is a bit ugly but works out alright and is flexible. I agree simply adding environment variables to run_target() is 90% of a solution though for running things locally.

The idea of supporting multiple configurations with a config file is an interesting one though and unifying run behavior from the cli and an ide is a good goal.

doraskayo commented 7 years ago

@TingPing, I mostly agree, but I think the ability to set the working directory is very important. This part of run_target()'s documentation still bothers me:

"The script is run from an unspecified directory..."

I personally ran into situations in which I wanted to be able to execute a target and know for a fact that its working directory is exactly what I define. I ended up using pushd and popd or a wrapper script to do that, but I would much rather have native solution I can rely on. Specifically, the problem of wrapper scripts is that they aren't cross-platform and they make it almost impossible to debug an executable without a lot of headache.

Also, I think a sane default should assure that the target runs from the current working directory (i.e., the one from which the command to run target is made), and not from some "unspecified" somewhere.

jpakkane commented 7 years ago

We already do this for unit tests and in addition we export all this information as JSON via mesonintrospect. With this you can already do the use case of "run all unit tests, get a list of failing tests, click on one to start it in under a debugger inside the IDE". We could expand that to work with run targets as well.

The reason for unspecified is an implementation detail. Different backends have different layouts and launch processes in random directories.

nirbheek commented 7 years ago

I agree simply adding environment variables to run_target() is 90% of a solution though for running things locally.

run_target() can be used for creating targets that run things, but I don't think it fits conceptually into the idea of "run configurations" for the following reasons:

  1. On Windows, we want to set PATH to point to built libraries used by that executable. This is not appropriate for a run_target().
  2. When cross-compiling, we want to use the exe_wrapper to run the executable, just like tests, but for run_target() only executables with native : true are appropriate semantically.
  3. You want to be able to run with arbitrary arguments, and in arbitrary directories.
  4. You sometimes want to be able to run executables inside valgrind or gdb, etc.

Note that all these are the same requirements that test configurations have. We should definitely reuse that infrastructure somehow to implement this, and have something like mesonrun.py similar to mesontest.py to run configurations.

doraskayo commented 7 years ago

@nirbheek, does run_target() have a use case that a "run configuration" wouldn't be able to fulfill?

nirbheek commented 7 years ago

As I understand it, run_target does NOT mean "run this target".

custom_target means "a custom target" and build_target means "a built target". In the same vein run_target means "a runnable target". It creates a top-level target that runs either a natively-built executable or a command found in PATH.

"Run this built target" has a similar-looking but semantically completely different meaning and use-case that must be handled differently.