1 /** 2 Copyright: Copyright (c) 2017, Joakim Brännström. All rights reserved. 3 License: MPL-2 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 6 This Source Code Form is subject to the terms of the Mozilla Public License, 7 v.2.0. If a copy of the MPL was not distributed with this file, You can obtain 8 one at http://mozilla.org/MPL/2.0/. 9 */ 10 module dextool_test.compiler; 11 12 import scriptlike; 13 14 import dextool_test.utils : escapePath, TestEnv, runAndLog, makeCommand; 15 import dextool_test.builders; 16 17 immutable defaultBinary = "./binary"; 18 19 /** Construct an execution of a compiler. 20 */ 21 auto makeCompile(const ref TestEnv testEnv, string compiler) { 22 // dfmt off 23 return BuildCommandRun(compiler, testEnv.outdir.escapePath) 24 .commandInOutdir(false) 25 .addArg("-g") 26 .addInclude(testEnv.outdir.escapePath); 27 // dfmt on 28 } 29 30 /// Use in conjunction with makeCompile to setup the default binary destination. 31 auto outputToDefaultBinary(BuildCommandRun br) { 32 return br.addArg(["-o", (br.workdir ~ defaultBinary).escapePath]); 33 } 34 35 /** Add recursively all files in outdir with extension ext (including dot) 36 * 37 * Params: 38 * br = builder param to extend 39 * ext = extension to filter on 40 * exclude = files to exclude 41 */ 42 auto addFilesFromOutdirWithExtension(BuildCommandRun br, string ext, string[] exclude) { 43 import dextool_test.utils : recursiveFilesWithExtension; 44 45 foreach (a; recursiveFilesWithExtension(br.workdir, ext).filter!(a => !canFind(exclude, 46 a.baseName.toString))) { 47 br.addArg(a); 48 } 49 50 return br; 51 } 52 53 /// Add parameters to link and use gmock/gtest. 54 auto addGtestArgs(BuildCommandRun br) { 55 // dfmt off 56 return br 57 .addInclude("fused_gmock") 58 .addArg("-L.") 59 .addArg("-lgmock_gtest") 60 .addArg("-lpthread"); 61 // dfmt on 62 } 63 64 /// Add the parameter as an include (-I). 65 auto addInclude(BuildCommandRun br, Path p) { 66 return br.addArg(["-I", p.toString]); 67 } 68 69 auto addInclude(BuildCommandRun br, string p) { 70 return br.addArg(["-I", p]); 71 } 72 73 /// Add the parameter as a define (-D). 74 auto addDefine(BuildCommandRun br, string v) { 75 return br.addArg(["-D", v]); 76 } 77 78 string[] compilerFlags() { 79 auto default_flags = ["-std=c++98"]; 80 81 auto r = BuildCommandRun("g++").addArg("-dumpversion").yapOutput(false) 82 .throwOnExitStatus(false).run; 83 84 if (!r.success) 85 return default_flags; 86 87 if (r.stdout.length == 0 || r.stdout[0].length == 0) { 88 return default_flags; 89 } else if (r.stdout[0][0] == '5') { 90 return default_flags ~ ["-Wpedantic", "-Werror"]; 91 } else { 92 return default_flags ~ ["-pedantic", "-Werror"]; 93 } 94 } 95 96 deprecated("legacy function, to be removed") void testWithGTest(const Path[] src, 97 const Path binary, const ref TestEnv testEnv, const string[] flags, const string[] incls) { 98 immutable bool[string] rm_flag = ["-Wpedantic" : true, "-Werror" : true, "-pedantic" : true]; 99 100 auto flags_ = flags.filter!(a => a !in rm_flag).array(); 101 102 Args args; 103 args ~= "g++"; 104 args ~= flags_.dup; 105 args ~= "-g"; 106 args ~= "-o" ~ binary.escapePath; 107 args ~= "-I" ~ testEnv.outdir.escapePath; 108 args ~= "-I" ~ "fused_gmock"; 109 args ~= incls.dup; 110 args ~= src.dup; 111 args ~= "-l" ~ "gmock_gtest"; 112 args ~= "-lpthread"; 113 args ~= "-L."; 114 115 runAndLog(args.data); 116 } 117 118 deprecated("legacy function, to be removed") void compileResult(const Path input, const Path binary, 119 const Path main, const ref TestEnv testEnv, const string[] flags, const string[] incls) { 120 Args args; 121 args ~= "g++"; 122 args ~= flags.dup; 123 args ~= "-g"; 124 args ~= "-o" ~ binary.escapePath; 125 args ~= "-I" ~ testEnv.outdir.escapePath; 126 args ~= incls.dup; 127 args ~= main; 128 129 if (exists(input)) { 130 args ~= input; 131 } 132 133 runAndLog(args.data); 134 }