Showing posts with label Tools. Show all posts
Showing posts with label Tools. Show all posts

2025-08-27

The problem with the solution

Out-of-source build are a solution to a number of problems. Most pressing in my day to day work they make it efficient to maintain separate builds and jump back and forth between them; they reduce the frequency of committing things to the repository that have no business being there; and they make it possible to play nice with IT (source is backed up, build is not). As such, they are widely recommended by respected professionals (and I see few serious attempts to defined in-source builds), but they are not without their own problems.

The particular problem that I want to talk about today is build metadata. My work projects use CMake,1 which has two implications:

  1. Once configured the build system stores all the metadata in ${BUILD_DIR}/CMakeChache
  2. But you occasionally (::cough:: pretty regularly) have to blow the cache away and start over

Worse, for design reasons driven by a core dependency, the build of my main project needs a pretty complicated set of environment variables to configure.

No problem, though, the IDE will store that stuff for you, right?

Yes. Yes, it will. In a tool-specific file. In the source directory.

And yeah, you can .gitignore the IDE files so they don't get committed, but because each IDE has it's own name, that's a little catalog of names to maintain. Similarly, you can't reuse information cached by one tool in another. It's be nice to have a unified standard for common things (build locations, environment variables, etc) with some provisions for tool-specific extras.


1 I know, I know. Don't get me started.

2025-02-28

Header-implementation duality?

While, in principle,1 C++20 marks the beginning of the end of our long, collective, inclusion nightmare the painful truth is that many C++ developers are going to be dealing with header files for years to come. And I've heard of no plans to bring a modules system to plain C at all.

But at least we have decades of experience from which to derive best practices and better tools to automate or enforce those practices. Right?

Some of the best practices:

  1. Every header should have include guards.2
  2. Don't #include files unless you need declarations or definitions found therein. Where possible prefer forward declarations or forward declaring headers (like iosfwd).
  3. Explicitly include headers to cover everything you need. Do not rely on transitive includes.

None of this is particularly controversial (leaving out the holy war over how to protect files from multiple inclusion), but I find that I have a minor interpretational difference with include-what-you-use (AKA IWYU: one of the leading tools for automating these rules). You see IWYU asks me to include in my implementation file things I already included in my the associated header file. Now, that is a strict interpretation of rule (3), so why does it bother me? Apparently I think of the header and implementation as two parts of a single logical unit rather than two independent things. I mean, those things should be maintained together so the danger of relying on the transitive inclusion is mitigated.

Of course, if I was implementing the tool I'd at the very least start with the current behavior. Simply because it's going to be very hard for the tool to know that this header really and truly does go with that implementation. I mean usual if they have the same stem that's a good clue, and in project where headers and implementations can sit in the same directories that is also helpful. But some layouts separate the interface files, so then what?


1 By now a non-trivial fraction of C++ coders are able to use the 2020 standard, but that doesn't mean that they are able to use modules. Support has been pretty slow even in compilers and build tools maintainers are stuggling with some real problems inherent in the pure flexibility of the module standard in C++.

2 Yes, I know, in the Windows world many people strongly advocate for #pragma once instead, and avoiding the possibility of name collisions is a big advantage in my book. But it remains non-standard which is why some major style guides and the core guideline still insist on classic approach.

2024-04-04

Yeah, well, you know, that’s just, like, your workflow, man.

I caught some flack at work this week: I circulated an early draft of a document that I was struggling with in plain text1 and my boss was very clear that he wanted me to use Word in the future so there would be change tracking and out-of-band comments. On the plus side those remarks came packaged up with some useful suggestions for the piece.

Once I tamped down my reflexive defensiveness and the basic anxiety that comes with screwing up at work, I pulled up my big kid underwear and moved on. Then, having decided to be an adult about this, I ran smack dab into a counter example for $BOSS's point. I received a second set of highly useful changes in the same document. Conflicting changes. I'm not aware of any good tooling to handle conflicting changes in Word, but it was no problem for me to handle the conflicts in my text document: I just opened the files in my favorite visual merge tool.2 and got on with it.

Caveat time. To take the "plain text means we can use good tools" thing seriously we'd want to put all our draft work in VC repositories, and when that occurred to me my first reaction was "Who'd want to do that?" I mean, yeah that makes sense for major pieces of writing, but it's not obvious that you want to maintain a full history on every minor document you bang out day in and day out.

But then I had another thought...

Caveat on the caveat. Which was "Hey, how do people who are really committed to Word deal with the possibility of conflicting changes, anyway?" A little poking around the web suggest that my employer's answer is completely mainstream. At the management tier we put everything in SharePoint and let it enforce serialized editing, so they're already putting all their work in a repository. Maybe the whole idea isn't so silly after all.


1 Now, I would never send plain text to the clients, but I often do my initial composition in text because the sense of informality helps me feel safe trying out different formulations in search of a natural arc through complex subjects.

2 Meld as it happens. But not because I've tried all the options: it was just the first one I spent any time with and it's been consistently available.

2023-09-14

Really, Qt?

Qt Creator is poluting my nice clear build results window with a complaint that my build directory is not on the same level of the filesystem as my source directory. It's a new complaint even though I've been using Qt Creator for ages, because I recently had to re-oganize my work a little. I have, for a long time, used a layout where by source, build, and distribution directories for each project are sub-directories of $HOME/source, $HOME/build, and $HOME/dist which actually meets Qt's strange requirement.1 Alas IT issued a new edict concerning the centalized backup system and on windows I've been forced to move my source hierarchy to $HOME/Documents/source on that platform. Which broke QT's little brain.

The policy is, presumably, intended to enfore a prefernce for out-of-source build, which is a good idea (every build should be out of source). But it is also way, way too restrictive a way to enforece that behavior.


1 This lets be share the source directory across the Windows host, several WSL linux installations, and the few VMs I still run while each platform maintains it's own build and distribution locations.

2023-06-21

IDE feature sweetner

My most common IDE knows how to extract selected block of text as a function or method.1 Which is great even when it misses a couple of parameters and almost magic when it works exactly as intended. But I've enountered a problem in the current bit of legacy code in front of me: I need to extract a loop body that is more than six hundred lines long. Selecting the thing is enough of a pain as to present a barrier to getting anything done.

I could really use a feature to "select current loop body" or a extract variant like "extract loop body".

Ah! Ha! Found it!

In Qt creator go to move the index inside the block, then use menu item "Edit:Advanced:Select block down".


1 Well, usually. For some reason Qt creator occassionally just doesn't offer that option in the re-factor sub-menu. No idea what controls the availability.

2023-03-22

Don't save!

I do a lot of programming at work in Qt Creator which is a perfectly acceptable IDE,1 and up until recently we used qmake to manage the build for basically the same reason we use Qt Creator: because these are Qt projects and the native tools understand them.

But several things have happened recently2 that collectively have made us move to cmake for most projects. And that means we've bumped into a quirk of the IDE: there is a big time-cost to changing the CMakeLists.txt files. Not I hasten to add because its any slower than anything else in running cmake. It does that just fine. But after it re-configures the build, it re-scans the project to locate files that should be listed in the project tree-view. For more than thirty second in the case of my main project. And for some reason it does this as a synchronous operation: preventing you from taking any other action in the IDE.

Now, most of the time this is a non-issue: I'm working on the code not the build, so it rarely comes up and is a minor annoyance.

But if you are working on the build (as I was this afternoon), it is critical to overrule that "hit the save key-combo everytime you pause to think" reflex that makes so much sense at other times.


1 I mean, it can't refactor template code very well, but you can at least learn how it fails and know how to fix up the results.

2 Qt has deprecated qmake with Qt6, we've started using some of our code (including a underlying library) with third party projects that use cmake, and we have found that cmake is slightly better at parallelizing bigish builds resulting in slighlty but noticiably faster edit-compiler-test cycles.

2022-11-01

Merge tool supporting on-the-fly revision history?

There is this internal library where we've been working on four branches. Call them devel, feature-a, feature-b, and feature-c. All three feature branches are significant and long running, but they have at least had the incremental improvements and bug fixes from devel regularly merged back in.

Recently feature-a and feature-b were merged to devel (by someone else, yeah!). Which means that devel now has large changes relative feature-c. Now, I'm one of the folks working on feature-c and I spent a little while today trying a "what-if" merge of devel into that branch. It wasn't as bad as I feared (because much of this branch is working on different parts of the code than the others), but it was bad.

While I was staring at the merge tool showing another set of conflicting changes without (a) recognising either change as one I had done or (b) understanding the intent behind either occured to me that it would be really nice to be able to ...

Frob1 a highlighted (i.e. changed) section of text to obtain a quick peak at the relevant change logs.

In the simplest form you would see the change summaries from the current commit back to the common anscenstor for each branch; better would be filtering only those commits that touched the current file, and best would be filtering those that involve the lines in question. Being able to drill down on interesting summaries is a bonus feature.

At that point—assuming your team writes reasonable commit messages—you have a fighting chance of sussing out the intent of the changes and thereby a better chance of choosing the right merge action. Of course, I can (and do) check those logs in a couple of terminals kept handy, but UI sugar can improve the experience.

This seemed like something someone might already have implemented, but my Google-fu wasn't up to finding it (or reliably eleminating the possibility). Anyone know?


1 Hover over, center click on, or something. Ask a UI specialist to help.