Skip to content

Commit

Permalink
m version 2.4.0
Browse files Browse the repository at this point in the history
Major Changes:

+ Added Generation Support that relies on Jinja
+ Add project template generation for CMake, Meson, and Rust

Bug Fixes:

+ Python can now pass command line arguments
  • Loading branch information
robertu94 committed Nov 3, 2020
1 parent 4d75139 commit 85eaeda
Show file tree
Hide file tree
Showing 17 changed files with 411 additions and 10 deletions.
2 changes: 1 addition & 1 deletion m/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from .plugins.Base import MBuildTool


MODES = ('build', 'clean', 'configure', 'test', 'install', 'settings', 'run', 'bench', 'tidy', 'format')
MODES = ('build', 'clean', 'configure', 'test', 'install', 'settings', 'run', 'bench', 'tidy', 'format', 'generate')

def make_abbreviations(mode):
"""creates a list of abbreviations for a given mode
Expand Down
8 changes: 8 additions & 0 deletions m/plugins/Base.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ def bench(self, settings):
"""runs the provided target"""
raise NotProvidedError("bench", self)

def generate(self, settings):
"""runs the provided target"""
raise NotProvidedError("generate", self)

def get_settings_factory(self, cls=None, priority=Setting.DEFAULT):
"""returns a helper function that fills in commmon arguments on the Setting object"""
if cls is None:
Expand Down Expand Up @@ -320,6 +324,10 @@ def settings(self):
for value in self._settings.values():
print(value)

def generate(self):
"""delgates to the right run function"""
self._run_action("settings")
self._run_action("generate")



Expand Down
65 changes: 62 additions & 3 deletions m/plugins/CMake.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from subprocess import run, DEVNULL
from subprocess import run, DEVNULL, PIPE
from .Base import plugin, BasePlugin, PluginSupport

import json
from jinja2 import Environment, PackageLoader, select_autoescape

@plugin
class CMakePlugin(BasePlugin):
Expand Down Expand Up @@ -88,6 +89,63 @@ def install(self, settings):
else:
print("failed to configure")

def generate(self, settings):
g_settings = settings['cmdline_generate'].value
if (not g_settings) or g_settings[0].startswith("l"):
self._generate_library(settings)
elif g_settings[0].startswith("b"):
self._generate_binary(settings)
else:
print("unknown options", *g_settings)

def _prepare_template(self, settings):
cmake_version_p = run(["cmake", "-E", "capabilities"], stdout=PIPE, stderr=PIPE)
cmake_version = json.loads(cmake_version_p.stdout)['version']['string']

env = {
"cmake_version_str": cmake_version,
"repo_name": settings['repo_base'].value.name
}
template_env = Environment(
loader=PackageLoader('m', 'templates'),
autoescape=select_autoescape(['html', 'xml'])
)

def templater(template_name, template_dest):
template = template_env.get_template(template_name)
render = template.render(**env)
with open(template_dest, 'w') as outfile:
outfile.write(render)

return templater, env

def _generate_library(self, settings):
templater, env = self._prepare_template(settings)
(settings['repo_base'].value / "test").mkdir(exist_ok=True, parents=True)
(settings['repo_base'].value / "include").mkdir(exist_ok=True, parents=True)
(settings['repo_base'].value / "src").mkdir(exist_ok=True, parents=True)
(settings['repo_base'].value / "src" / (env['repo_name'] + ".cc")).touch()
(settings['repo_base'].value / "include" / (env['repo_name'] + ".h")).touch()
templater("cpp/CMakeListsLibrary.txt.j2", settings['repo_base'].value / "CMakeLists.txt")
templater("cpp/library_name.pc.in.j2", settings['repo_base'].value / (env['repo_name'] + ".pc.in"))
templater("cpp/repo_name_version.h.in.j2", settings['repo_base'].value / "src" / (env['repo_name'] + "_version.h.in"))
templater("cpp/CMakeListsTests.txt.j2", settings['repo_base'].value /"test"/ "CMakeLists.txt")
templater("cpp/GTestCMakeLists.txt.in.j2", settings['repo_base'].value /"test"/ "GTestCMakeLists.txt.in")
templater("cpp/test.cc.j2", settings['repo_base'].value /"test"/ ("test_" + env['repo_name'] + ".cc"))

def _generate_binary(self, settings):
templater, env = self._prepare_template(settings)
(settings['repo_base'].value / "test").mkdir(exist_ok=True, parents=True)
(settings['repo_base'].value / "include").mkdir(exist_ok=True, parents=True)
(settings['repo_base'].value / "src").mkdir(exist_ok=True, parents=True)
(settings['repo_base'].value / "include" / (env['repo_name'] + ".h")).touch()
templater("cpp/binary_name.cc.j2", settings['repo_base'].value /"src"/ (env['repo_name'] + ".cc"))
templater("cpp/CMakeListsBinary.txt.j2", settings['repo_base'].value / "CMakeLists.txt")
templater("cpp/repo_name_version.h.in.j2", settings['repo_base'].value / "src" / (env['repo_name'] + "_version.h.in"))
templater("cpp/CMakeListsTests.txt.j2", settings['repo_base'].value /"test"/ "CMakeLists.txt")
templater("cpp/GTestCMakeLists.txt.in.j2", settings['repo_base'].value /"test"/ "GTestCMakeLists.txt.in")
templater("cpp/test.cc.j2", settings['repo_base'].value /"test"/ ("test_" + env['repo_name'] + ".cc"))

@staticmethod
def _supported(settings):
"""returns a dictionary of supported functions"""
Expand All @@ -102,6 +160,7 @@ def _supported(settings):
"build": state,
"test": state,
"clean": state,
"install": state
"install": state,
"generate": PluginSupport.NOT_ENABLED_BY_DEFAULT,
}

6 changes: 6 additions & 0 deletions m/plugins/Meson.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ def install(self, settings):
else:
print("failed to configure")

def generate(self, settings):
"""generates a blank project"""
run(["meson", "init", *settings['cmdline_generate'].value], cwd=settings['repo_base'].value)


@staticmethod
def _supported(settings):
"""returns a dictionary of supported functions"""
Expand All @@ -98,5 +103,6 @@ def _supported(settings):
"install": state,
"tidy": state,
"bench": state,
"generate": PluginSupport.NOT_ENABLED_BY_DEFAULT,
}

8 changes: 4 additions & 4 deletions m/plugins/Python.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ class PythonSetupToolsPlugin(BasePlugin):

def build(self, settings):
"""compiles the source code or a subset thereof"""
run(["python", "setup.py", "build"], cwd=settings['repo_base'].value)
run(["python", "setup.py", "build", *settings['cmdline_build'].value], cwd=settings['repo_base'].value)

def test(self, settings):
"""runs automated tests on source code or a subset there of"""
run(["python", "setup.py", "test"], cwd=settings['repo_base'].value)
run(["python", "setup.py", "test", *settings['cmdline_test'].value], cwd=settings['repo_base'].value)

def clean(self, settings):
"""cleans source code or a subset there of"""
run(["python", "setup.py", "clean"], cwd=settings['repo_base'].value)
run(["python", "setup.py", "clean", *settings['cmdline_clean'].value], cwd=settings['repo_base'].value)

def install(self, settings):
"""cleans source code or a subset there of"""
run(["python", "setup.py", "install"], cwd=settings['repo_base'].value)
run(["python", "setup.py", "install", *settings['cmdline_install'].value], cwd=settings['repo_base'].value)


@staticmethod
Expand Down
4 changes: 4 additions & 0 deletions m/plugins/Rust.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ def bench(self, settings):
"""runs the binary"""
run(["cargo", "bench", *settings['cmdline_bench'].value], cwd=settings['repo_base'].value)

def generate(self, settings):
run(["cargo", "init", *settings['cmdline_generate'].value], cwd=settings['repo_base'].value)

@staticmethod
def _supported(settings):
"""returns a dictionary of supported functions"""
Expand All @@ -56,5 +59,6 @@ def _supported(settings):
"format": state,
"tidy": state,
"bench": state,
"generate": PluginSupport.NOT_ENABLED_BY_DEFAULT,
}

Empty file added m/templates/__init__.py
Empty file.
95 changes: 95 additions & 0 deletions m/templates/cpp/CMakeListsBinary.txt.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
## template for a CMake C++ Library
# vim: ft=cmake :
cmake_minimum_required(VERSION 3.14)
project({{repo_name}} VERSION "0.0.1" LANGUAGES CXX)

#correct was to set a default build type
# https://blog.kitware.com/cmake-and-the-default-build-type/
set(default_build_type "Release")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "No build type was set. Setting build type to ${default_build_type}.")
set(CMAKE_BUILD_TYPE ${default_build_type} CACHE
STRING "Choose the type to build" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif()

include(CTest)
include(GNUInstallDirs)
include(CheckCXXCompilerFlag)

#compiler flags and standard conformance checks
check_cxx_compiler_flag("-fno-omit-frame-pointer" HAVE_NO_OMIT_FRAME_POINTER)
set(NO_OMIT_FRAME_POINTER_FLAG "")
if(HAVE_NO_OMIT_FRAME_POINTER)
set(NO_OMIT_FRAME_POINTER_FLAG "-fno-omit-frame-pointer")
endif()


set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

option(BUILD_SHARED_LIBS "build {{repo_name}} as a shared library" ON)

add_executable({{repo_name}}
./src/{{repo_name}}.cc
./include/{{repo_name}}.h
)
target_compile_features({{repo_name}} PUBLIC cxx_std_17)
target_include_directories({{repo_name}}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/{{repo_name}}>
)
target_compile_options({{repo_name}} PRIVATE
$<$<CONFIG:Debug>: -Wall -Werror -Wextra -Wpedantic>
$<$<CONFIG:RelWithDebInfo>: ${NO_OMIT_FRAME_POINTER_FLAG}>
)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/src/{{repo_name}}_version.h.in
${CMAKE_CURRENT_BINARY_DIR}/include/{{repo_name}}_version.h
)

install(TARGETS {{repo_name}} EXPORT library_name
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

if(BUILD_TESTING)
add_subdirectory(test)
endif()

option(USE_CLANG_TIDY "include clang-tidy warnings in the build log" OFF)
if(USE_CLANG_TIDY)
find_program(CLANG_TIDY clang-tidy)
set_target_properties({{repo_name}} PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY}")
set_target_properties({{repo_name}} PROPERTIES C_CLANG_TIDY "${CLANG_TIDY}")
endif()

option(USE_INCLUDE_WHAT_YOU_USE "include include-what-you-use warnings in the build log" OFF)
if(USE_INCLUDE_WHAT_YOU_USE)
find_program(INCLUDE_WHAT_YOU_USE include-what-you-use)
set_target_properties({{repo_name}} PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "${INCLUDE_WHAT_YOU_USE}")
set_target_properties({{repo_name}} PROPERTIES C_INCLUDE_WHAT_YOU_USE "${INCLUDE_WHAT_YOU_USE}")
endif()


option(BUILD_DOCS "build the documentation" OFF)
if(BUILD_DOCS)
find_package(Doxygen REQUIRED dot)
set(DOXYGEN_MAN_LINKS YES)
set(DOXYGEN_GENERATE_MAN YES)
set(DOXYGEN_GENERATE_HTML YES)
set(DOXYGEN_EXTRACT_LOCAL_METHODS YES)
set(DOXYGEN_EXTRACT_STATIC YES)
set(DOXYGEN_MACRO_EXPANSION YES)
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE README.md)
doxygen_add_docs(
docs
${PROJECT_SOURCE_DIR}/README.md
${PROJECT_SOURCE_DIR}/include
COMMENT "Generate Documenation"
)
endif()

107 changes: 107 additions & 0 deletions m/templates/cpp/CMakeListsLibrary.txt.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
## template for a CMake C++ Library
cmake_minimum_required(VERSION 3.14)
project({{repo_name}} VERSION "0.0.1" LANGUAGES CXX)

#correct was to set a default build type
# https://blog.kitware.com/cmake-and-the-default-build-type/
set(default_build_type "Release")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "No build type was set. Setting build type to ${default_build_type}.")
set(CMAKE_BUILD_TYPE ${default_build_type} CACHE
STRING "Choose the type to build" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif()

include(CTest)
include(GNUInstallDirs)
include(CheckCXXCompilerFlag)

#compiler flags and standard conformance checks
check_cxx_compiler_flag("-fno-omit-frame-pointer" HAVE_NO_OMIT_FRAME_POINTER)
set(NO_OMIT_FRAME_POINTER_FLAG "")
if(HAVE_NO_OMIT_FRAME_POINTER)
set(NO_OMIT_FRAME_POINTER_FLAG "-fno-omit-frame-pointer")
endif()


set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

option(BUILD_SHARED_LIBS "build {{repo_name}} as a shared library" ON)

add_library({{repo_name}}
./src/{{repo_name}}.cc
./include/{{repo_name}}.h
)
target_compile_features({{repo_name}} PUBLIC cxx_std_17)
target_include_directories({{repo_name}}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/{{repo_name}}>
)
target_compile_options({{repo_name}} PRIVATE
$<$<CONFIG:Debug>: -Wall -Werror -Wextra -Wpedantic>
$<$<CONFIG:RelWithDebInfo>: ${NO_OMIT_FRAME_POINTER_FLAG}>
)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/src/{{repo_name}}_version.h.in
${CMAKE_CURRENT_BINARY_DIR}/include/{{repo_name}}_version.h
)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/{{repo_name}}.pc.in
${CMAKE_CURRENT_BINARY_DIR}/{{repo_name}}.pc
@ONLY
)

export(TARGETS {{repo_name}} NAMESPACE {{repo_name}}:: FILE {{repo_name}}.cmake)
install(TARGETS {{repo_name}} EXPORT {{repo_name}}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(EXPORT {{repo_name}} NAMESPACE {{repo_name}}:: DESTINATION share/{{repo_name}}/cmake)
install(DIRECTORY include/ DESTINATION
${CMAKE_INSTALL_INCLUDEDIR}/{{repo_name}})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/{{repo_name}}_version.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/{{repo_name}})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/{{repo_name}}.pc DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pkgconfig)


if(BUILD_TESTING)
add_subdirectory(test)
endif()

option(USE_CLANG_TIDY "include clang-tidy warnings in the build log" OFF)
if(USE_CLANG_TIDY)
find_program(CLANG_TIDY clang-tidy)
set_target_properties({{repo_name}} PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY}")
set_target_properties({{repo_name}} PROPERTIES C_CLANG_TIDY "${CLANG_TIDY}")
endif()

option(USE_INCLUDE_WHAT_YOU_USE "include include-what-you-use warnings in the build log" OFF)
if(USE_INCLUDE_WHAT_YOU_USE)
find_program(INCLUDE_WHAT_YOU_USE include-what-you-use)
set_target_properties({{repo_name}} PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "${INCLUDE_WHAT_YOU_USE}")
set_target_properties({{repo_name}} PROPERTIES C_INCLUDE_WHAT_YOU_USE "${INCLUDE_WHAT_YOU_USE}")
endif()


option(BUILD_DOCS "build the documentation" OFF)
if(BUILD_DOCS)
find_package(Doxygen REQUIRED dot)
set(DOXYGEN_MAN_LINKS YES)
set(DOXYGEN_GENERATE_MAN YES)
set(DOXYGEN_GENERATE_HTML YES)
set(DOXYGEN_EXTRACT_LOCAL_METHODS YES)
set(DOXYGEN_EXTRACT_STATIC YES)
set(DOXYGEN_MACRO_EXPANSION YES)
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE README.md)
doxygen_add_docs(
docs
${PROJECT_SOURCE_DIR}/README.md
${PROJECT_SOURCE_DIR}/include
COMMENT "Generate Documenation"
)
endif()
# vim: ft=cmake :
Loading

0 comments on commit 85eaeda

Please sign in to comment.