Skip to content

gavr-vlad-s/murlyka

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Introduction

To build projects written on C and C++, various build system are used. The most famous build systems are CMake, GNU Make, Scons, Shake, and the system used to build the Boost libraries. Consider each of these build system.

System GNU Make takes a Makefile describing the build script of the project. Writing this script manually is not very convenient, if there are a lot of source files. The advantage of this system is that this system works both under Linux, and under Windows.

Systems SCons and CMake are wrappers over Make utility and generate input files for Make. System SCons is written in language Python 2.7, and has installing problem under Windows 7. There are no installing problems under Linux. The inability to work under Windows is disadvantage of this system. The Makefile generated by CMake system, are complicated and contains absolute paths to source files and to compiler. By default, CMake uses C++ compiler, which is standard for an operating system. Standard C++ compiler for Linux is g++ (a compiler from GCC collection). Standard C++ compiler for Windows is a compiler from Microsoft Visual Studio. However, Visual Studio compiler does not fully support recent standards of C++ language, unlike the compiler of the GCC collection. Hence, it is better to use g++ under Windows. But, under Windows, in order for CMake used g++ and the needed keys of g++, you need to write a long chain of command-line arguments. As for Linux, then, in addition to the compiler from collection GCC can be installed, for example, compilers of a set of Clang. Under Linux, in order for CMake used clang, you need to write a long chain of command-line arguments. The build system for the Boost libraries is not recommended by an author of one of Boost library, because it is difficult to use this build system.

The build system Shake is written in Haskell, and requires installed system Haskell Stack. But Haskell Stack does not work under Linux. The purpose of the system Haskell Stack is to write Makefiles as programs in Haskell, then to compile them by Haskell compiler, and to run resulting program. Resulting program will build the needed project. To use in C++ projects, is is disadvatage. Therefore, we need a more simple build system. It is the goal of the project Murlyka.

Input file format

Input file consists of an arbitrary sequence the following commands (this sequence can be empty):

  • project(project_name main_file)

  • compiler(compiler_name)

  • compiler_flags(compiler_flags)

  • linker(linker_name)

  • linker_flags(linker_flags)

  • source_dir(directory_with_source_files)

  • source_exts(source_files_extensions)

  • build_dir(directory_for_object_files_and_for_program)

  • include_dirs(list_of_directories_for_header_files)

  • makefile_name(name_for_Makefile)

  • libraries(list_of_linked_libraries)

  • library_dirs(directory_lst_to_search_libraries)

Command project specifies the project name and the name of the main file (i.e. the name of the file containing function 'main'). The name of the main file is optional. The default name of the main file is the project name with prepended extension cpp. If command project is not specified, then the name of the main file is 'main.cpp' and the project name is 'main'.
Command compiler specifies a used compiler name. The default compiler name is 'g++'.
Command compiler_flags specifies the compiler flags. The default compiler flags are '-O3 -Wall -std=c++14'.
Command linker defines the linker name. The default linker name is the compiler name.
Command linker_flags specifies the linker flags. The default flags is '-s'.
Command source_dir specifies the directory with source code (files with extensions cpp, c++, cxx). The default directory is the current directory.
Command source_exts specifies source files extensions (fextensions cpp, c++, cxx, and so on, except header files extensions).
Command build_dir specifies a directory with object files and with an executable file. If this command is not specified, the object files and an executable file will be in the root directory of the project.
Command include_dirs specifies the location of header files for external libraries.
Command makefile_name specifies the name of the generated Makefile. The default name of Makefile is Makefile.
Command libraries specifies a quoted list of names linked libraries, separated by whitespace chars (i.e. spaces and tabulations). Name format is as follows: you should not include the prefix lib and the suffix .a.
Command library_dirs specifies a quoted list of paths for external libraries search.

Here project_name, name_for_Makefile, compiler_name, linker_name are identifiers. All other arguments are string literals. Here an identifier is any non-empty sequence of Latin letters, decimal digits, characters '+' and '-', underscore and dot; string literal is any (including empty) sequence of characters enclosed in double quotes. If in a string literal you need to specify a double quote, it should be doubled.
A string literal that is the value of the argument of the command source_exts is a list of source code files extensions, delimited by whitespace characters. Extensions must be specified without begin point.

The argument of the command include_dirs contains a list separated by semicolons paths to directories containing header files for external libraries.

The argument of the command library_dirs contains a list separated by semicolons paths to directories containing external libraries.

Examples

Let us give examples of the program Murlyka using.

Example 1.

Let 'simple01' be a project with the following structure:

simple01  
	func1.cpp  
	func1.h  
	func2.cpp  
	func2.h  
	simple01.cpp  
	build

Suppose that the main file is the file 'simple01.cpp", and the build directory is the directory 'build'. If we put a file (for example, a file with the name 'mkdescr.txt') in the project root directory, and this file has the following contents

project(simple01)
compiler(g++)
linker(g++)
source_exts("cpp")
build_dir("build")

then after processing this file, we will get a Makefile with the following contents:

LINKER      = g++  
LINKERFLAGS = -s  
CXX         = g++  
CXXFLAGS    = -O3 -Wall -std=c++14  
BIN         = simple01  
vpath %.o build  
OBJ         = simple01.o func2.o func1.o  
LINKOBJ     = simple01.o func2.o func1.o  

.PHONY: all all-before all-after clean clean-custom

all: all-before $(BIN) all-after

clean: clean-custom   
	rm -f ./build/*.o  
	rm -f ./build/$(BIN)

.cpp.o:  
	$(CXX) -c $< -o $@ $(CXXFLAGS) 

$(BIN):$(OBJ)  
	$(LINKER) -o $(BIN) $(LINKOBJ) $(LINKERFLAGS)  
	mv $(BIN) $(OBJ) ./build

Example 2.

Let 'simple02' be a project with the following structure:

simple02  
	build  
	include  
		func1.h  
		func2.h  
	src  
		func1.cpp  
		func2.cpp  
		simple02.cpp

In other words, files with the file extension .h located in the directory 'include', and the files with the extension .cpp in the directory 'src'. Suppose that the main file is the file 'simple01.cpp", and the build directory is the directory 'build'. If we put a file (for example, a file with the name 'mkdescr.txt') in the project root directory, and this file has the following contents

project(simple02)
compiler(g++)
linker(g++)
source_exts("cpp")
source_dir("src")
build_dir("build")

then after processing this file, we will get a Makefile with the following contents:

LINKER           = g++  
LINKERFLAGS      = -s  
COMPILER         = g++  
COMPILERFLAGS    = -O3 -Wall -std=c++14  
BIN              = simple02  
vpath %.cpp src  
vpath %.o build  
OBJ              = simple02.o func2.o func1.o  
LINKOBJ          = build/simple02.o build/func2.o build/func1.o  

.PHONY: all all-before all-after clean clean-custom

all: all-before $(BIN) all-after

clean: clean-custom  
	rm -f ./build/*.o  
	rm -f ./build/$(BIN)  

.cpp.o:  
	$(CXX) -c $< -o $@ $(CXXFLAGS)   
	mv $@ ./build

$(BIN):$(OBJ)  
	$(LINKER) -o $(BIN) $(LINKOBJ) $(LINKERFLAGS)  
	mv $(BIN) ./build

Command line syntax

Command line syntax for Murlyka is

$ murlyka option

or

$ murlyka files

Here 'option' is either --help, or --version. First of them displays help, second of them displays version info; 'files' are processed configuration files.

Building of Murlyka project

To build this project, you need to install Haskell Platform. Suppose that you installed Haskell Platform; then to build the project Murlyka, you need

$ git clone https://github.com/gavr-vlad-s/murlyka
$ cd murlyka
$ cabal configure
$ cabal build

Installing Haskell

For Windows

  1. Download installer from https://www.haskell.org/downloads.
  2. Run downloaded installer.

For Debian and Debian-based Linux

Execute the following command:

$ sudo apt-get install haskell-platform

For Arch Linux and for Arch-based Linux (e.g., Manjaro Linux)

Execute the following command:

$ sudo pacman -S ghc cabal-install haskell-haddock-api haskell-haddock-library happy alex

About

Build system for programs in C or C++ programming lanuage

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Haskell 100.0%