Skip to content

Makefile macros library as an alternative of cmake

Notifications You must be signed in to change notification settings

sergeniously/makeup

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

makeup:
use makefiles in cmake manner

Introducing

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.

Features

  • 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)

Quick start

  1. 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 run make install command from the root directory of sources (it will automatically install makeup to the one of those directories).
  2. 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).
  3. Optionally fill makeup.mk project file with project-specific variables and options.
  4. Create Makefile and include makeup.mk file from inside of it.

Now, this new Makefile is ready to use all makeup features.

Example

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 ...

Documentation

Built-in targets

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.

Built-in variables

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
  • 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 in make 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.

Built-in functions

Here are some generic functions supported by makeup.

find_program

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:

  1. names: specify one or more possible names for the program.
  2. 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)

add_compile_options

Appends compile options to COMPILE_OPTIONS variable that is used by modules to compile binary targets.

Example:

$(call add_compile_options, -Wall -O2)

add_definitions

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)

include_directories

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))

add_link_options

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)

link_directories

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))

link_libraries

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)

add_binary_target

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:

  1. name: a target name to aggregate target files.
  2. file: a basename of a file that will be created in current binary directory.
  3. sources: a list of prerequisite source files for target file.
  4. comment: a comment to print of what is going to be done.
  5. command: a command to create binary target file.
  6. 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 $$@)

add_subdir_target

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:

  1. name: a target name that may be the same as a subdirectory name.
  2. 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)

add_test_directory

Appends a target to only perform a check target in subdirectory.

Example:

$(call add_test_directory,test)

add_test_program

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)

add_test_command

Adds a test command line to be run by make check.

Example:

$(call add_test_command,test-name,valgrind $(CURRENT_BINARY_DIR)/program)

To be continued...

About

Makefile macros library as an alternative of cmake

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published