7 ms·
MakeMake: Generate make files from C source code
- jjgreen 3y ago[edited] Since extern is the default scope for functions, so can be (and often is) omitted in declarations and definitions, won't the program "miss" functions which are implicit extern? (I've not inspected the code in detail, so might well be wrong, to indicate this an earlier version of this comment was prefixed with an "Er", which was taken by other commenters as a swipe, not my intention).
- jahsome 3y agoUm, you do know that the word "can" indicates a personal preference and has no effect on functionality, so there is no need to be passive aggressive?
- jjgreen 3y agoFrom the project's README make make does this by looking for any function declaration using extern, Taking that at face value (I'd not inspected the code in detail), then it would miss functions with implicit externs, no? My apologies if you found my posting offensive, that was not my intention.
- jahsome 3y agoI don't know enough to even answer to that, and it's not the issue. The issue is phrasing a statement as a question like you did is passive aggressive, and unconstructive.
- dang 3y agoPlease don't respond to a bad comment by breaking the site guidelines yourself. That only makes things worse. https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html
- zabzonk 3y agoin my experience, anyone that accuses someone else of being passive aggressive are themselves being passive aggressive. let's just not do that.
- jahsome 3y agoI mimicked the comment merely to demonstrate how childish the tone was. But I agree it's tacky.
- dang 3y agoCan you please make your substantive points without swipes? This is in the site guidelines: https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html. (Edit: I see downthread that you mentioned it wasn't your intention.)
- notfed 3y agoI've made a similar tool in the past: https://github.com/notfed/automaker https://github.com/notfed/automaker
- oolonthegreat 3y agoreminds me of tsoding's nobuild, except it bypasses make and the only thing required is a C compiler. neat!
- keyle 3y agoDo you have a link or more info on this?
- lifthrasiir 3y agohttps://github.com/tsoding/nobuild https://github.com/tsoding/nobuild Basically it is a build system that uses C as a DSL. And no dependency tracking I think?
- keyle 3y agoThanks but... Oof! I think I prefer make.
- p4bl0 3y agoGCC has the ability to generate dependencies in the Makefile format using `gcc -MM` which I guess is also for "Make Make" :). It does not create the whole Makefile but it's a nice way to have a script (or a Make recipe) that maintains up-to-date dependencies for each targets in a file that can be included from the Makefile (which then declares generic compilation recipes). E.g.: force-update-deps:: rm .deps .deps: gcc -MM *.c > $@ include .deps
- toast0 3y agoClang's docs say -MM includes only user dependencies, -MD includes user and system dependencies. A better choice if your system includes might change.
- o11c 3y agoSystem includes are generally well-behaved though, so it doesn't matter if they add new things.
- AceJohnny2 3y agoGoing on a tangent here, but properly integrating support for such "discovered" dependencies in GNU Make can get a bit complicated. In particular, you probably want to use `-include` instead of `include`, to continue even a given .dep file doesn't exist (as on the first run). The GNU Make maintainer wrote in-depth about ways to do it here: https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ https://make.mad-scientist.net/papers/advanced-auto-dependen...
- jjgreen 3y agoI think you can get away with 'include' here -- the (Gnu only?) make behaviour on trying to include a non-existent file is to look for a target which creates that file, then running it if found, then to try the include again. This has other applications: if your Common.mk is generated by autoconf (say), then default: all Common.mk: $(error Not configured) include Common.mk gives a nicer error message if you 'make' having not './configure'd
- notfed 3y ago> make make does this by looking for any function declaration using extern In C, "extern" is normally implicit for functions. Does your tool require them to be explicitly marked?
- quelsolaar 3y agoYes. I had an early implementation that did look for any function declarations, but using extern made it more robust, and enforces the use of extern, something i think helps with clarity.
- felipellrocha 3y agoIt’s make all the way down
- zabzonk 3y agothis: https://latedev.wordpress.com/2014/11/08/generic-makefiles-with-gcc-and-gnu-make/ https://latedev.wordpress.com/2014/11/08/generic-makefiles-w... is a blog article i wrote a long time back abouut how to automate makefiles. there is a lot wrong with it, but some of the concepts might be useful for people trying to do better. edit: in the blog i said "indirection" when i meant "redirection". doh.
- deleted 3y ago[deleted]
- Animats 3y agomakedepend [1] [1] https://en.wikipedia.org/wiki/Makedepend https://en.wikipedia.org/wiki/Makedepend
- jim_lawless 3y agoWe had purchased a commercial MS-DOS utility with the exact same name back in the early 90's. It was reasonably priced ... I think it was $50 at the time. It successfully untangled the dependency chain in our code allowing for more optimal build times.
- CoastalCoder 3y agoMy interest in make and makemake has recently been rekindled. I've mostly used CMake for my build systems over the past ~20 years. But recently I got into CUDA programming, and I was put off by the large amount of opaque magic provided by CMake's built-in CUDA support. It made it somewhat harder to have clarity about the variety of CUDA build commands, which kinds of file each could ingest and produce, and which options they accepted. As someone new to the entire CUDA toolchain, that magic was more of an impediment than an help. So for starters I'm just writing a Bash script for building my code. But the next step for automation will be a hand-written Makefile, not a CMakeLists.txt file.
- ahejfjarjnt 3y agoThat's the way to go in my opinion. The FreeBSD folks build their entire damn project with make, although I'll admit my eyes glaze over a bit anytime I take a look at it. CMake is just a little too high level for my taste. Like I don't really understand how its figuring stuff out under the hood. Now that is of course because I haven't bothered studying up on it, but the point is you don't really have to with Make since the basic concept is dead simple.
- Thorrez 3y ago>My interest in make and makemake has recently been rekindled. Did you have an interest in makemake before? This github repo looks brand new.
- CoastalCoder 3y agoI'm not sure exactly how long makemake has been around, but I think it's at least 20 years.
- ChickeNES 3y ago> MakeMake was designed to solve my problem (Im a C developer that develops > protable C programs using VisualStudio, and I do not want to maintain up > todate make files for all projects and platforms). I just don't understand why you wouldn't use CMake for this? Especially since VS has built-in CMake support.
- not_the_fda 3y agoYep, modern CMake makes this super easy, its a solved problem.
- bch 3y agoWhat constitutes “modern” here? ~15 years ago I was bitten by the CMake bug and enjoyed it for years until I got frustrated by it getting 90% of the job done and having to fight it for the last 10%. These days I have “reverted” back to BSD Make, and feel pretty good about it. So… when did CMake start its “modern” phase? Does my experience resonate with yours at all?
- plorkyeran 3y agoThe switch over to doing everything via target properties is the big difference between "modern" and "old school" CMake. This fixed a lot of CMake's problems other than the scripting language being awful and has mostly happened over the last decade. CMake release notes pretty consistently have at least one thing that makes me go "how is that a thing that just got implemented now and not 20 years ago?" That's not exactly a positive, but there are a very large number of things where 15 years ago you'd be shocked and frustrated to discover that there's no good way to do it, while today there's an obvious and simple way.
- o11c 3y agoI stopped considering CMake when I reported a bug (that worked in all major alternatives) and they actively refused to patch it (because it was based on a traditionally-UNIX API, and they refused to use it ... even though it was available on Windows too!).
- kristopolous 3y agoLet's get this cleared up now. Is it https://en.wikipedia.org/wiki/Makemake_(deity) https://en.wikipedia.org/wiki/Makemake_(deity) as in "ma ke ma ke" or "make make"?
- hnaccountme 3y agoAutotools???
- kamray23 3y agoAutotools are so big for tiny projects though. Like if I need a small util I'm not configuring autotools.
- chr15m 3y agoYou might also like this "make watcher" hack for continuous builds: while true; do make -q || make; sleep 0.5; done https://stackoverflow.com/a/48496716 https://stackoverflow.com/a/48496716
- norir 3y agoNice quick and dirty hack, but the latency isn't great and it will hammer the file system in large projects calculating time stamps. It's especially bad on windows although polling on mac has also historically been rather expensive (linux is better in this regard though polling still isn't free). I'd much rather install entr if it's available and do something like `ls ** | entr -c make`
- ChickeNES 3y agoOr even better, fswatch (https://github.com/emcrisostomo/fswatch https://github.com/emcrisostomo/fswatch) which works on Linux, BSDs, macOS, Windows, and even Solaris
- buserror 3y agoTHIS is the lightest way to have continuous make, without wasting cycles and hammering the file system. inotifywait is a pretty standard tool that does exactly what's needed. watch : while true; do \ clear; $(MAKE) -j all tests; \ inotifywait -qre close_write src tests; \ done
- buserror 3y agoI don't understand, with gcc -MM (to generate .d files), -include to include them, and VPATH for source file discovery, a typical small project makefile is about 1/2 page and requires very little maintenance. More complicated project? Might shoot out to 2 pages. It'll still work in 20 years time too, the tools won't change under you (I'm looking at you, pretty much all other build systems)
- quelsolaar 3y agoHere is the fundamental problem it solves for me: my code in 99% pure C code without dependencies. Then i have a few wrappers for platform specific stuff. I have many many projects that use the same wrappers. Make files store both what files are used and what dependencies there are, but that creates a lot of duplication. Its better if the wrappers themselves can say what dependencies they have. Then thats stored in one place, and a change affects all projects. Then we have the issue of what files are needed. That information already exists in the .c files, so again why duplicate it? Its better to parse it out.
- ReleaseCandidat 3y agoYes, even MS' cl has `/sourceDependencies` and `/scanDependencies` by now, which generate JSON files with the needed information.
- kitd 3y ago> To build makemake on unix platform you can use the shellscript MakeMakeMake Ofc, what's really needed is a tool to make the MakeMakeMake script. Struggling for a name though ...
- unwind 3y agoThat's built in. Read the readme. :)
- mtlmtlmtlmtl 3y agom4?
- deleted 3y ago[deleted]
- AmazingTurtle 3y agoWhy not just jq?
- ReleaseCandidat 3y agoIt is a bad idea to use "makemake" as a name, I have seen/heard about at least 5 different programs/scripts/... called makemake during the last 25 years, each of which had been quite widespread (I wouldn't have heard of that 20 years ago if it hadn't ;). And nowadays I get quite a number of Github repos called "makemake". And there is always makedepend (and similar named programs) too, of course. I don't want to sound too negative, but what does this version do that all the other existing 13843215 versions don't?
- quelsolaar 3y agoIt builds a Android APK with one line of comand line on a fresh install linux to begin with (Thanks to Felix) thats pretty cool. Id say the main use case is to move dependencies from a project file to the actiual C files that have the dependencies, This way if the dependencies change all projects that use the file have their build process automaticaly updated. It also removes the need to list the files included in a project since this is information that already exists in the .c files. Any time you have to define the same thing in two places, you have the risk of them not beeing in sync. This way there is only one canoical ground truth. Source and build process can never be out of sync.
- ReleaseCandidat 3y agoI'm sorry, but that doesn't really answer my question. I'll try another one: does it correctly set preprocessor directives before parsing the includes? E.g. does it correctly parse stuff like #ifdef FOO #include <bar> #else #include <baz> #endif
- quelsolaar 3y agoNo, Bercause MakeMake cant know what defines are made by the compiler on the system. MakeMake may not even run on the same system as the resulting makefile will be used on. This means that all source code files has to be compilable on all platforms, and thats good practice anyways, so thats not a problem for me. The makemake pragma lets you define platform specific build options.
- cassepipe 3y agoI have a makemake function in my zsh config for simple C programs that relies on implicit rules (which I turn off for more complex programs) : function makemake() { >makefile echo ' .RECIPEPREFIX = > ASAN = -fsanitize=address CFLAGS += -Wall -Wextra -g3 CFLAGS += $(ASAN) LDFLAGS += $(ASAN) -Wall -Wextra -g3 SRCS = $(wildcard .c) OBJS = $(patsubst .c, .o, $(SRCS)) #CC = clang # main function must be in the $NAME.c file '"NAME=${1:-main}" ' all: $(NAME) $(NAME): $(OBJS) print_name: > @echo $(NAME) clean: > rm -rf .o fclean: clean > rm -rf ${NAME} re: fclean all .PHONY: print_name clean fclean re ' }