Compile sources and objects list with clang using makefile - makefile

src = $(wildcard src/*.c)
src_files = $(notdir ($src))
obj = $(src_files:%.c=build/%.o)
all: $(obj)
$(obj): $(src)
clang ${clang_options} -c $(src) -o $#
If my makefile is written in this way, I can just iterate list $(obj) through $#.
How could I iterate both $(obj) and $(src) in one rule?

What you wrote means that any object file depends on all source files and is the result of the compilation of all source files. This is probably not what you want. Use a static pattern rule:
src = $(wildcard src/*.c)
src_files = $(notdir ($src))
obj = $(src_files:%.c=build/%.o)
all: $(obj)
$(obj): build/%.o: src/%.c
clang ${clang_options} -c $< -o $#
This means that any object file depends on only one source file, with same base name, and is the result of its compilation.

Related

make: Cleaner way to refer to object files in subdirectories

I've got a simple program that has sources in its root directory and in subdirectories. I'm using recursive make invocations to build the subdirectory objects. When linking I can use a symbolic name for the objects in the program's root (${OBJECTS}) but not for objects in the subdirectories (*/*.o). Is there a cleaner way to refer to the subdirectory object files than what I've written? I'm using GNU Make 4.1. Here's the (simplified) top-level Makefile:
MAKE = make
CXX = g++
CFLAGS = -O -Wall -D_DEFAULT_SOURCE -D_BSD_SOURCE
LIBS =
PROGRAM = program_name
TOPTARGETS := all clean
SUBDIRS := util command device
$(TOPTARGETS): $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $# $(MAKECMDGOALS)
.PHONY: $(TOPTARGETS) $(SUBDIRS)
all: $(PROGRAM)
SOURCES := $(wildcard *.cpp)
OBJECTS := $(SOURCES:.cpp=.o)
$(OBJECTS): %.o: %.cpp %.h
$(PROGRAM): $(OBJECTS) ${SUBDIRS}
$(CXX) -o $(PROGRAM) ${OBJECTS} */*.o $(LIBS)
clean:
rm -f ${OBJECTS} $(PROGRAM)

Makefile doesn't find source files

I have tried to make a makefile. I have the following folder structure.
Source
- include
- My headerfiles
- objects
- The object files
- src
- My source files
My problem is that the source files in the src directory isn't found.
My make file looks as the following.
# gcc for C
# g++ for c++
CC = gcc
#compiler flags
# -g adds debugging information to the executebells
# -Wall
CFLAGS = -g -Wall
#target
TARGET = gabe_the_dog_server
#directory for the object files
OBJDIR = ./objects
SRCDIR = ./src
default: $(TARGET)
all: default
HEADERS = $(wildcard include/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
$(OBJDIR)/%.o: $(SRCDIR)/%.c $(HEADERS)
$(CC) $(CFLAGS) -c $< -o $#
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) $(CFLAGS) $(LIBS) -o $(OBJDIR)/$#
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
clean:
-rm -f *.o
-rm -f $(TARGET)
Here:
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
You use the variable SOURCES, but you never define it. You need one more line:
SOURCES = $(wildcard $(SRCDIR)/*.c)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
Instead of using the path to your source files, it's recommended that you put this path in the special variable named VPATH. Then you just mention your source file, like this:
OBJDIR = ./obj
SRCDIR = ./src
VPATH = $(SRCDIR)
OBJECTS = $(addprefix $(OBJDIR)/, foo.o bar.o)
all: $(OBJECTS)
$(OBJDIR)/%.o: %.c
$(cc) ...
GNU make will look in the folders present in VPATH for the files that are prerequisites of a target. Note that this could be a problem if you have multiple folders where you can find multiple times the same file name.
See GNU make VPATH manual. If you need additional examples of VPATH good practices, see this link as well: Mad Scientist: How not to use VPATH

Makefile with multiple directories and dependencies

``I am pretty new to Makefile and I am trying to build a project.
This is the structure of my project:
-Project
|-generic
| |-include
| |-src
|-specific
| |-include
| |-src
|-Makefile
|-bin
Here generic contains mainly interface classes (virtual), and files in specific may depends on those.
I want to compile all sources and put their corresponding .o files in bin and also create a static library in bin.
EDIT:
CC=k1-g++
CPPFLAGS=-c -I$(GENERIC_INCLUDE_DIR) -I$(SPECIFIC_INCLUDE_DIR) -Os -std=gnu++11 -mos=nodeos
CXXFLAGS=-c -I$(GENERIC_INCLUDE_DIR) -I$(SPECIFIC_INCLUDE_DIR) -Os -std=gnu++11 -mos=nodeos
LFLAGS=-pthread -lnodeos
GENERIC_INCLUDE_DIR=generic/include
SPECIFIC_INCLUDE_DIR=specific/include
GENERIC_SRC_DIR=generic/src
SPECIFIC_SRC_DIR=specific/src
LIB = libengine.a
BIN_DIR=bin
vpath %.cpp $(GENERIC_SRC_DIR) $(SPECIFIC_SRC_DIR)
SOURCES := $(wildcard $(GENERIC_SRC_DIR)/*.cpp $(SPECIFIC_SRC_DIR)/*.cpp)
#SOURCES := $(wildcard $(GENERIC_SRC_DIR)/*.cpp $(SPECIFIC_SRC_DIR)/*.cpp)
SOURCES := $(notdir $(SOURCES))
OBJECTS := $(patsubst %.cpp,$(BIN_DIR)/%.cpp.o,$(SOURCES))
all: $(OBJECTS) $(LIB)
$(LIB): $(OBJECTS)
ar -cvq $(BIN_DIR)/$# $^
#$(BIN_DIR)/%.cpp.o: $(GENERIC_SRC_DIR)/%.cpp
# $(CC) $(CPPFLAGS) $< $(LFLAGS) -o $#
$(BIN_DIR)/%.cpp.o: %.cpp
$(CC) $(CPPFLAGS) $< $(LFLAGS) -o $#
.PHONY: clean
clean:
rm -f $(BIN_DIR)/*
Any help would be appreciated
Suppose you have generic/src/foo.cpp and specific.src/bar.cpp.
This:
$(BIN_DIR)/%.o: %.cpp
$(CC) $(CPPFLAGS) $*.cpp -o $#
is pretty close to what you need (I've replaced $(BIN_DIR)/$*.o with the automatic variable $#, which expands to the name of the target); the only problem is that it doesn't work. This rule tells Make it can build obj/foo.o from foo.cpp, but there is no foo.cpp. There's a generic/src/foo.cpp, but Make doesn't know that that's what you meant. We could write a rule like this:
$(BIN_DIR)/%.o: $(GENERIC_SRC_DIR)/%.cpp
$(CC) $(CPPFLAGS) $*.cpp -o $#
But a tidier way is to use the vpath directive:
vpath %.cpp $(GENERIC_SRC_DIR) $(SPECIFIC_SRC_DIR)
$(BIN_DIR)/%.o: %.cpp
$(CC) $(CPPFLAGS) $*.cpp -o $#
This will do nicely for building any one object file, but you say you want to compile "all sources". That isn't always a good idea, but if that's what you want it isn't hard, we use wildcard to obtain a list of all the sources, then convert that into a list of corresponding object files, then build them all:
SOURCES := $(wildcard $(GENERIC_SRC_DIR)/*.cpp $(SPECIFIC_SRC_DIR)/*.cpp)
SOURCES := $(notdir $(SOURCES))
OBJECTS := $(patsubst %.cpp,%.o, $(SOURCES))
# We could have done that all in one line, but this way is easier to read.
all: $(OBJECTS)
Now for the library:
vpath %.o $(BIN_DIR)
$(BIN_DIR)/$(LIB): $(OBJECTS)
ar -cvq $# $^
Further refinements are possible, but that should keep busy for a while.

My Makefile is trying to compile a non-exsistent/made up filename

This is my VERY FIRST Makefile and so I have cut and paste junk I have found all over the web. My directory structure is pretty flat and was not thought out for Makefiles. It is:
Project/
Project/Control
Project/NodeMgmt
Project/Common
Project/Interfaces
I am writing a Makefile for Control and would like it to standalone inside Control. It needs to include compile and include from Common & Interfaces. Here's my Makefile:
CC = g++
CFLAGS = -Wall -c
INCLUDES = -I/usr/local/include -I/SuperCool/Ion-1.0.0-snapshot-1/include -I/SuperCool/FastrakSDK-4.0.1-snapshot-1/include/Fastrak/Engine/Core/CoreIpc -I/Projects/Common -I/Projects/Interfaces -I/Projects/NodeMgmt -I/Projects/Controller
LFLAGS = -L/usr/local/lib -L/SuperCool/FastrakSDK-4.0.1-snapshot-1/lib
LIBS = -lCoreIpc4 -lIonOs
VPATH = ../Interfaces/
VPATH = ../Common/
VPATH = ../NodeMgmt/
SRCS = *.cc
OBJS = $(SRCS:.cc=.o)
MAIN = controller
.PHONY: clean
all: $(MAIN)
#echo Built Controller
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
.cc.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $#
clean:
$(RM) *.o $(MAIN)
It's compiling the first .cc file it finds "-c Controller.cc -o *.o" which make sense but that's all it's compiling and I get a *.o output file, not a Controller.o file. It does not compile any other files.
Here's one problem:
SRCS = *.cc
Make doesn't understand wildcards without the wildcard function:
SRCS = $(wildcard *.cc)
That should get it working; we can make minor improvements later.

Makefile - Generate Targets from Sources

I'm trying to build a growing number of .cpp files with the use of make. They all reside in a subdirectory src/. I want to compile each file into it's own executable, residing in bin/.
This is what I have tried so far, but it doesn't work, and since I'm new to make, all the Patterns, Variables etc. make it difficult to pinpoint what gets expanded into what and so on.
CXX = g++
CXXFLAGS = -Wall -Wextra -pedantic
SRC = $(wildcard src/*.cpp)
BIN = $(patsubst src/%.cpp,bin/%,$(SRC))
all: $(BIN)
%: scr/%.cpp
$(CXX) $(CXXFLAGS) $< -o $#
Also, is there a way to show just the contents of BIN for example to allow me to see what is going on?
This is what your final expansion looks like
file: scr/bin/file.cpp
Why not do this?
BIN = $(patsubst src/%.cpp,%,$(SRC))
all: $(addprefix bin/, $(BIN))
bin/% : src/%
$(GCC) $(FLAGS) $< -o $#
I think that works?
As for showing the contents of BIN
all: $(addprefix bin/, $(BIN))
#echo $(BIN)

Resources