Remix.run Logo
mtlynch 6 days ago

Author here. Happy to take any feedback or questions about this post.

chihuahua 2 days ago | parent | next [-]

It's kinda mind-boggling to me that after making a change to the build definition, there was no way to try it out and see if it works, other than committing the change and waiting until the next day to see if it broke the build.

My question is: how was anyone expected to make changes to the build definition if this was the only way? Wait a day to find out if it worked, and break the build for everyone if not?

rincebrain 2 days ago | parent | next [-]

My understanding from other anecdotes about Microsoft is that a lot of their internal tooling, for a very long time, remained the kind of hideous nightmare of interwoven dependencies and build times measured in hours that we try to avoid in most modern setups.

I would speculate that in most parts of the company that haven't been left to rot that's hopefully no longer true, but I have no direct anecdotes about that, I just would have assumed it to be a target for someone looking for their iteration cycles to be saner at some point, and once one group managed it, etc.

sterlind 2 days ago | parent [-]

never was part of Windows, but from my limited interactions with it the old build system was a chimera of Perl scripts, passes, Makefile-like things and other tooling. build labs would run and jobs would take hours.

it underwent a Herculean effort to modernize it, converging on the actual VS build system and from sd to git. it seemed much healthier last I looked.

mtlynch 2 days ago | parent | prev [-]

>how was anyone expected to make changes to the build definition if this was the only way? Wait a day to find out if it worked, and break the build for everyone if not?

You could build a subcomponent of Windows source locally, and 99% of the time, you knew which subparts of the source tree to build locally to have confidence that you wouldn't break the build.

The problem was that if I was doing something exotic nobody has tried before, I'm suddenly in the 1% case where I no longer have confidence that building locally will eliminate all issues.

quuxplusone 6 days ago | parent | prev | next [-]

At one point you say "precompiler" when I guess you mean "preprocessor"?

Also I think the C preprocessor would be relatively unhelpful with the file format you explained in the post: As soon as you reached the first unmatched, unquoted apostrophe, cpp would assume it was inside a really long character literal and refuse to substitute any macros until the next apostrophe.

cpp is great, but it does basically require a grammar that assigns broadly the expected meaning to ' " # // /* */. Curly-brace languages fine, running English text not so much.

quuxplusone 6 days ago | parent | next [-]

Without running a preprocessor on the .mc file, and without adding "%d" support to `ShowError`, here's one other category of solution. These days, you could just write

    if (minimumPassphraseLength > MAX_PASSPHRASE_MINIMUM) {
      static_assert(MAX_PASSPHRASE_MINIMUM == 20);
      ShowError(ERROR_BITLOCKER_PASSPHRASE_MINIMUM_LONGER_THAN_20);
    }
so that if the value of MAX_PASSPHRASE_MINIMUM ever changed, you'd get a build failure right on this line and you'd be forced to fix it (part of which should involve updating the message to match).

You could make that fancier by trying to craft the name of the error message itself via the preprocessor — something like:

    SymbolicName=ERROR_BITLOCKER_PASSPHRASE_MINIMUM_LONGER_THAN_20
    The BitLocker minimum passphrase length cannot exceed 20.

    ...

    #define CONCAT(x, y) x##y
    #define ERROR_BITLOCKER_PASSPHRASE_MINIMUM_LONGER_THAN(x) \
        CONCAT(ERROR_BITLOCKER_PASSPHRASE_MINIMUM_LONGER_THAN_, x)
    #define MAX_PASSPHRASE_MINIMUM 20

    if (minimumPassphraseLength > MAX_PASSPHRASE_MINIMUM) {
      ShowError(ERROR_BITLOCKER_PASSPHRASE_MINIMUM_LONGER_THAN(MAX_PASSPHRASE_MINIMUM));
    }
But that would just make the compiler error (when MAX_PASSPHRASE_MINIMUM changed) a lot harder to read, without changing the essential task (go find the error message and update it), so it's not a good idea.
mtlynch 6 days ago | parent | prev [-]

>At one point you say "precompiler" when I guess you mean "preprocessor"?

Ah, you're right! Fixed, thanks!

>Also I think the C preprocessor would be relatively unhelpful with the file format you explained in the post: As soon as you reached the first unmatched, unquoted apostrophe, cpp would assume it was inside a really long character literal and refuse to substitute any macros until the next apostrophe.

Oh, that's a good point. I'm not sure how Visual C++ does with it, but I just tried with gcc, and it falls over on an apostrophe:

    $ cat values.h 
    #define MAX_PASSPHRASE_MINIMUM 20

    $ cat example.mcp 
    SymbolicName=ERROR_BITLOCKER_PASSPHRASE_MINIMUM_TOO_LONG
    The BitLocker minimum passphrase length can't exceed MAX_PASSPHRASE_MINIMUM.

    $ gcc --version | head -n 1
    gcc (GCC) 14.3.0

    $ gcc --preprocess --language=c --no-line-commands --include=values.h example.mcp
    SymbolicName=ERROR_BITLOCKER_PASSPHRASE_MINIMUM_TOO_LONG
    example.mcp:2:44: warning: missing terminating ' character
        2 | The BitLocker minimum passphrase length can't exceed MAX_PASSPHRASE_MINIMUM.
          |                                            ^
    The BitLocker minimum passphrase length can't exceed MAX_PASSPHRASE_MINIMUM.
zem 9 hours ago | parent | prev | next [-]

very nice anecdote, thanks for sharing it!

card_zero 2 days ago | parent | prev [-]

Somehow, for me, your code samples are appearing as black text on a black background.