conan-io / conan

Conan - The open-source C and C++ package manager
https://conan.io
MIT License
8.15k stars 972 forks source link

Prepend a custom command before cmake #10426

Closed harsszegi closed 2 years ago

harsszegi commented 2 years ago

Hi,

we'd like to use Incredibuild with Conan. Incredibuild is practically a bootstrap before cmake, meaning it executes cmake ('s build step only) on its own, like 'buildconsole /command="cmake --build xxxx -j yyy"'

as I check tools/cmake/cmake.py, it is not quite possible to do that (e.g. wrap the generated 'command' in '_build' into something).

Any thoughts on how to overcome the problem? Obviously I could use "should_build=False", but I have absolutely zero idea how I could regenerate exactly the same build invocation (e.g. how to use _cmake_cmd_line_args externally), Thanks,

memsharded commented 2 years ago

Hi @harsszegi

You can try the CONAN_CMAKE_PROGRAM to define that command you like, but that will apply to all invocations of cmake, both cmake.configure() and cmake.build().

What happens if the command is also added to the cmake configure step?

We might have a better chance to improve this with the new CMake integration (in from conan.tools.cmake import CMake) and using [conf] items, but we should learn better what is necessary.

earonesty commented 2 years ago

yes, CONAN_CMAKE_PROGRAM is the only way you can run a program, especially if you have no control over the source package (like if it's from conancenter, for example, and you want to maintain a patch, not a fork)

if that package doesn't use CMAKE, i don't think there's any way to insert a hook that happens before the build process, especially since you can't call conan source on the package to preload the sources, before applying a patch or something to modify the build

the only solution i've found is to call conan build. wait for it to fail, then patch

harsszegi commented 2 years ago

Thanks guys, I don’t think CONAN_CMAKE_PROGRAM is sufficient sadly as you could see from the example, technically speaking cmake is not actually prepended with another comand, but something like this instead:

custom_cmd_prefix=‘buildconsole /command=“‘ custom_cmd_postfix=‘“‘ final_cmake_cmd=custom_cmd_prefix+original_cmake_cmd+custom_cmd_postfix

memsharded commented 2 years ago

We are going to consider a wider solution:

harsszegi commented 2 years ago

We are going to consider a wider solution:

  • An interceptor extension in .py, that will get a command and will be able to return a new command to be executed. This way it can be used for other build systems too, not only cmake

Awesome, thank you very much guys!

memsharded commented 2 years ago

Having a look at this. I am checking what Conan is doing inside self.run(cmd), and it is doing a lot of things. An actual command might look something like:

cd <some dir> && conanbuild.bat && cmake ....

with the bat or shell script managing to activate the necessary environment (for example calling vcvars to activate the right VS environment).

With that in mind, how would the solution look like? Wrapping just the original cmd? Wrapping everything? Will users like and process the bare cmd or the full one?

harsszegi commented 2 years ago

I think it is just perfect, if there would be an injeciton point prior calling the actual build / configure stage and still would be executed in the same shell environment where the build / configure command is executed, it is just fine afaik

memsharded commented 2 years ago

So that means, an injection point around the "user" cmd?, so the final executed thing would be like:

cd <some dir> && conanbuild.bat && <user-inject-pre> cmake .... <user-inject-post>
harsszegi commented 2 years ago

I think that is just perfect.

memsharded commented 2 years ago

https://github.com/conan-io/conan/pull/10867 implemented a plugin approach for this, to be released in next 2.0-alpha.6 soon