# Tag Info

16

Dependencies: right now your makefile will let changes in .h to remain unnoticed. DEPS := $(SOURCES:.c=.d) .c.d:$(CC) -o $< -MM$(CFLAGS) -include $(DEPS) PS: it is highly recommended to remove -c from CFLAGS and mention it explicitly in the .c.o rule. 11 I would make source file discovery dynamic: SOURCES =$(wildcard *.c) In addition to all I usually add debug and release versions. CFLAGS = -fdiagnostics-color=always -std=gnu11 -s -c -time all: CFLAGS += -DTYPE=ALL debug: CFLAGS += -DTYPE=DEBUG -g3 release: CFLAGS += -DTYPE=RELEASE -O3 I have a generic build file that I have all my rules ...

11

The first rule should just be all: $(EXECUTABLE) In turn,$(EXECUTABLE) will require $(OBJECTS), and each object will require its corresponding .c file. Also, all should be a .PHONY target, since you are not actually going to produce a file named all. Both of the remarks above apply equally to the debug target as well. 11 You are not using the make system properly. As a result, it will always relink the executable, even when everything is already up to date. On the other hand, it might fail to recompile some source files into object files. When you run make… It will try to create the build target. No file named build exists, so… It will try to create the prerequisites ... 11 Common Conventions The C++ compiler is named CXX What you call RESULT is usually named TARGET In addition to SRC you probably need OBJ Commands are usually replaced by uppercase version varaiable names that name themselves. ie. RM not DEL Building issues It rebuilds everything every time for two reasons. The all: rule performs a clean: before it starts. ... 10 Things you did well You initialize your variables when you declared them. You initialize variables inside of your for loops.(C99) Your pointer arithmetic looks pretty sound. Things you can improve Efficiency/Algorithm Unfortunately, bubble sort is not a very good sorting algorithm if you are looking for speed. Its average case performance is \$ O\left(n^...

9

My CMake-fu is a bit rusty - probably as old as this question -, but I still see some things that could be trivially improved: CMake doesn't require else() and endif() to contain the original if() expression anymore. It seems that this restriction disappeared a long time ago, so you can simplify your code by leaving empty else() and endif() expressions. ...

7

First of all, good for you for learning how to write a proper makefile. Few people are any good at it, and it's a really fundamental tool. Even when nice tools such as CMake are used, it's very useful to understand how to write one from scratch. With that said, here are some things that may help you improve your makefile: Prefer Makefile to makefile The ...

7

Making sources? The line all: $(SOURCES)$(EXECUTABLE) asks make to build $(SOURCES), in this case helloWorld.cpp. Is it possible to build it? Strictly speaking there are situations when you do want to build the source file (e.g. fetch it from git/cvs/sccs) but it is not applicable here: no rule is provided. Generally you don't want to build something ... 6 I'll assume throughout this answer that you're targeting GNU Make. It's available on all targets that matter, and it simplifies your world no end if you can avoid pandering to the idiosyncrasies of the manifold implementations of Make supplied with operating systems. Object files depend on headers This is the biggest thing that I think could be improved; I ... 6 The biggest problem I can see is that you are not using idiomatic Makefile names, which will confuse readers and frustrate users who want to change things via the command line. Typically CFLAGS is compiler flags passed to the C compiler, CPPFLAGS the preprocessor and CXXFLAGS the C++ compiler.$(CPP), $(I) and$(L) are are also just plain confusing and hard ...

6

Couple of things you do that don't match standards. CXX is usually the C++ compiler CC is usually the C compiler. CXXFLAGS are the flags that are applied to the C++ compiler. CPPFLAGS are the flags that are applied for the pre-processor. This usually means passed to both C and C++ compiler. CFLAGS are the flags passed to the C compiler. ...

6

Makefile review We're missing the instruction to tell Make to remove partial results from failing rules; all Makefiles should somewhere contain .DELETE_ON_ERROR: makeiso is never up to date. We don't want to re-run it unless the binary has changed, so I'd write: makeiso: $(RESULTING_ISO)$(RESULTING_ISO): $(BINDIR)/$(BINARY) $(info )$(info $(... 5 I am the author of FASTBuild. I presume the config as you have it is ok, but you're worried about copying it 95 times for your other projects and it becoming unmaintainable. With that in mind, the best advice I can offer is to continue to factorize the common configuration patterns into structures (as you've already started doing). In particular, it looks ... 5 Your OBJ* variables are unnecessary, as they are just the executable name with a .o extension. You can simplify by doing something like this:$(PROG1) : $@.o$(OBJ3) $(LD)$^ -o $@$@ expands to the name of the recipe's target, and $^ expands to the list of prerequisites. Note that this also replaces PROG3 with OBJ3, since that's what is actually ... 5 clean and all are not files should therefore be declared as phony. .PHONY: clean all all :$(PROG1) $(PROG2)$(PROG3) ... clean : /bin/rm -f *.o a.out $(PROG1)$(PROG2) $(PROG3) 5 To complement the Makefile review, here are a few more points that may help you improve your program. Use VPATH make already has a number of builtin rules that could be used for this project with no loss of generality. If you omit the colored printing (which I would advocate) and use VPATH, you could use replace most of your Makefile with a single rule: ... 4 import sys, os, time, copy, logging from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler class ChangeHandler(FileSystemEventHandler): def __init__(self, callback): if callable(callback): self.callback = callback else: raise TypeError('callback is required') def ... 4 A couple of things I dislike about your set up. Your low level make file in the top level directory. You only have one object directory (so you can only have one type of build) I have four types of build debug/release/coverage/size(built with size optimization) You use explicit commands where the makefile internal rules will work just as well. 1: At the ... 4 Yes: CXX = g++ # # Notice the +=. Use CPPFLAGS rather than INC for pre-processor rules. # CPPFLAGS += -Iinclude/ -I../tools/ CXXFLAGS += -std=c++0x # # Move the backslash # This will stop it looking like a directory at first glance. binaries=01sum35 \ 02evenfibs \ 03largestprimefactor \ ... 4 CFLAGS traditionally refer to compiling .c files. The c++ compiler is traditionally invoked with CXXFLAGS. I must advise against automatic collection of SOURCES (line 54). Usually you need to build more than one target from the same tree (a unit test version, for example). It is better to be explicit telling which sources contribute to which target. Line 67. ... 4 It looks pretty good to me, but I see a few minor things that might be improved. Specify which perl to run I'd recommend not leaving it to chance as to which instance of perl is run. Instead, for both safety and consistency, it might be better to do this: PERL=/usr/bin/perl ##... @$(PERL) -e '$(HELP_FUN)'$(MAKEFILE_LIST) Allow multiword category tags ...

4

You should be able to simplify the definition of DEPS to DEPS := $(OBJS:.o=.d) For small projects that don't require complicated configuration schemes, it's often times easiest to get the list of source files by wildcard instead of manually maintaining an explicit list: SRCS :=$(wildcard $(SRCDIR)/*.c) OBJS :=$(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,(... 4 Dependency Propagation One thing that's missing is dependency propagation. So each .o file will be recompiled only if its corresponding .cc file has changed. This is good, I don't want to have to recompile foo.o just because I changed bar.cc. However, what if both foo.cc and bar.cc include some other file quux.h, and you changed some of the function ... 4 I see some things that may help you improve your program. Don't use unneeded macros The AC_C_CONST is only used to compensate for either a C compiler that doesn't fully support the const keyword or when a C++ compiler is used to compile C code. Since CFLAGS has -std=gnu99, it's clear that this project is assuming either gcc or clang, both of which have ... 4 In makefiles you can have spacing around equals signs, making the code slightly easier to read. For example PREFIX = ./node_modules/.bin. UPPER_CASE variables are generally used for things that the end user might want to change when running, while lower_case is for internal use variables. The user is presumably not supposed to change for example the source ... 4 There is no need to pass linker flags to the compile stage. You only them when you link the final executable. Traditionally (aligned with make defaults) the flags variables are CFLAGS for C compiler, CXXFLAGS for C++ compiler, and LDFAGS for the link stage specifics. It is not recommended however to have -c as a part of CFLAGS: the CFLAGS can be reused for ... 4 I see a number of things that may help you improve this. Don't manually write a Makefile Since you're using standard tools such as gcc and ld, you could use: autotools (that is the collection of autoconf and related software) instead of writing and maintaining your own Makefile. There is a learning curve, of course, but the benefits are considerable, ... 4 As mentioned in the comments, define two macros: COMPILER_OPTIONS := -Wextra -Wall -O3 -Wno-unused-result -Wno-unused-parameters CUDA_COMPILER_OPTIONS :=(foreach option, $(COMPILER_OPTIONS), --compiler-option$(option)) C in CFLAGS stands for compiler, and should contain only the compile phase options. Don't send CFLAGS to the linker, it is surely not ...

4

The dependencies of gcd.h and test.h are missing. If you modify them, the objects would not be rebuilt. Stem rules let you avoid repetition: obj/%.o: src/%.c gcc -c $< -o$@ is the (almost) only thing you need to generate all objects. Almost, because you'd still need to add .h dependencies. gcc has a nice feature to autogenerate them: obj/%.d: src/%...

Only top voted, non community-wiki answers of a minimum length are eligible