From f1afd44b2b2fb85de1c55408b46e50b4381f50d2 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Wed, 27 Dec 2017 23:40:15 +0200 Subject: [PATCH] Added C++ library sample. --- mesonbuild/minit.py | 147 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 143 insertions(+), 4 deletions(-) diff --git a/mesonbuild/minit.py b/mesonbuild/minit.py index 4ccd590ff..29b5056e6 100644 --- a/mesonbuild/minit.py +++ b/mesonbuild/minit.py @@ -21,12 +21,16 @@ from glob import glob lib_h_template = '''#pragma once #if defined _WIN32 || defined __CYGWIN__ #ifdef BUILDING_{utoken} - #define {utoken}_PUBLIC __attribute__ ((dllexport)) + #define {utoken}_PUBLIC __declspec(dllexport) #else - #define {utoken}_PUBLIC __attribute__ ((dllimport)) + #define {utoken}_PUBLIC __declspec(dllimport) #endif #else - #define {utoken}_PUBLIC __attribute__ ((visibility ("default"))) + #ifdef BUILDING_{utoken} + #define {utoken}_PUBLIC __attribute__ ((visibility ("default"))) + #else + #define {utoken}_PUBLIC + #endif #endif int {utoken}_PUBLIC {function_name}(); @@ -119,7 +123,8 @@ int main(int argc, char **argv) {{ hello_c_meson_template = '''project('{project_name}', 'c', version : '{version}', - default_options : ['warning_level=3']) + default_options : ['warning_level=3', + 'cpp_std=c++14']) exe = executable('{exe_name}', '{source_name}', install : true) @@ -151,6 +156,111 @@ exe = executable('{exe_name}', '{source_name}', test('basic', exe) ''' +lib_hpp_template = '''#pragma once +#if defined _WIN32 || defined __CYGWIN__ + #ifdef BUILDING_{utoken} + #define {utoken}_PUBLIC __declspec(dllexport) + #else + #define {utoken}_PUBLIC __declspec(dllimport) + #endif +#else + #ifdef BUILDING_{utoken} + #define {utoken}_PUBLIC __attribute__ ((visibility ("default"))) + #else + #define {utoken}_PUBLIC + #endif +#endif + +namespace {namespace} {{ + +class {utoken}_PUBLIC {class_name} {{ + +public: + {class_name}(); + int get_number() const; + +private: + + int number; + +}}; + +}} + +''' + +lib_cpp_template = '''#include <{header_file}> + +namespace {namespace} {{ + +{class_name}::{class_name}() {{ + number = 6; +}} + +int {class_name}::get_number() const {{ + return number; +}} + +}} +''' + +lib_cpp_test_template = '''#include <{header_file}> +#include + +int main(int argc, char **argv) {{ + if(argc != 1) {{ + printf("%s takes no arguments.\\n", argv[0]); + return 1; + }} + {namespace}::{class_name} c; + return c.get_number() != 6; +}} +''' + +lib_cpp_meson_template = '''project('{project_name}', 'cpp', + version : '{version}', + default_options : ['warning_level=3', 'cpp_std=c++14']) + +# These arguments are only used to build the shared library +# not the executables that use the library. +lib_args = ['-DBUILDING_{utoken}'] + +# Hiding symbols that are not explicitly marked as exported +# requires a compiler flag on all compilers except VS. +cpp = meson.get_compiler('cpp') +if cpp.get_id() != 'msvc' + lib_args += ['-fvisibility=hidden'] +endif + +shlib = shared_library('{lib_name}', '{source_file}', + install : true, + cpp_args : lib_args, +) + +test_exe = executable('{test_exe_name}', '{test_source_file}', + link_with : shlib) +test('{test_name}', test_exe) + +# Make this library usable as a Meson subproject. +{ltoken}_dep = declare_dependency( + include_directories: include_directories('.'), + link_with : shlib) + +# Make this library usable from the system's +# package manager. +install_headers('{header_file}', subdir : '{header_dir}') + +pkg_mod = import('pkgconfig') +pkg_mod.generate( + name : '{project_name}', + filebase : '{ltoken}', + description : 'Meson sample project.', + subdirs : '{header_dir}', + libraries : shlib, + version : '{version}', +) +''' + info_message = '''Sample project created. To build it run the following commands: @@ -203,6 +313,33 @@ def create_exe_cpp_sample(project_name, project_version): source_name=source_name, version=project_version)) +def create_lib_cpp_sample(project_name, version): + lowercase_token = re.sub(r'[^a-z0-9]', '_', project_name.lower()) + uppercase_token = lowercase_token.upper() + class_name = uppercase_token[0] + lowercase_token[1:] + namespace = lowercase_token + lib_h_name = lowercase_token + '.hpp' + lib_c_name = lowercase_token + '.cpp' + test_c_name = lowercase_token + '_test.cpp' + kwargs = {'utoken': uppercase_token, + 'ltoken': lowercase_token, + 'header_dir': lowercase_token, + 'class_name': class_name, + 'namespace': namespace, + 'header_file': lib_h_name, + 'source_file': lib_c_name, + 'test_source_file': test_c_name, + 'test_exe_name': lowercase_token, + 'project_name': project_name, + 'lib_name': lowercase_token, + 'test_name': lowercase_token, + 'version': version, + } + open(lib_h_name, 'w').write(lib_hpp_template.format(**kwargs)) + open(lib_c_name, 'w').write(lib_cpp_template.format(**kwargs)) + open(test_c_name, 'w').write(lib_cpp_test_template.format(**kwargs)) + open('meson.build', 'w').write(lib_cpp_meson_template.format(**kwargs)) + def create_sample(options): if options.language == 'c': if options.type == 'executable': @@ -214,6 +351,8 @@ def create_sample(options): elif options.language == 'cpp': if options.type == 'executable': create_exe_cpp_sample(options.name, options.version) + elif options.type == 'library': + create_lib_cpp_sample(options.name, options.version) else: raise RuntimeError('Unreachable code') else: