makeup is a library of Makefile macros which helps and eases creating short Makefiles in cmake manner. Since it uses native Makefile features it is useful for those projects which are restricted to be upgraded for using external build system utilities such as cmake or so on.
- Provide cmake-like syntax of Makefiles
- Produce cmake-like colorful output of building
- Rebuild objects on Makefile change
- Rebuild objects on header files change
- Rebuild objects on dependencies change
- Create binaries in separate customized build directory so that:
- there is no need to go to build directory to run make (better than cmake)
- objects files are not mixed with source files (no need to clean before commit)
- Extendable by modules (allows to build any kind of binaries: java, python, etc)
- Allows to build Qt programs and libraries without using of .pro files (provided by Qt module)
- Allows to download and build third-party libraries (provided by ExternalProject module)
- Download these sources of makeup project and copy makeup directory to the one of following directories:
/usr/local/include
,/usr/include
or/usr/gnu/include
. Or better runmake install
command from the root directory of sources (it will automatically install makeup to the one of those directories). - Create makeup.mk file in the root of your project and place the line
include makeup/.mk
in the top of it (see makeup.mk). - Optionally fill makeup.mk project file with project-specific variables and options.
- Create Makefile and include makeup.mk file from inside of it.
Now, this new Makefile is ready to use all makeup features.
Here is an example of Makefile to build a simple C++ program which uses external json library (see demo/Makefile):
include ../makeup.mk
# Import module to deal with external sources
$(call import_modules,ExternalProject)
# Add, configure and build external project
$(call add_external_project,az-json,INCLUDE:headers BINARY:build/sources/libaz-json.a)
$(call clone_external_project,az-json,[email protected]:sergeniously/az-json.git,BRANCH:master)
$(call configure_external_project,az-json,cmake -B build)
$(call build_external_project,az-json,make -C build)
# Link external project to program
$(call include_directories,$(EPINC))
$(call link_directories,$(EPBIN))
$(call link_libraries,az-json)
# Build program
$(call add_program,makeup,main.cpp,DEPEND:az-json)
# Install external project and program
$(call install_external_project,az-json,,$(ROOT_INSTALL_DIR)/usr/local/lib)
$(call install_targets,makeup,$(ROOT_INSTALL_DIR)/usr/local/bin)
$(call install_command,touch makeup.cfg,$(ROOT_INSTALL_DIR)/etc,\
Pretending to create makeup configuration)
Now it is easy to build. Just run make all
command:
~/makeup/demo > make all
Configuring external project: az-json
Building external project: az-json
az-json is 100% done (see ~/makeup/build/EP/logs/az-json.log)
Compiling CPP-file: ~/makeup/demo/main.cpp
Building executable program: ~/makeup/build/demo/makeup
It is also ready for running make install
command:
~/makeup/demo > make install
Installing external project az-json in ~/makeup/install/usr/local/lib ...
Installing makeup in ~/makeup/install/usr/local/bin ...
Pretending to create makeup configuration in ~/makeup/install/etc ...
makeup implements some built-in targets for some special reasons:
-
help target prints some details about some available targets which are provided by Makefile in the current source directory.
-
all (default) target builds everything that can be built for the current source directory.
-
clean target deletes everything that was built for the current source directory.
-
install target installs built target files in DESTDIR directory.
-
check target runs test targets if there are such ones.
-
built target shows objects and binaries which are built for current source directory and its subdirectories.
Further details and another Makefile-dependent targets can be shown by make help
command. Feel free to use it every time you need help.
makeup provides some built-in variables which have special useful values:
-
ROOT_SOURCE_DIR
Contains an absolute path to the makeup.mk location. It is supposed to be a root directory of a project. -
ROOT_BINARY_DIR
Contains the absolute path of the root directory for building. By default it is set as <ROOT_SOURCE_DIR>/build, but can be changed in two ways:- specify BUILD_DIR in make command:
make all BUILD_DIR=dir
- override it in makeup/Project.mk file:
ROOT_BINARY_DIR=dir
- specify BUILD_DIR in make command:
-
ROOT_INSTALL_DIR
Contains an absolute path of the root directory to install target files. Default value is <ROOT_SOURCE_DIR>/install. Can be changed by specifying INSTALL_DIR or DESTDIR variables inmake install
command. -
CURRENT_SOURCE_DIR
It is a synonym for the standard Makefile variable CURDIR that is set to the absolute path of the current working (source) directory. -
CURRENT_BINARY_DIR
Contains the absolute path of the current building (binary) directory that responds to the current working directory. For example, if the current working directory equals to ROOT_SOURCE_DIR/demo, then the current building directory will be ROOT_BINARY_DIR/demo. There is also a short form of this variable: BINDIR.
Here are some generic functions supported by makeup.
Searches an executable program by names in specified paths or in default locations specified in system environment variable $PATH
and returns one found variant.
$(call find_program, names ..., [PATH:dir ...] [REQUIRED] [RECURSIVE])
Arguments:
- names: specify one or more possible names for the program.
- options:
- PATH:dir : specify directories to search in addition to the default locations.
- REQUIRED : stop processing Makefile with an error message if nothing is found.
- RECURSIVE : recursively search the program in specified paths (use carefully).
Example:
QMAKE=$(call find_program, qmake, PATH:/usr/lib/qt5 REQUIRED)
Appends compile options to COMPILE_OPTIONS variable that is used by modules to compile binary targets.
Example:
$(call add_compile_options, -Wall -O2)
Appends definitions to COMPILE_OPTIONS variable in NAME[=VALUE] form
Note: do not add them with -D prefixes as so they added automatically
Example:
$(call add_definitions, DEBUG PLATFORM=ANY)
Adds the given directories to those the compiler uses to search for include files. Relative paths are interpreted as relative to the current source directory. The given directories are added to COMPILE_OPTIONS variable with -I prefixes.
Example:
$(call include_directories, /usr/local/include $(EPINC))
Appends any options to LINK_OPTIONS variable that is used by modules to perform linking step for binary targets.
Example:
$(call add_link_options, -fPIC)
Adds the paths in which the linker should search for libraries. Relative paths are interpreted as relative to the current source directory. The given paths are added to LINK_OPTIONS variable with -L prefixes.
Example:
$(call link_directories, /usr/local/lib $(EPBIN))
Specifies libraries or flags to use when linking any targets created later. Also appends current binary path to those which have relative specifier.
Example:
$(call link_libraries, boost_system -l:libzip.a ../libany.so)
Universal function to create a binary target file. It is supposed to be used by modules to create executable programs or libraries.
$(call add_binary_target, name, file, sources ..., comment, command, [DEPEND:name ...] [EXCLUDE_FROM_ALL])
Arguments:
- name: a target name to aggregate target files.
- file: a basename of a file that will be created in current binary directory.
- sources: a list of prerequisite source files for target file.
- comment: a comment to print of what is going to be done.
- command: a command to create binary target file.
- options:
- DEPEND:name: additional dependency for target file.
- EXCLUDE_FROM_ALL: do not add the target to default all target.
Example:
$(call add_binary_target,foo,libfoo.a,foo.cpp,Building static library,g++ $$^ -o $$@)
Appends a target to build, clean, check or install targets in a subdirectory.
$(call add_subdir_target, name, [DIR:name] [DEPEND:name ...] [EXCLUDE_FROM_ALL])
Arguments:
- name: a target name that may be the same as a subdirectory name.
- options:
- DIR:name: specify subdirectory name or path if the target name must be different from the subdirectory name.
- DEPEND:name: additional dependency for target name.
- EXCLUDE_FROM_ALL: do not add the target to default all target.
Example:
$(call add_subdir_target,lib,DIR:src/lib EXCLUDE_FROM_ALL)
$(call add_subdir_target,bin,DIR:src/bin DEPEND:lib)
Appends a target to only perform a check target in subdirectory.
Example:
$(call add_test_directory,test)
Adds a test program to be run by make check
. The program is supposed to locate in the current binary directory. So the program must be created either directly by add_binary_target macro or by those macros which use this one, for example, add_program from Cpp module.
Example:
$(call add_test_program,test-name,program)
Adds a test command line to be run by make check
.
Example:
$(call add_test_command,test-name,valgrind $(CURRENT_BINARY_DIR)/program)