diff options
-rw-r--r-- | .gitlab-ci.yml | 18 | ||||
-rwxr-xr-x | deheader | 52 | ||||
-rwxr-xr-x | tools/ci/jobs/deheader.sh | 3 | ||||
-rw-r--r-- | tools/ci/samples/test11.cpp | 18 | ||||
-rw-r--r-- | tools/ci/samples/test11.h | 6 | ||||
-rw-r--r-- | tools/ci/samples/test12.h | 16 |
6 files changed, 94 insertions, 19 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8c2a711..7bdbd1a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -164,6 +164,24 @@ test10_h: tags: - docker +test11_cpp: + stage: build + script: + - ./tools/ci/jobs/deheader.sh "g++-5" "" test11.cpp + - ./tools/ci/jobs/deheadererror.sh "<map>" + image: debian:unstable + tags: + - docker + +test12_h: + stage: build + script: + - ./tools/ci/jobs/deheader.sh "g++-5" "" test12.h + - ./tools/ci/jobs/deheadererror.sh "<map>" + image: debian:unstable + tags: + - docker + # reports success: @@ -1234,7 +1234,7 @@ class InclusionMap: def c_source(filename): "Predicate: return true if the filename appears to be C or C++ source." return filename.endswith(".c") or filename.endswith(".cpp") or filename.endswith(".cc") or filename.endswith(".h") - def __init__(self, roots, ignore, excludes, verbosity, compiler, defines, maker, showerrs=False, subdir=""): + def __init__(self, roots, ignore, excludes, verbosity, compiler, std, defines, maker, showerrs=False, subdir=""): "Build the initial inclusion map." self.verbosity = verbosity self.files = [] @@ -1283,7 +1283,7 @@ class InclusionMap: c = match_preproc(["ifndef", "ifdef", "if", "elif"], line) if c is not False: if allow_parse_includes == True: - allow_parse_includes = self.check_block(sourcefile, cnt, compiler, defines, maker, verbosity, showerrs, subdir) + allow_parse_includes = self.check_block(sourcefile, cnt, compiler, "", defines + " " + std, maker, verbosity, showerrs, subdir) conditions.append((c, allow_parse_includes)) elif match_preproc("else", line) is not False: allow_parse_includes = not allow_parse_includes @@ -1328,7 +1328,7 @@ class InclusionMap: def remember(self, sourcefile, header): "Undo forgetting of a dependency." self.depends_on[sourcefile].append(header) - def check_block(self, sourcefile, cnt, compiler, defines, maker, verbosity, showerrs, subdir): + def check_block(self, sourcefile, cnt, compiler, std, defines, maker, verbosity, showerrs, subdir): tempName = sourcefile + ".cpp" try: with open(sourcefile, "r") as r: @@ -1339,7 +1339,7 @@ class InclusionMap: if cnt2 == cnt: w.write("#error deheader\n") cnt2 = cnt2 + 1 - (st, _t) = testcompile(tempName, compiler, defines, maker, "make {0}".format(cnt), verbosity, showerrs=False, subdir=subdir) + (st, _t) = testcompile(tempName, compiler, std, defines, maker, "make {0}".format(cnt), verbosity, showerrs=False, subdir=subdir) if st == 0: return False return True @@ -1392,18 +1392,17 @@ def trim(line): else: return repr(line) -def testcompile(source, compiler, defines, maker, msg="", verbosity=0, showerrs=False, subdir=""): +def testcompile(source, compiler, std, defines, maker, msg="", verbosity=0, showerrs=False, subdir=""): "Test-compile a sourcefile. Return the status and the compilation time" (stem, _suffix) = os.path.splitext(source) tmpname = stem + ".o" - command = "{0} {1} {2} -o {3} {4}".format(compiler, defines, maker, tmpname, source) olddir = os.getcwd() if len(subdir) > 0: os.chdir(subdir) start = time.time() + command = "{0} {1} {2} {3} -o {4} {5}".format(compiler, std, defines, maker, tmpname, source) (status, output) = getstatusoutput(command) end = time.time() - os.chdir(olddir) if verbosity >= COMMAND_DEBUG or (showerrs and os.WIFEXITED(status) and os.WEXITSTATUS(status) != 0): sys.stdout.write(output + "\n") if status: @@ -1411,12 +1410,25 @@ def testcompile(source, compiler, defines, maker, msg="", verbosity=0, showerrs= if verbosity >= PROGRESS_DEBUG: explain += " (%d)" % status else: - explain = "succeeded" + if std == "": + explain = "succeeded" + else: + command = "{0} {1} {2} -o {3} {4}".format(compiler, defines, maker, tmpname, source) + (status, output) = getstatusoutput(command) + end = time.time() + if status: + explain = "failed" + if verbosity >= PROGRESS_DEBUG: + explain += " (%d)" % status + else: + explain = "succeeded" + + os.chdir(olddir) if verbosity >= PROGRESS_DEBUG: print("deheader: %s%s %s." % (source, msg, explain)) return (status, end - start) -def c_analyze(sourcefile, compiler, defines, maker, includes, requires, verbosity, subdir=""): +def c_analyze(sourcefile, compiler, std, defines, maker, includes, requires, verbosity, subdir=""): "Given a C file and a list of includes, return those that can be omitted." # We'll remove headers in reverse order, because later unnecessary # headers might depend on earlier ones @@ -1440,7 +1452,7 @@ def c_analyze(sourcefile, compiler, defines, maker, includes, requires, verbosit retain += 1 if not retain: saveit.remove_headers(unneeded + [header]) - (st, _t) = testcompile(sourcefile, compiler, defines, maker, " without %s" % trim(header), verbosity, showerrs=False, subdir=subdir) + (st, _t) = testcompile(sourcefile, compiler, std, defines, maker, " without %s" % trim(header), verbosity, showerrs=False, subdir=subdir) if st == 0: unneeded.append(header) includes.remove(header) @@ -1459,19 +1471,19 @@ def c_analyze(sourcefile, compiler, defines, maker, includes, requires, verbosit print("deheader: in %s, %s portability requires %s." % (os.path.join(subdir, sourcefile), trigger, ",".join(requirement))) return unneeded -def deheader(sourcefile, compiler, defines, maker, includes, requires, remove, verbose): +def deheader(sourcefile, compiler, std, defines, maker, includes, requires, remove, verbose): # Sanity check against broken sourcefiles; we want this to # complain visibly if the sourcefile won't build at all. subdir = "" - (st, _t) = testcompile(sourcefile, compiler, defines, maker, verbosity=max(1, verbose), showerrs=False) + (st, _t) = testcompile(sourcefile, compiler, std, defines, maker, verbosity=max(1, verbose), showerrs=False) if st != 0: subdir = os.path.dirname(sourcefile) sourcefile = os.path.basename(sourcefile) - (st, _t) = testcompile(sourcefile, compiler, defines, maker, verbosity=max(1, verbose), showerrs=True, subdir=subdir) + (st, _t) = testcompile(sourcefile, compiler, std, defines, maker, verbosity=max(1, verbose), showerrs=True, subdir=subdir) if st == 0: # Now do the analysis if sourcefile.endswith(".c") or sourcefile.endswith(".cpp") or sourcefile.endswith(".cc") or sourcefile.endswith(".h"): - unneeded = c_analyze(sourcefile, compiler, defines, maker, + unneeded = c_analyze(sourcefile, compiler, std, defines, maker, includes[:], requires, verbose, subdir=subdir) if unneeded: for line in unneeded: @@ -1505,18 +1517,20 @@ class Summary: (len(self.filenames), len(self.includes), len(self.unneeded)) if __name__ == "__main__": - (options, arguments) = getopt.getopt(sys.argv[1:], "hi:m:qrvx:V:c:d:", + (options, arguments) = getopt.getopt(sys.argv[1:], "hi:m:qrvx:V:c:d:s:", ["help", "ignore", "maker", "quiet", "remove", "verbose", "exclude", "version", - "compiler", "defines"]) + "compiler", "defines", + "std"]) maker = "make" verbose = 0 quiet = False remove = False compiler = "g++" defines = "" + std = "" ignores = [] exclusions = [] for (switch, val) in options: @@ -1542,6 +1556,8 @@ if __name__ == "__main__": compiler = val elif switch in ('-d', '--defines'): defines = val + elif switch in ('-s', '--std'): + std = val if not ignores: ignore = None else: @@ -1554,10 +1570,10 @@ if __name__ == "__main__": arguments = ["."] inclusion_map = InclusionMap(arguments, ignore, exclusions, verbose, - compiler, defines, maker, showerrs=False) + compiler, std, defines, maker, showerrs=False) summaries = [] for sourcefile in sorted(inclusion_map.depends_on.keys()): - summaries.append(deheader(sourcefile, compiler, defines, maker, + summaries.append(deheader(sourcefile, compiler, std, defines, maker, inclusion_map.depends_on[sourcefile], inclusion_map.requires[sourcefile], remove, verbose)) diff --git a/tools/ci/jobs/deheader.sh b/tools/ci/jobs/deheader.sh index 314506f..25cd26c 100755 --- a/tools/ci/jobs/deheader.sh +++ b/tools/ci/jobs/deheader.sh @@ -18,5 +18,6 @@ echo $3 ${dir}/deheader -q \ -c "$1" \ -d "$2" \ --m "-c -std=gnu++1z -Werror -Wall -Wextra -Wundef -Wmissing-declarations -I/usr/include -I${dir}/tools/ci/samples" ${dir}/tools/ci/samples/$3 \ +-s "-std=gnu++1z" \ +-m "-c -Werror -Wall -Wextra -Wundef -Wmissing-declarations -I/usr/include -I${dir}/tools/ci/samples" ${dir}/tools/ci/samples/$3 \ | grep -v "portability requires" | tee -a ${LOGFILE} diff --git a/tools/ci/samples/test11.cpp b/tools/ci/samples/test11.cpp new file mode 100644 index 0000000..89430b5 --- /dev/null +++ b/tools/ci/samples/test11.cpp @@ -0,0 +1,18 @@ +#include "test11.h" + +#include <map> +#include <string> + +class Class1 +{ + Class1(const std::string &str) : + mStr(str) + { + } + const std::string mStr; +}; + +int function1() +{ + return 0; +} diff --git a/tools/ci/samples/test11.h b/tools/ci/samples/test11.h new file mode 100644 index 0000000..53ef57d --- /dev/null +++ b/tools/ci/samples/test11.h @@ -0,0 +1,6 @@ +#ifndef TEST11 +#define TEST11 + +int function1(); + +#endif // TEST11 diff --git a/tools/ci/samples/test12.h b/tools/ci/samples/test12.h new file mode 100644 index 0000000..3dac36c --- /dev/null +++ b/tools/ci/samples/test12.h @@ -0,0 +1,16 @@ +#ifndef TEST12 +#define TEST12 + +#include <map> +#include <string> + +class Class1 +{ + Class1(const std::string &str) : + mStr(str) + { + } + const std::string mStr; +}; + +#endif // TEST12 |