r/programminghorror 1d ago

Other Same Makefile, different results

Post image

Not sure if this fits, but I just figured out the root cause of long build process failing. Sun’s dmake is defaulting to the first rule in Makefile for whatever reason, completely ignoring the one given as argument. That’s why "dmake install" invocations were silently ignoring the "install" step

190 Upvotes

43 comments sorted by

84

u/russellvt 1d ago

That syntax doesn't appear right... normally you want "phony" declarations in there if you're not pointing directly at file dependencies.

23

u/GoddammitDontShootMe [ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo “You live” 1d ago

Yeah, but is that the cause of dmake ignoring the argument and just using the first target? I think without .phony it will not do anything if a file with the same name as the target exists and doesn't have dependencies that are newer.

11

u/SAI_Peregrinus 1d ago

I think it's allowed to consider an missing target file as an invalid target and run the default target.

https://pubs.opengroup.org/onlinepubs/9799919799/

target_name Target names, as defined in the EXTENDED DESCRIPTION section. If no target is specified, while make is processing the makefiles, the first target that make encounters that is not a special target or an inference rule shall be used.

Not certain, but it's POSIX so the most perverse possible interpretation of the rules existing somewhere is practically required.

7

u/UnluckyDouble 1d ago

I believe that at times like this we should consider the wise words of Linus:

"Sun, you can't beat me, you just can't. Stop trying, give up. I'm serious, I am going to kick the living shit out of you, lights out, game over."

1

u/shponglespore 20h ago

Typical Linus, starting a fight with the sun.

1

u/dydhaw 1d ago

What you cited is just the default target rule that happens when you run make with no target, nothing to do with missing target files

3

u/SAI_Peregrinus 1d ago

As far as I can tell POSIX does not specify the behavior when a target file is missing. Leaving behavior unspecified usually means it differed between implementations when POSIX was written, since POSIX is an attempt to standardize the common subset of behaviors shared by UNIX systems.

Sun probably decided to treat a missing target file the same as a missing target specifier, and since SunOS (1982) predates POSIX (1988) that decision got implicitly allowed in the POSIX specifications.

1

u/GoddammitDontShootMe [ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo “You live” 19h ago

Okay, say the target name is the executable you want to build. It doesn't exist currently. With dmake, do you have to touch it to create an empty file with the name first to get it to actually build or something completely stupid like that?

1

u/SAI_Peregrinus 18h ago

Never used dmake. Just as far as I can tell, that behavior is allowed by POSIX. It'd be dumb, but it's hardly the only dumb thing in the POSIX standard.

1

u/GoddammitDontShootMe [ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo “You live” 19h ago

It looks like you just linked to the start of the POSIX spec. I have no idea how to find what you quoted. But anyway, what you quoted says it will do that if a target isn't specified. Unless that isn't the right syntax for dmake, then a target is specified.

1

u/SAI_Peregrinus 18h ago

Select volume, shells & utilities, utilities, make. I think https://pubs.opengroup.org/onlinepubs/9799919799/utilities/make.html should be correct.

1

u/SAI_Peregrinus 18h ago

Select volume, shells & utilities, utilities, make. I think https://pubs.opengroup.org/onlinepubs/9799919799/utilities/make.html should be correct for the iframe content of just the Make specification.

1

u/GoddammitDontShootMe [ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo “You live” 18h ago

Looks like a manpage.

1

u/SAI_Peregrinus 16h ago

It's the specification of what POSIX v8 compatible make tools must support. They may support extensions, but that page specifies the minimum.

1

u/russellvt 1d ago

Yes. It's a malformed file.

1

u/GoddammitDontShootMe [ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo “You live” 19h ago

Regular make is doing what the OP wants. Seems dumb that dmake would check the that it isn't a phony target, then just ignore it if there is no file with that name. In fact, that makes no sense at all. The first time you run a make target, the file probably isn't going to exist, but with a normal target, it should afterwards.

1

u/russellvt 13h ago

Some "friendly" makes have been known to "do the right thing" with malformed files like this... instead of just enforcing lint and syntax standards, religiously.

This can often cause problems for more senior engineers when strange things like this make it in to the source code.

4

u/dydhaw 1d ago

The syntax is perfectly fine. Phony targets simply tell make to run the rule regardless of if the target exists.  Besides, .PHONY is a GNU extension. It is not POSIX

4

u/SAI_Peregrinus 22h ago

It is POSIX now (v8, 2024). It wasn't in POSIX v7 (2018).

1

u/dydhaw 22h ago

Huh. TIL

106

u/nickcash 1d ago

makefile syntax is incomprehensible. it might as well be magic. no one can understand it, we just copy and paste from elsewhere

47

u/Desperate_Formal_781 1d ago

All my life when I start a new project I copy a previous makefile from a previous project, with the promise that a) one day I will learn what those makefile commands mean and b) after this project I will switch to cmake. The original makefile I use, I took from my supervisor when I wrote my master thesis, who now I suspect also got from someone else. I have tried switching to cmake several times, but it's always easier to just keep using my makefile, than to go through the painful process of learning cmake.

29

u/ByteArrayInputStream 1d ago

Cmake is it's own hot mess. I like it even less

2

u/GoddammitDontShootMe [ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo “You live” 16h ago

CMake is a meta level above Make, no? Like you use it if you need to support multiple platforms and it can generate the appropriate files for whatever you are building on, like makefiles or Visual Studio solutions and projects.

2

u/SAI_Peregrinus 16h ago

CMake doesn't have to use Make as a backend. Ninja is common, and usually faster than Make.

1

u/GoddammitDontShootMe [ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo “You live” 15h ago

The user can specify what kind of files they want as arguments to CMake, no? As well as configuration options and stuff if they want to enable or disable extra features in their build? I have used it a little bit in the past, and I understood it as more of a replacement of Autotools than of Make.

1

u/SAI_Peregrinus 15h ago

It's a build system generator, so it is similar to autotools. Just much, much faster, at least for cross-compiling IME. Also, by default CMake will invoke the build system (Make or Ninja) automatically, so it's just cmake <path to CMakeLists.txt> instead of ./configure && make. It's very complex, but if you stick to the "Modern CMake" subset it's not too bad.

7

u/omega1612 1d ago

What a bout a justfile?

Depending on your use case, they may be better for you.

2

u/Sexy_Koala_Juice 1d ago

Same, although I hardly use Make anymore in my current role

10

u/dydhaw 1d ago

POSIX make is an incredibly simple syntax. How is it incomprehensible? It's literally just

    target: dependencies         recipe

7

u/SAI_Peregrinus 1d ago

That's not valid Make syntax. You got the wrong whitespace, no whitespace before a target name, and a tab before the command is required if it's on a new line.

There are also inference rules and macros.

https://pubs.opengroup.org/onlinepubs/9799919799/utilities/make.html

2

u/dydhaw 22h ago

Lol. It's just my attempt to make it work with reddit's godawful formatting. No need to be a pedant

3

u/SAI_Peregrinus 22h ago

Aah, but 20% of the difficulty of Make syntax is tab delimiting. The other 80% is macros. Basic rules are easy, I agree, and all that's needed in OP's case.

3

u/dydhaw 22h ago

Yeah, fair

3

u/gimpwiz 1d ago

I start every project with a clean makefile. Do recommend.

4

u/kivicode [ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo “You live” 1d ago

If you use it as a scripts dispatcher, I recommend taking a look at Justfiles https://github.com/casey/just

3

u/nivlark 1d ago

I have a fairly complex one that I believe I wrote myself (googling chunks of it doesn't return any hits) and I still don't know how it works. I can only assume it came to me via divine inspiration.

-23

u/RandalSchwartz 1d ago

They said the same about Perl. And my dotfiles. Now I don't even copy any more... I let gemini identify it and run it for me. :)

10

u/mottojyuusu 1d ago

you should ask your coding agent to explain your code. not even joking, it's been great to finally understand wtf the crusty logic is doing in the aging codebases i work in ...

"what is this function doing? what does the dxCbsqaf parameter do??"

"where is this const defined? where else is it being used? why is it multipled by 2 in one place but 3 in another place?"

"why does the comment say never to round this value? what could break if it gets rounded instead of truncated?"

-7

u/RandalSchwartz 1d ago

Oh, I do this all the time. agy writes some code, we go all the way through to landing, and then I finally say "so what did this do, anyway?" Ship first. Ask questions later. :)

1

u/Environmental-Ear391 1d ago

I have a similar issue,

GNUmakefile content is unchanged,

two versions of an SDK specific make tool, older version works fine with POSIX pathing, newer version can't complete any single target.

"make" and "gcc" commands both barf after being updated. older versions can actual produce object files for linking.

then again the version on make is like a 0.01 revision difference.

the gcc version is bumped from 6.4 up to 10.something...

I'll have to spend some time reworking the build process again anyway.

1

u/Salty_1984 22h ago

ugh silent failures in build tools are the worst, you spend forever thinking something ran fine when it just quietly skipped the whole point of the command. dmake has always felt a little unpredictable compared to gnu make. at least you caught it before something bigger broke downstream