Opened 5 years ago

Last modified 5 years ago

#50246 new enhancement

CMake PortGroup : generate a file in ${workpath} containing the complete cmake invocation

Reported by: RJVB (René Bertin) Owned by: macports-tickets@…
Priority: Normal Milestone:
Component: ports Version:
Keywords: Cc: michaelld (Michael Dickens), mkae (Marko Käning), mojca (Mojca Miklavec)
Port:

Description

Michael, would you consider adding a small post-configure block to the CMake PortGroup which stores the complete cmake command that was just executed in a file in the work directory?

This would come in very handy during port development, for configuring certain IDEs to use the work/build (Qt Creator needs to know how to call cmake, and KDevelop5 also). It's feasible to set up the IDE's environment so that it corresponds to the one "base" sets up, but reconstructing the cmake command is tedious (and logfiles tend to have been overwritten just when you want to extract this information from them).

Attachments (1)

cmake-1.0.diff (4.6 KB) - added by RJVB (René Bertin) 5 years ago.

Download all attachments as: .zip

Change History (13)

comment:1 Changed 5 years ago by mf2k (Frank Schima)

Port: cmake removed
Type: requestenhancement
Version: 2.3.4

Note that a "request" ticket type is only for requesting a new port.

comment:2 Changed 5 years ago by michaelld (Michael Dickens)

That's a good idea, René. I don't know when I'll have time to do it. Do you have a patch that will do the trick? That would be easiest. Might be able to create a cmake script file that is automatically executed within the configure command that does this; not sure.

comment:3 Changed 5 years ago by RJVB (René Bertin)

I don't know about doing this in cmake, but I ought to be able to design a patch one of these days.

Do you think the environment should be dumped to that file too?

comment:4 Changed 5 years ago by ryandesign (Ryan Schmidt)

Why is it more important to know what cmake command was used to configure than it is to know what command was used to configure any other port not using the cmake portgroup? In other words: If this enhancement is to be implemented, wouldn't it make more sense to do it in MacPorts base for all ports, not in the cmake portgroup only for ports that use cmake?

The next question would be: why is it more important to know what configure command was used than it is to know what build or destroot command was used? Should this be done for all phases, not just the configure phase?

You can of course get this information from the main.log file already, but I imagine you're requesting this because you often retry port builds without cleaning first, which overwrites the original log.

comment:5 Changed 5 years ago by RJVB (René Bertin)

Among the ports that I update frequently there are only few which I update in the regular, one-shot fashion. Logfiles don't only get lost after an update, but by each consecutive step if you split the process, and there are valid reasons for doing so even if you're not developing a port.

When I say "developing a port", I mean not just the portfile, but also the software it bundles. That's what I'm also doing with my Qt and KF5 ports, so yes, I do lots of incremental builds. MacPorts' de/activate feature comes in very handy in that context. I'm pretty sure I'm not the only one doing this, and it's why I wrote those utilities I submitted here a while back (port-redo-install-phase, port-edit-statefile, ...)

To answer your question: yes, it would make sense to implement this in "base". I've suggested the idea several months ago already, but it wasn't picked up. I've also coined the idea upstream, to store the full command in the CMakeCache header, but I guess they feel that's not necessary. The reason I now requested it for cmake is twofold: 1- cmake commands tend to get much more complicated once you do need arguments; certainly much less readable 2- I've never seen an IDE that needs to know the cmake command because it'll call cmake as part of its project-parsing step.

Storing the command for the build step is probably not of much use (tends to be really simple), for the destroot probably a bit more. I've already looked how to reconstruct it in order to do a partial destroot manually, of a very big port on a slow host. In fact, the destroot of Qt5 must take somewhere between 2 and 5 minutes on my MBP, so yeah, anything that makes it easier doing partials would be appreciated - but that's another topic altogether.

comment:6 Changed 5 years ago by michaelld (Michael Dickens)

I'd love to see this feature in base, somehow: a single command including environment variables for how to do the configure stage. Given the ever growing number of projects using cmake, I think doing it with just cmake would be fine as a test to see about the usefulness of storing this info.

Storing the configure phase environment and command are generally more useful that those for build or destroot since the latter 2 are generally just "make" and "make install". Not always, of course. So, if we're talking about storing 1 phase's info then I'd say to just store all phase's info if it's that simple.

cmake does actually store it's original command line internal to the build (somewhere; I don't remember) such that if one of the cmake build files is updated (even just touched) then cmake will try to re-run itself (sort of a re-configure). But, it doesn't store the shell environment so the results from re-configuration might vary from the original configuration stage.

comment:7 Changed 5 years ago by RJVB (René Bertin)

I'd love to see this feature in base, somehow: a single command including environment variables for how to do the configure stage.

Do you mean a way to call port configure repeatedly, ignoring when saved state says configure has already been done?

cmake does actually store it's original command line internal to the build (somewhere; I don't remember)

Part of the info is stored in the "preamble" (commented out lines) of CMakeCache.txt, the rest is based on what is stored in CMakeCache.txt. Presumably, that file is loaded to pre-initialise variables that could also be specified on the command line, meaning you don't need to do that in a repeat invocation. Of course that doesn't fly during the 1st invocation, and also presumes that repeat invocations (as could be done by an IDE) do not set arguments of their own. And what Michael said about the environment.

comment:8 in reply to:  7 Changed 5 years ago by michaelld (Michael Dickens)

Replying to rjvbertin@…:

Do you mean a way to call port configure repeatedly, ignoring when saved state says configure has already been done?

Yes. What I currently do is edit the macports state file & delete the 'configure' line. "rm -rf *" in the build directory then redo port configure. Very tedious. It would nice to have a simple port command to call to do all of this, like "port reconfigure" or something like that. With cmake it is important clear out the cmake files before re-configuring, otherwise cruft is likely to happen. "rm -rf *" is overkill, but it does the trick & is a pain really just on big builds when I'm testing out some cmake feature way late in the build.

comment:9 Changed 5 years ago by RJVB (René Bertin)

Sounds like the sort of thing I do all the time too. Do a search for port-redo-install-phase here on trac, it should lead you to the current version in my repo. It handles removing specific entries from the state file, but also updates its checksum so you stand less risk of losing the entire build dir. It is rarely required to remove the entire build.dir in my experience. Most of the time a cmake rerun will suffice; sometimes you'd better remove CMakeCache.txt first. The port-redo-install-phase -configure vs. -configure-all options implement those 2 approaches.

There's also port-active-variants which helps not having to re-determine the current variants every time ;)

Port-redo* also has -patch vs. -patch-all; the former applies only new patches, the latter reapplies all and must be used with -extract or a separate git reset --hard in worksrcpath. But those assume you have another patch of mine for "base" which stores applied patchfiles in the state file. It's on trac somewhere too, not sure if it's been incorporated yet.

> port-redo-install-phase -configure|-configure-all [-build] [-destroot] foo
> port -nvok {configure,build,destroot} `port-active-variants -echo foo` configure.optflags="..."

-n : don't touch anything else; -o : reduncant after port-redo* but let's take no risks; -k : idem, don't risk forgetting this one when editing the last command to do an install / upgrade --force ;)

And sometimes I do a port-edit-state foo if I want to add or remove a variant.

The only thing that still surprises me in all that is how long it took before I went ahead and wrote those utilities...

Last edited 5 years ago by RJVB (René Bertin) (previous) (diff)

comment:10 Changed 5 years ago by RJVB (René Bertin)

Here's what I came up with, a small post-configure block to be copied immediately after the 1st pre-configure block in cmake-1.0.tcl:

post-configure {
    if {![catch {set fd [open "${workpath}/.macports.${subport}.configure.cmd" "w"]} err]} {
        foreach var [array names ::env] {
            puts ${fd} "${var}=$::env(${var})"
        }
        puts ${fd} "[join [lrange [split ${configure.env} " "] 0 end] "\n"]\n"
        puts ${fd} "cd ${worksrcpath}"
        puts ${fd} "${configure.cmd} ${configure.pre_args} ${configure.args} ${configure.post_args}"
        close ${fd}
        unset fd
    }
}

I'll attach a diff of my vs. the current upstream cmake-1.0.tcl (or maybe I should do that in the ticket about adding a "MacPorts" CMAKE_BUILD_TYPE ...)

Changed 5 years ago by RJVB (René Bertin)

Attachment: cmake-1.0.diff added

comment:11 Changed 5 years ago by mkae (Marko Käning)

Cc: mk@… added

Cc Me!

comment:12 Changed 5 years ago by mojca (Mojca Miklavec)

Cc: mojca@… added

Cc Me!

Note: See TracTickets for help on using tickets.