diff --git a/list-headers.py b/list-headers.py new file mode 100644 index 00000000..cb88f53f --- /dev/null +++ b/list-headers.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python + +import os +import re + +description = "Lists all primary sol2 header files" + +script_path = os.path.normpath(os.path.dirname(os.path.realpath(__file__))) +working_dir = os.getcwd() +os.chdir(script_path) + +includes = set([]) +local_include = re.compile(r'#(\s*?)include "(.*?)"') +project_include = re.compile(r'#(\s*?)include ') +pragma_once_cpp = re.compile(r'(\s*)#(\s*)pragma(\s+)once') +ifndef_cpp = re.compile(r'#ifndef SOL_.*?_HPP') +define_cpp = re.compile(r'#define SOL_.*?_HPP') +endif_cpp = re.compile(r'#endif // SOL_.*?_HPP') + + +def get_include(line, base_path): + local_match = local_include.match(line) + if local_match: + # local include found + full_path = os.path.normpath( + os.path.join(base_path, local_match.group(2))).replace( + '\\', '/') + return full_path + project_match = project_include.match(line) + if project_match: + # local include found + full_path = os.path.normpath( + os.path.join(base_path, project_match.group(2))).replace( + '\\', '/') + return full_path + return None + + +def is_include_guard(line): + return ifndef_cpp.match(line) or define_cpp.match( + line) or endif_cpp.match(line) or pragma_once_cpp.match(line) + + +def process_file(filename): + global includes + filename = os.path.normpath(filename) + relativefilename = filename.replace(script_path + os.sep, "").replace( + "\\", "/") + + rel_filename = os.path.relpath(filename, script_path).replace('\\', '/') + + if rel_filename in includes: + return + + empty_line_state = True + + with open(filename, 'r', encoding='utf-8') as f: + includes.add(rel_filename) + + for line in f: + # skip comments + if line.startswith('//'): + continue + + # skip include guard non-sense + if is_include_guard(line): + continue + + # get relative directory + base_path = os.path.dirname(filename) + + # see if it's an include file + name = get_include(line, base_path) + + if name: + process_file(name) + continue + +processed_files = [os.path.join(script_path, x) for x in ['sol.hpp']] + +for processed_file in processed_files: + process_file(processed_file) + +for include in includes: + print(include) \ No newline at end of file diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..f30d3ebb --- /dev/null +++ b/meson.build @@ -0,0 +1,44 @@ +project('sol2', 'cpp') + +# Expose standard dependency +sol2_dep = declare_dependency( + include_directories: include_directories('.'), +) + + +# Check if we have python installed (required for creating single) +python = find_program('python3', required: false) + +if not python.found() + python = find_program('python', required: false) +endif + +single_opt = get_option('single') + +if not python.found() and single_opt + error('Could not locate Python. Python is required when building a single header.') +endif + + +# Single header targets requested +if single_opt + + # Get sol header files + cmd = run_command(python, 'list-headers.py') + + if cmd.returncode() != 0 + error('Could not list sol2 header files.') + endif + + # Setup the single generation target + sol2_single = custom_target('sol2_single', + output: 'sol2.hpp', + input: cmd.stdout().strip().split('\n'), + command: [ python, 'single.py', '--output', '@OUTPUT@' ], + ) + + # Create the dependency + sol2_single_dep = declare_dependency( + sources: [ sol2_single ], + ) +endif \ No newline at end of file diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 00000000..a4d904cf --- /dev/null +++ b/meson_options.txt @@ -0,0 +1 @@ +option('single', type: 'boolean', value: false, description: 'Generate the sol2 single header and expose the corresponding build targets') \ No newline at end of file