Skip to content

Commit

Permalink
Merge pull request #16 from ericsonj/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
ericsonj committed Apr 27, 2021
2 parents 790e3f1 + 0412ce6 commit bb4c9b4
Show file tree
Hide file tree
Showing 13 changed files with 506 additions and 54 deletions.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,33 @@ Install pymaketool:
$ pip3 install pymaketool
```

Create new basic C project.
```bash
$ pynewproject CLinuxGCC
(author) Your name: Ericson
(project_name) Your project name: hello

$ cd hello

hello$ make clean

hello$ make

hello$ ./Release/hello
```
Note: this example use **EclipseAddon** by default, pymaketool generate files *.setting/language.settings.xml* and *.cproject*.

## Quick start in Docker

Pull imagen and run container:
```bash
$ docker pull ericsonjoseph/pymaketool

$ docker run -it ericsonjoseph/pymaketool

ubuntu@$ pynewproject CLinuxGCC
```

## Quick Info

**pymaketool** process modules of code like objects. These objects ware define by files **_mk.py*. With Python you can code how to discover and get source files and include paths, e.g.:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
author = 'Ericson Joseph'

# The full version, including alpha/beta/rc tags
release = '2.0.2'
release = '2.0.3'

version = release

Expand Down
11 changes: 10 additions & 1 deletion pymakelib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from abc import ABC,abstractmethod
import logging
from logging import Logger as SysLogger
from typing import List

FORMATTER = logging.Formatter("%(levelname)-8s%(filename)s:%(lineno)d %(message)s")

Expand Down Expand Up @@ -77,7 +78,7 @@ class MKVARS():
SIZE = '$(SIZE)'
TARGET = '$(TARGET)'
PROJECT = '$(PROJECT)'
STATIC_LIBS = '$(addprefix -L,$(dir $(SLIBS_OBJECTS))) $(addprefix -l,$(SLIBS_NAMES))'
STATIC_LIBS = '$(SLIBS_NAMES)'

def MOD_PATH(wk):
return wk['modPath']
Expand Down Expand Up @@ -144,6 +145,7 @@ def getProjectInstance() -> AbstractMake:
from pathlib import Path
import copy
from . import prelib as plib
from . import module
import sys

class Pymaketool():
Expand All @@ -163,4 +165,11 @@ def readModules(self, modulesPaths) -> list:
for filename in modulesPaths:
mod = plib.readModule(filename, copy.deepcopy(self.compilerOpts), None)
self.modules.extend(mod)
return self.modules

def read_modules(self, modulesPaths) -> List[module.AbstractModule]:
self.modules = []
for filename in modulesPaths:
mod = plib.read_module(filename, copy.deepcopy(self.compilerOpts), None)
self.modules.extend(mod)
return self.modules
185 changes: 185 additions & 0 deletions pymakelib/generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
from os import write
from pathlib import Path
from . import Define as D
from . import preconts as K
from . import Pymaketool
from .module import AbstractModule, StaticLibraryModule
from . import Logger
from abc import ABC, abstractmethod

from pymakelib import module

log = Logger.getLogger()

def getLineSeparator(key: str, num: int):
header = ''
for _ in range(num):
header += key
return header

def macrosDictToString(macros):
mstr = []
if isinstance(macros, dict):
for key in macros:
if macros[key] != None and macros[key] != '':
if isinstance(macros[key], str):
mstr.append('-D{}=\\\"{}\\\"'.format(key, macros[key]))
elif isinstance(macros[key], bool):
mstr.append(
'-D{}={}'.format(key, '1' if macros[key] else '0'))
elif isinstance(macros[key], D):
mstr.append(
'-D{}={}'.format(key, macros[key].getDefine()))
else:
mstr.append('-D{}={}'.format(key, macros[key]))
else:
mstr.append('-D{}'.format(key))

return ' '.join(mstr)


class Generator(ABC):

def __init__(self, module: AbstractModule, project: Pymaketool):
self.module = module
self.project = project
self.output = []

@abstractmethod
def process(self) -> str:
pass

class MakeGenerator(Generator):

def __init__(self, module, project: Pymaketool):
super().__init__(module, project)
self.isstaticlib = isinstance(module, StaticLibraryModule)
if self.isstaticlib:
mod:StaticLibraryModule = module
mod.decorate_module()

def write(self, value):
self.output.append(value)

def get_srcs_dirs(self, srcs) -> list:
dirs = []
for src in srcs:
dirs.append(Path(str(src)).parent)
dirs = list(set(dirs))
return dirs

def compiler_opts2str(self, compiler_opts):
mstr = []
def proc(moduleCompileOps):
if isinstance(moduleCompileOps, dict):
for key in moduleCompileOps:
if key == 'TARGETS':
continue
if (key == K.COMPOPTS_MACROS_KEY and isinstance(moduleCompileOps[key], dict)):
macros = macrosDictToString(moduleCompileOps[key])
mstr.append(macros)
else:
mstr.append(' '.join(moduleCompileOps[key]))

elif isinstance(moduleCompileOps, list):
for item in moduleCompileOps:
mstr.append(item)

if isinstance(compiler_opts, dict):
proc(compiler_opts)
elif isinstance(compiler_opts, list):
for moduleCompileOps in compiler_opts:
proc(moduleCompileOps)

rmstr = list(filter(lambda item: item, mstr))
rmstr = ' '.join(rmstr)
rmstr = ' '.join(rmstr.split())
log.debug(f"compiler options: {rmstr}")
return rmstr

def write_header(self):
mod_path = f"{self.module.path}"
self.write("{}\n".format(getLineSeparator('#', 52)))
self.write("#{0:^50}#\n".format(mod_path))
self.write("{}\n".format(getLineSeparator('#', 52)))
self.write("\n")

def write_srcs(self):
prefixSrcs = ""
if self.isstaticlib:
prefixSrcs = self.module.name.upper() + "_"
srcs = self.module.getSrcs()
for src in srcs:
if str(src).endswith('.c'):
self.write("{}CSRC += {}\n".format(prefixSrcs, src))
elif str(src).endswith('.cpp'):
self.write("{}CXXSRC += {}\n".format(prefixSrcs, src))
elif str(src).endswith('.s'):
self.write("{}ASSRC += {}\n".format(prefixSrcs, src))
self.write('\n') if srcs else None

def write_incs(self):
incs = self.module.getIncs()
for inc in incs:
if inc:
self.write("INCS += -I{}\n".format(inc))
self.write('\n') if incs else None

def write_compiler_opts(self):
proj_settings = self.project.projSettings;
comp_opts = self.module.getCompilerOpts()
if comp_opts:
srcs = self.module.getSrcs()
isstatic = self.isstaticlib
for src in srcs:
if isstatic:
objs = str(src).replace('.c', '.o').replace('.s', '.o')
outputObj = '$({}_OUTPUT)/'.format(self.module.key) + str(objs)
self.write("{} : CFLAGS = {}\n".format(str(outputObj), self.compiler_opts2str(comp_opts)))
else:
objs = str(src).replace('.cpp', '.o')
objs = objs.replace('.c', '.o')
objs = objs.replace('.s', '.o')
ouputobj = Path(str(proj_settings['FOLDER_OUT']) + '/' + str(objs))
log.debug(ouputobj)
self.write("{} : CFLAGS = {}\n".format(str(ouputobj), self.compiler_opts2str(comp_opts)))


def write_staticlib_def(self):
mod: StaticLibraryModule = self.module
log.debug(f"module \'{mod.path}\' static library name {mod.name}")
log.debug(f"module \'{mod.path}\' static output directory {mod.output_dir}")
self.write('{}_NAME = {}\n'.format(mod.key, mod.name))
self.write('{}_OUTPUT = {}\n'.format(mod.key, str(mod.output_dir)))
library = mod.output_dir / Path('lib'+mod.name+'.a')
self.write('{}_AR = {}\n'.format(mod.key, str(library)))
self.write('\n')

def write_staticlib_rules(self):
mod: StaticLibraryModule = self.module
self.write('{0}'.format(mod.objects))
self.write('\n\n' if mod.objects else '')
self.write('{}'.format(mod.rule))
self.write('\n\n' if mod.rule else '')
self.write('{}\n'.format(mod.command))
self.write('\n\n')
self.write('SLIBS_NAMES += {}\n'.format(mod.linker))
self.write('SLIBS_OBJECTS += {}\n'.format(mod.library))
if mod.rebuild:
self.write('\n')
for src in mod.getSrcs():
obj = str(src).replace('.c', '.o').replace('.s', '.o')
outputObj = '$({}_OUTPUT)/'.format(mod.key) + str(obj)
self.write("{} : .FORCE\n".format(outputObj))
self.write('\n')

def process(self) -> str:
self.write_header()
if self.isstaticlib:
self.write_staticlib_def()
self.write_srcs()
self.write_incs()
self.write_compiler_opts()
if self.isstaticlib:
self.write_staticlib_rules()
return ''.join(self.output)

0 comments on commit bb4c9b4

Please sign in to comment.