Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Or just switch to Meson+Ninja [1][2] and enjoy all features of modern build systems.

[1] https://mesonbuild.com/

[2] https://ninja-build.org/



Before mesom/ninja, you had one problem - install gmake. Now you have three problems - install python, ninja and meson ;)

Maybe fourth - learn how to use it


> Before mesom/ninja, you had one problem - install gmake.

No, you had as many problems as there are '%' and '$' symbols in this web page : http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/ multiplied by the number of permutations of tools in the different platforms you want to support, e.g. (gcc-mingw-windows, clang-cl-windows, msvc-windows (this one counts as 10), xcode-macos, gcc-macos). And let's not even get started with cross-compiling.


Meson and Ninja cannot handle "C, Perl 5, Python, Ruby, GNU Bash, XML, CMake, XSLT, XHTML5, XHTML1.1, Website META Language, JavaScript and more."

One of make's great strengths is that it is so generic.


Ninja is generic and minimalist. You can use it for anything that can be defined as a command with inputs and outputs.

Writing ninja files by hand is tedious and those extra features make provides can make it easier to use, but in principle ninja should be able to handle anything make could.

It also works in windows.


For my projects which are written in C or C++, I use cmake which can generate BSD makefiles among other targets. For some other projects (websites/etc.) I use gmake directly because they are not related to C. Since some of my makefiles (e.g: https://github.com/shlomif/shlomi-fish-homepage/blob/master/... ) have become quite large, I've started looking for better build systems - see my current research at https://www.shlomifish.org/open-source/resources/software-to... .

I tried using meson for https://github.com/shlomif/mini-factor , and while it worked fine locally it turned out to require python 3.6 which made it hard to install on Travis-CI. I ended up created a complementary cmake build system.


In what sense isn't gnu make a modern build system?


Make is a much of a build system as C++ as you can call stat() and system() from it.

A modern build system by default should be able to provide utilities to make sure your build is correct and reproducible. Those features need to be coded into your Makefile and aren't available easily or by default.

If you need to code those rules, then you don't have a build system, just a way to run commands and possibly add some (usually poor) logic around them.

A typical example that most handcrafted Makefiles will fail is that changing a build flag should only rebuild the files affected. Most will either require a full clean (aka ignoring the flag change) or rebuild everything.


> A typical example that most handcrafted Makefiles will fail is that changing a build flag should only rebuild the files affected.

If you change a build flag, how aren't all the files affected?


I've noticed a plethora of build options over the past decades. I keep hearing how they are all "better" than make.

Then to build one particular bit of software, there is a dependency upon a particular version of cmake, which you don't have.

Or you have to upgrade Maven. Or install some software you do not have by default on your environment.

I've never had to do that with make.

I've been told that other tools are better because the are simpler ... that is ... until you run into one of those aforementioned compatibility issues with the build tool.

This isn't an infrequent occurrence for me, I see lots of hardwiring for various packages that I don't have installed by default in some projects.

Then you get the gophers/rust folk, and their need to run on the most recently released kit. With all its undiscovered bugs. The gophers want to replace make with mage ... well, to be more correct, they want to replace every non-go based tool with one built in go, because ... go. A modern version of the insufferable pythonistas of years past.

Throughout this, I've been using and building with Make just fine. My make files do the heavy lifting in my projects. And I get a good laugh each time I hear "oh I have to fix my magefile/CMakeFile.txt/yadda yadda yadda".

As the great philosopher Inigo Montoya once opined ... you keep using that word [better]. I do not think it means what you think it means.


Usability.


I find gnu make very usable and very clear on its purpose. Sometimes I have used cmake and it was uglier, more complicated, and harder to understand. What would you suggest as a modern, usable build system?


> Sometimes I have used cmake and it was uglier, more complicated, and harder to understand.

okay, please provide a makefile which:

* detects if, say, libpng is available

* compile a library, an executable and a unit test if that's the case

* links the executable to the library and the library to libpng

* does so for mac, windows, linux, creates a .app for mac, an installer for windows, a .deb package for linux

* can be used from IDEs, with IDEs understanding where your code has to be fetched, what the includes are, etc

here's more-or-less the CMake version :

   project(myapp)

   find_package(PNG REQUIRED)

   add_library(mylib lib.c)
   add_executable(myapp MACOS_BUNDLE WIN32 app.c)
   target_link_libraries(mylib PRIVATE PNG::PNG)
   target_link_libraries(myapp PRIVATE mylib)

   install(
      TARGETS myapp mylib 
      RUNTIME DESTINATION bin 
      ARCHIVE DESTINATION lib)
   include(CPack)
you can't seriously say that this (which covers an immense part of software project needs) is easier to do in make, right ?


> * detects if, say, libpng is available

You just compile with -lpng. If libpng is available, it will work, otherwise it will fail with a clear error message. What else do you need?

> * links the executable to the library and the library to libpng

    LDLIBS = -lpng
 
    BIN = foo bar baz
    OBJ = lib1.o lib2.o lib3.o
    LIB = libmine.a

    default : $(BIN) $(LIB)
    $(BIN)  : $(OBJ)
    $(LIB)  : $(LIB)($(OBJ))
    clean   :        ; $(RM) $(BIN) $(LIB) $(OBJ)
    check   : $(BIN) ; ./foo -test
This will compile the code from lib*.c into libmine.a, and then compile the source code of a few test executables from foo.c, bar.c and baz.c

The .a is useless often, but there you have it just in case. Otherwise, just remove all references to $(LIB) and get a shorter makefile.

> you can't seriously say that this (which covers an immense part of software project needs) is easier to do in make, right ?

This is rather subjective. In my case the makefile seems easier. It will work for all unices, but probably not for windows, and will not create an "app" package, your are right about that.

But the makefile covers indeed all my personal needs, and it is much more powerful and easier to use than the cmake/make combo. For example, you can test multiple compilers and compiler options with a shell loop:

    # test all compilers in debug and release modes
    for i in gcc clang tcc icc; do
    for m in "-O3 -DNDEBUG" "-g"; do
	    make clean check CC=$i CFLAGS=$m
    done
    done
doing that in cmake would be a nightmare, wouldn't it?


> You just compile with -lpng. If libpng is available, it will work, otherwise it will fail with a clear error message. What else do you need?

well, no you don't "just compile", because one of the most used compilers out there does not support "-l". Also because you may have multiple libpng versions on your machine - debug, with special testing flags, in your ~/work/libpng_build, etc.

Also, you may have libpng.so but not the headers. You may be compiling on Nix or GoboLinux or whatever system which does not respect the FHS. It won't work as is on OS X because you have to add -L/usr/local/lib. Users won't know what to do when they see whatever missing include error the compiler spits out.

> doing that in cmake would be a nightmare, wouldn't it?

.. it would be mostly the same than your example ? just tested and this works fine (normal practice with cmake is to build outside of src which helps):

    for i in gcc clang; do        
        for m in "-DCMAKE_BUILD_TYPE=Debug" "-DCMAKE_BUILD_TYPE=Release"; do #not using -g because that's something compiler-specific
            rm -rf ** ; CC=$i cmake ../ $m ; cmake --build . 
        done
    done


Spare your fingers ;) - you'll never convince anybody of the value of cmake by telling them about it. You just have to put them in a situation where they're looking after a program that has to build on multiple desktop platforms, and they'll figure it out eventually...

(The combination I've always had to deal with is Linux, OS X and Windows/VC++ - but any combination that includes both Windows/VC++ and a POSIX-type OS is probably enough to make it worthwhile. The POSIX/non-POSIX differences are rather annoying to deal with otherwise, and that quite apart from how most Windows programmers will quite reasonably want to use a Visual Studio project rather than a Makefile.)

506c


Yeah, CMake and autotools solve different problems than make. I'm definitely not a fan of either one but if I need to really distribute and compile something on more than one OS there isn't much of a choice.

The posted makefile example fails right away on multiple platforms since headers are often in somewhere else than in /usr/include directly, for example in Debian the right (atm) path would be /usr/include/libpng16 and Makefile does not handle that.


> The posted makefile example fails right away on multiple platforms since headers are often in somewhere else

And that's the intended behavior. Finding system headers around your disk is not a problem that a build system must try to solve. This is the task of a distribution or a packaging system, which is a different problem as you say.


Yeah I agree, it's not the ideal situation but it is the real world. Simple makefiles do not work often and there are systems that can solve the problem. Not elegant, brilliantly designed tools but ones that work anyway.


I hope this day never arrives for me... In any case, if I ever had to compile something for windows I would rather install cygwin and a posix toolchain than cmake and visual studio.


Thanks for your answer, I see that cmake is not as cumbersome as I thought.

> Also, you may have libpng.so but not the headers.

Then how on earth are you supposed to compile it? You write the definitions verbatim on your code?

> It won't work as is on OS X because you have to add -L/usr/local/lib.

For that case it is better to not mess with compiler options and set up the compiling environment so that -lpng works, e.g. by setting LIBRARY_PATH=/usr/local/lib, and similarly for C_INCLUDE_PATH. These variables are recognized by all unix linkers and compilers that I care about.

Of course, this attitude may not be appropriate for everyone. Yet, I am in the happy position to be able to say say "this program requires gcc, clang, tcc or icc to be compiled, otherwise, please edit the makefile to suit your needs". Are there really other C compilers around? (notice that visual studio is not a C compiler, and cannot compile modern C code, so it does not enter into the discussion if you are a C programmer).


Yes, quite a few, mainframes, embedded OSes, bare metal deployments for SoC, surviving commercial UNIXes.


> Then how on earth are you supposed to compile it? You write the definitions verbatim on your code?

what I mean is that an user might download your source archive, run `make`, and have hard-to-understand failures because of this.


For example it checks the last modified time on all your files, every build. This doesn’t scale at a certain point. More modern build systems have better ways of doing this.


How to modern build systems check for file updates?


I can't speak for other build systems, but tup [0] provides the option to listen for filechanges via the fuse library.

[0] http://gittup.org/tup/make_vs_tup.html <edit substitutes the make comparison link instead of the main page>


Meson is a joy to use.


Ever tried Premake?


Long time ago, I thought it is not that actively maintained as before.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: