[mm-common/check-dllexport-usage] util: Add script to check gmmproc version



commit 8a29ded06fea7e80309f6b747af1bd41a04ed9db
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Thu Apr 2 12:27:16 2020 +0800

    util: Add script to check gmmproc version
    
    This adds a new utility script for Meson builds to check on what gmmproc
    version was used (or is to be used) to generate the sources, so that we
    can know whether we are ready to use compiler directives to export
    symbols by defining macros during the build of the various -mm C++
    modules.

 Makefile.am                                 |   1 +
 README                                      |   5 ++
 meson.build                                 |   1 +
 skeletonmm/meson.build                      |   1 +
 skeletonmm/untracked/README                 |   3 +-
 util/build_scripts/check-dllexport-usage.py | 108 ++++++++++++++++++++++++++++
 util/build_scripts/dist-build-scripts.py    |   1 +
 util/mm-common-get.1.in                     |   2 +
 util/mm-common-get.in                       |   2 +-
 9 files changed, 122 insertions(+), 2 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index cbb7451..68019a7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -30,6 +30,7 @@ dist_build_support_DATA =             \
        am_include/dist-changelog.am            \
        am_include/doc-reference.am             \
        am_include/generate-binding.am \
+  util/build_scripts/check-dllexport-usage.py \
   util/build_scripts/dist-build-scripts.py \
   util/build_scripts/dist-changelog.py \
   util/build_scripts/doc-reference.py \
diff --git a/README b/README
index d4bea2a..d94c37c 100644
--- a/README
+++ b/README
@@ -221,6 +221,11 @@ util/build_scripts/dist-build-scripts.py:
   not checked into the git repository. All .gitignore files and an empty build/
   directory are removed
 
+util/build_scripts/check-dllexport-usage.py:
+  Command that checks on the gmmproc version that is to be used or been used
+  to generate the sources, to check whether to use compiler directives to
+  export symbols
+
 Documentation utilities (Meson and Autotools)
 ---------------------------------------------
 
diff --git a/meson.build b/meson.build
index fbc7e5e..92c639a 100644
--- a/meson.build
+++ b/meson.build
@@ -73,6 +73,7 @@ endforeach
 # These are installed so that mm-common-get can copy them
 # into projects at Meson setup or configure time.
 meson_build_support_basefiles = [
+  'check-dllexport-usage.py',
   'dist-build-scripts.py',
   'dist-changelog.py',
   'doc-reference.py',
diff --git a/skeletonmm/meson.build b/skeletonmm/meson.build
index 2274d32..0c885c6 100644
--- a/skeletonmm/meson.build
+++ b/skeletonmm/meson.build
@@ -102,6 +102,7 @@ generate_binding = script_dir / 'generate-binding.py'
 doc_reference = script_dir / 'doc-reference.py'
 dist_changelog = script_dir / 'dist-changelog.py'
 dist_build_scripts = script_dir / 'dist-build-scripts.py'
+check_dllexport_usage = script_dir / 'check-dllexport-usage.py'
 dist_cmd = project_source_root / 'tools' / 'dist-cmd.py' # Must be committed to git.
 
 if maintainer_mode and mm_common_get.found()
diff --git a/skeletonmm/untracked/README b/skeletonmm/untracked/README
index 8082503..b51c2cb 100644
--- a/skeletonmm/untracked/README
+++ b/skeletonmm/untracked/README
@@ -19,7 +19,8 @@ untracked/doc/doc-install.pl
               doc-postprocess.pl
               doxygen-extra.css
               tagfile-to-devhelp2.xsl
-untracked/build_scripts/dist-build-scripts.py
+untracked/build_scripts/check-dllexport-usage.py
+                        dist-build-scripts.py
                         dist-changelog.py
                         doc-reference.py
                         generate-binding.py
diff --git a/util/build_scripts/check-dllexport-usage.py b/util/build_scripts/check-dllexport-usage.py
new file mode 100644
index 0000000..7029b42
--- /dev/null
+++ b/util/build_scripts/check-dllexport-usage.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python3
+#
+# Check for the first line in a file generated with gmmproc,
+# to see which gmmproc version was used, to see whether
+# to enable __declspec(dllexport to export symbols)
+#
+# Author: Chun-wei Fan April 2, 2020
+
+import argparse
+import os
+import subprocess
+import sys
+import tempfile
+import traceback
+
+parser = argparse.ArgumentParser(description='Check gmmproc version used.')
+parser.add_argument('--file',
+                    dest='file',
+                    help='Generated .cc/.h file or .ccg/.hg ' +
+                         'template to check gmmproc version',
+                    required=True)
+parser.add_argument('--gmmprocdir',
+                    dest='gmmprocdir',
+                    help='Directory where gmmproc is located, required ' +
+                         'if --file argument is a .hg/.ccg file.  Note ' +
+                         'that PERL with XML::Parser and some common ' +
+                         'UNIX utilities are required to run gmmproc')
+parser.add_argument('--extra-gmmproc-flags',
+                    dest='gmmprocflags',
+                    help='Extra flags to be passed to gmmproc')
+parser.add_argument('--perl',
+                    dest='perl',
+                    help='PERL interpreter command or full path, for ' +
+                         'running gmmproc (default: \'perl\')',
+                    default='perl')
+args = parser.parse_args()
+
+if not os.path.exists(args.file):
+    raise FileNotFoundError('File specified with --file does not exist')
+
+# We only allow .hg/.ccg/.h/.cc files to run this check
+file_ext_idx = args.file.rfind('.')
+if file_ext_idx == -1 or \
+   (args.file[file_ext_idx + 1:] != 'hg' and \
+    args.file[file_ext_idx + 1:] != 'ccg' and \
+    args.file[file_ext_idx + 1:] != 'cc' and \
+    args.file[file_ext_idx + 1:] != 'h'):
+    raise ValueError('Only .cc/.ccg/.hg/.h files are accepted here')
+
+checked_file = None
+do_cleanup = False
+tmp_check_dir = None
+
+if args.file[file_ext_idx + 1:] == 'hg' or \
+   args.file[file_ext_idx + 1:] == 'ccg':
+    # A .ccg/.hg file is specified: First create a tmpdir, and use
+    # gmmproc to generate the full sources from it, and check on
+    # that file on what gmmproc version is used.
+    if args.gmmprocdir is None or \
+       not os.path.exists(os.path.join(args.gmmprocdir, 'gmmproc')):
+        raise ValueError('A valid directory to locate gmmproc must be ' \
+                         'specified with --gmmprocdir=<directory>')
+    
+    do_cleanup = True
+    if os.name == 'nt':
+        args.file = args.file.replace('\\', '/')
+
+    extra_gmmproc_flags = []
+    if args.gmmprocflags is not None:
+        extra_gmmproc_flags = args.gmmprocflags.split()
+
+    modname = args.file[args.file.rfind('/') + 1: file_ext_idx]
+    srcpath = args.file[:args.file.rfind('/')]
+    
+    tmp_check_dir = tempfile.TemporaryDirectory()
+    os.mkdir(os.path.join(tmp_check_dir.name, 'private'))
+    subprocess.run([args.perl, '--',
+                    os.path.join(args.gmmprocdir, 'gmmproc'),
+                    '-I', 'tools/m4'] +
+                   extra_gmmproc_flags +
+                   ['--defs', srcpath, modname,
+                    srcpath, tmp_check_dir.name])
+    checked_file = os.path.join(tmp_check_dir.name, modname + '.h')
+else:
+    # A .cc/.h file is specified: Just check on that file as-is
+    checked_file = args.file
+
+# Now grab the first line of the file we are checking for
+f = open(checked_file)
+firstline = f.readline()
+f.close()
+
+# Remove the temporary directory if we created one
+if do_cleanup:
+    tmp_check_dir.cleanup()
+
+# Check for gmmproc signature...
+if not firstline.startswith('// Generated by gmmproc '):
+   raise ValueError('Specified file is not generated by gmmproc')
+
+# Now compare the gmmproc version against the one we want
+tokens = firstline.split()
+gmmproc_ver = tokens[tokens.index('gmmproc') + 1]
+
+if gmmproc_ver >= '2.64.3':
+    sys.exit(0)
+else:
+    sys.exit(1)
diff --git a/util/build_scripts/dist-build-scripts.py b/util/build_scripts/dist-build-scripts.py
index 7318bc7..bdcda10 100755
--- a/util/build_scripts/dist-build-scripts.py
+++ b/util/build_scripts/dist-build-scripts.py
@@ -19,6 +19,7 @@ os.makedirs(dist_script_dir, exist_ok=True)
 
 # Distribute files that mm-common-get has copied to src_script_dir.
 files = [
+  'check-dllexport-usage.py',
   'dist-build-scripts.py',
   'dist-changelog.py',
   'doc-reference.py',
diff --git a/util/mm-common-get.1.in b/util/mm-common-get.1.in
index ff8996c..951f7ea 100644
--- a/util/mm-common-get.1.in
+++ b/util/mm-common-get.1.in
@@ -30,6 +30,8 @@ are listed below.
 .BI "Meson build scripts copied to " BUILDSCRIPT-DIR :
 .PD 0
 .IP
+.I check-dllexport-usage.py
+.IP
 .I dist-build-scripts.py
 .IP
 .I dist-changelog.py
diff --git a/util/mm-common-get.in b/util/mm-common-get.in
index e0b28f0..8a21f02 100644
--- a/util/mm-common-get.in
+++ b/util/mm-common-get.in
@@ -41,7 +41,7 @@ doctooldir = args.doctool_dir
 print(progname + ': putting Meson build scripts in ' + buildscriptdir)
 # Create the destination directory, if it does not exist.
 os.makedirs(buildscriptdir, exist_ok=True)
-for file in ['dist-build-scripts.py', 'dist-changelog.py', 'doc-reference.py', 'generate-binding.py']:
+for file in ['check-dllexport-usage.py', 'dist-build-scripts.py', 'dist-changelog.py', 'doc-reference.py', 
'generate-binding.py']:
   src_file = os.path.join(pkgdatadir, 'build', file)
   dest_file = os.path.join(buildscriptdir, file)
   # Don't update the timestamp of dest_file, if it's equal to src_file.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]