common.mk
is a centralized Makefile providing a large number of features that ease regular development:
In addition, common.mk
systems are fully parallelizable for all targets avoiding truncated file issues while still utilizing bigsmp systems as completely as possible.
A new project should create a top-level Makefile and after the boilerplate, include common.mk
. After doing so, they may define their targets as usual. If there are subdirectories, they will be pulled in automatically if they contain a module.mk
file. This file will be just like the top-level Makefile except that all targets and dependencies should be referred to by their relative path to the top-level src. E.g., lib/foo.o
instead of just foo.o
.
The Makefile may be called from the source directory with just make
or from any other location with make -C /path/to/source
. If the build artifacts should live somewhere other than $PWD/build-$MODE
, then it may be called with make -C /path/to/source OUT=$PWD
, for instance. In addition to OUT
and MODE
, there are several commandline variables which may be set. See the comment in common.mk
for full explanation and defaults.
example/
contains a fully working example of a make hierarchy that explores all the different ways common.mk
can be used.
This section is a brief recipe book to some common activities, but you should consult the common.mk
file for detailed information. In these recipes replace <text>
with the appropriate text for your situation. These recipes assume that you have organized your Makefile along the lines of the other recipes, i.e. the add flag recipe assumes your targets follow the add target recipes.
For libraries these recipes assume that you want to build the PIE versions of libraries. You have the option of building PIC versions by replacing where .pie.
is used with .pic.
. One of these must be present, since common.mk
is looking to parse these out and there isn't a default behaviour.
<target>_FLAGS =
line or add a line <target>_FLAGS += flag
.-l<library>
to <target>_LIBS =
line or add a line <target>_LIBS += -l<library>
.<target>_DEPS
exists:pkg_config
name of the dependency to the <target>_DEPS =
line.<target>_DEPS
does not exist:<target>_DEPS =
line before the related FLAGS
and LIBS
lines, with the proper pkg_config
name of your dependency.<target>_FLAGS =
to <target>_FLAGS :=
and add $(shell $(PKG_CONFIG) --cflags $(<target>_DEPS))
to the line.<target>_LIBS =
to <target>_LIBS :=
and add $(shell $(PKG_CONFIG) --libs $(<target>_DEPS))
to the line.<filename>.cc
to a existing target:<filename>.o
to <target>_OBJS
.CXX_STATIC_LIBRARY(lib<library>.pie.a)
to the dependencies of CXX_BINARY(<binary>)
.<target>_DEPS =
line with dependency list<target>_FLAGS =
line with flags list.<target>_LIBS =
line with library list.<target>_OBJS =
line with object list. The object list is composed of the .cc
source files that are needed for the target, with .o
replacing the .cc
.CXX_BINARY(<target>): $(<target>_OBJS) ...
line. This line should have any library dependencies that are built in this file included on it. How to do this is discussed above.CXX_BINARY(<target>): CPPFLAGS += $(<target>_FLAGS) CXX_BINARY(<target>): LDLIBS += $(<target>_LIBS) clean: CLEAN(<target>) all: CXX_BINARY(<target>)
It is assumed there is a binary or library target that defines the environment.
<target>_FLAGS =
line with $(<parent>_FLAGS)
and any other needed flags.<target>_LIBS =
line with $(<parent>_LIBS) -lgtest -lgmock
and other needed libs.<target>_OBJS> =
line with the objects for the unit tests`CXX_BINARY(<target>): $(<target>_OBJS) ...
line. This line should have any library dependencies that are built in this file included on it. How to do this is discussed above.CXX_BINARY(<target>): CPPFLAGS += $(<target>_FLAGS) CXX_BINARY(<target>): LDLIBS += $(<target>_LIBS) clean: CLEAN(<target>) tests: TEST(CXX_BINARY(<target>))
<target>_DEPS =
line with dependency list<target>_FLAGS =
line with flags list.<target>_LIBS =
line with library list.<target>_OBJS =
line with object list. The object list is composed of the .cc
source files that are needed for the target, with .o
replacing the .cc
.CXX_STATIC_LIBRARY(lib<target>.pie.a): $(<target>_OBJS) ...
line.CXX_STATIC_LIBRARY(<target>): CPPFLAGS += $(<target>_FLAGS) CXX_STATIC_LIBRARY(<target>): LDLIBS += $(<target>_LIBS) clean: CLEAN(<target>)
<protobuf>.pb.cc
to <package>_PROTO_BINDINGS =
line or add a line <package>_PROTO_BINDINGS += <protobuf>.pb.cc
.<target>.o.depends: <protobuf>.pb.cc
<target>.o.depends: <protobuf>.pb.h
<package>_PROTO_BINDINGS = <package>_PROTO_PATH = $(SYSROOT)/<installed location of .proto files> <package>_PROTO_HEADERS = $(patsubst %.cc,%.h,$(<package>_PROTO_BINDINGS)) <package>_PROTO_OBJS = $(patsubst %.cc,%.o,$(<package>_PROTO_BINDINGS)) $(<package>_PROTO_HEADERS): %.h: %.cc ; $(<package>_PROTO_BINDINGS): %.pb.cc: $(<package>_PROTO_PATH)/%.proto $(PROTOC) --proto_path=$(<package>_PROTO_PATH) --cpp_out=. $< clean: CLEAN($(<package>_PROTO_BINDINGS)) clean: CLEAN($(<package>_PROTO_HEADERS)) clean: CLEAN($(<package>_PROTO_OBJS)) # Add rules for compiling generated protobuffer code, as the CXX_OBJECTS list # is built before these source files exists and, as such, does not contain # them. $(eval $(call add_object_rules,$(<package>_PROTO_OBJS),CXX,cc))
If you have added in protocol buffer definitions directly to the package you are working in, go undo that and figure out where they should actually go. If you are really sure they should be in your package you are a bit on your own, please feel free to contact chromium-os-dev@chromium.org.