@@ -110,33 +110,49 @@ namespace printer {
110110          dependencyDirectory(buildDirectory / " dependencies" 
111111          pathToShellVariable{{buildDirectory, " $(build_dir)" 
112112                              {projectContext.projectPath , " $(project_dir)" 
113-                               {buildDirectoryRelative, " $(build_relative)" 
114-                               {Paths::getUTBotRootDir (), " $(UTBOT_ALL)" 
115-                               {Paths::getGtestLibPath (), " $(gtest)" 
116-                               {Paths::getAccessPrivateLibPath (), " $(access_privateLib)" 
117-                               {Paths::getAsanLibraryPath (), " $(asanLib)" 
113+                               {buildDirectoryRelative, " $(build_relative)" 
118114                              },
119-           artifacts ({getRelativePath (buildDirectory), getRelativePath (dependencyDirectory) }), stubSources(stubSources) {
115+           priorityObjectNameByAbsolutePath{{Paths::getUTBotClangPP (), " clang++" 
116+                                            {Paths::getUTBotClang (),   " clang" 
117+                                            {Paths::getGcc (),          " gcc" 
118+                                            {Paths::getGpp (),          " g++" 
119+                                            {Paths::getGtestLibPath (), " gtest" 
120+                        },
121+           stubSources (stubSources) {
122+ 
123+         artifacts = {getRelativePath (buildDirectory), getRelativePath (dependencyDirectory)};
120124        init ();
121125    }
122126
123127    void  NativeMakefilePrinter::init () {
124-         declareVariableIfNotDefined (" UTBOT_ALL" Paths::getUTBotRootDir ());
128+         const  auto  declareVariableFunc = &NativeMakefilePrinter::declareVariable;
129+         const  auto  declareVariableIfNotDefinedFunc = &NativeMakefilePrinter::declareVariableIfNotDefined;
130+         const  auto  declareVariableWithPriorityFunc = &NativeMakefilePrinter::declareVariableWithPriority;
125131
126-         declareVariable (" access_privateLib" Paths::getAccessPrivateLibPath ());
127-         declareVariable (" asanLib" Paths::getAsanLibraryPath ());
132+         declareShellVariable (" UTBOT_ALL" Paths::getUTBotRootDir (), declareVariableFunc);
128133
129-         declareVariableIfNotDefined (" clang" Paths::getUTBotClang ());
130-         declareVariableIfNotDefined (" clangpp" Paths::getUTBotClangPP ());
131-         declareVariableIfNotDefined (" gcc" Paths::getGcc ());
132-         declareVariableIfNotDefined (" gpp" Paths::getGpp ());
134+         declareShellVariable (" UTBOT_INSTALL" Paths::getUTBotInstallDir (), declareVariableFunc);
133135
134-         declareVariableIfNotDefined (" ar" Paths::getAr ());
135-         declareVariableIfNotDefined (" ld" Paths::getLd ());
136-         declareVariableIfNotDefined (" ldGold" Paths::getLdGold ());
136+         declareShellVariable (" access_privateLib" Paths::getAccessPrivateLibPath (), declareVariableFunc);
137137
138+         declareShellVariable (" utbotDebsInstallDir" Paths::getUTBotDebsInstallDir (), declareVariableFunc);
138139
139-         declareVariableIfNotDefined (" gtest" Paths::getGtestLibPath ());
140+         declareShellVariable (" asanLib" Paths::getAsanLibraryPath (), declareVariableFunc);
141+ 
142+         declareShellVariable (" clang" Paths::getUTBotClang (), declareVariableWithPriorityFunc, true );
143+ 
144+         declareShellVariable (" clangPlusPlus" Paths::getUTBotClangPP (), declareVariableWithPriorityFunc, true );
145+ 
146+         declareShellVariable (" gcc" Paths::getGcc (), declareVariableWithPriorityFunc, true );
147+         declareShellVariable (" gpp" Paths::getGpp (), declareVariableWithPriorityFunc, true );
148+ 
149+         declareShellVariable (" ar" Paths::getAr (), declareVariableIfNotDefinedFunc);
150+ 
151+         declareShellVariable (" ldGold" Paths::getLdGold (), declareVariableIfNotDefinedFunc);
152+ 
153+         declareShellVariable (" ld" Paths::getLd (), declareVariableIfNotDefinedFunc);
154+ 
155+         declareShellVariable (" gtest" Paths::getGtestLibPath (), declareVariableWithPriorityFunc, true );
140156
141157        declareVariable (" project_dir" stringFormat (" %s/%s" " $(makefile_dir)" " $(project_dir_relative_to_makefile)" 
142158        declareVariable (" build_relative" 
@@ -153,7 +169,7 @@ namespace printer {
153169
154170        fs::path gtestBuildDirectory = getRelativePath (buildDirectory / " googletest" 
155171        fs::path defaultPath = " default.c" 
156-         std::vector<std::string> defaultGtestCompileCommandLine{ getShellByCompiler (primaryCxxCompiler), " -c" " -std=c++11" 
172+         std::vector<std::string> defaultGtestCompileCommandLine{ getRelativePath (primaryCxxCompiler), " -c" " -std=c++11" 
157173                                                            FPIC_FLAG, defaultPath };
158174        utbot::CompileCommand defaultGtestCompileCommand{defaultGtestCompileCommandLine,
159175                                                         getRelativePath (buildDirectory), defaultPath };
@@ -233,7 +249,7 @@ namespace printer {
233249                CompilationUtils::getCompilerName (compileCommand.getCompiler ()));
234250        fs::path cxxCompiler = CompilationUtils::toCppCompiler (compiler);
235251        auto  compilerName = CompilationUtils::getCompilerName (compiler);
236-         compileCommand.setCompiler (getShellByCompiler (compiler));
252+         compileCommand.setCompiler (getRelativePath (compiler));
237253        compileCommand.setSourcePath (getRelativePath (sourcePath));
238254        compileCommand.setOutput (getRelativePath (output));
239255
@@ -306,7 +322,7 @@ namespace printer {
306322    void  NativeMakefilePrinter::addTestTarget (const  fs::path &sourcePath) {
307323        auto  compilationUnitInfo = buildDatabase->getClientCompilationUnitInfo (sourcePath);
308324        auto  testCompilationCommand = compilationUnitInfo->command ;
309-         testCompilationCommand.setCompiler (getShellByCompiler (primaryCxxCompiler));
325+         testCompilationCommand.setCompiler (getRelativePath (primaryCxxCompiler));
310326        testCompilationCommand.setOptimizationLevel (OPTIMIZATION_FLAG);
311327        testCompilationCommand.filterCFlags ();
312328        testCompilationCommand.removeIncludeFlags ();
@@ -343,7 +359,7 @@ namespace printer {
343359                                             getRelativePath (
344360                                                     sharedOutput.value ()) };
345361        if  (rootLinkUnitInfo->commands .front ().isArchiveCommand ()) {
346-             std::vector<std::string> dynamicLinkCommandLine{getShellByLinker ( cxxLinker), " $(LDFLAGS)" 
362+             std::vector<std::string> dynamicLinkCommandLine{getRelativePath ( getLinker ( cxxLinker) ), " $(LDFLAGS)" 
347363                                                            pthreadFlag, coverageLinkFlags,
348364                                                            sanitizerLinkFlags, " -o" 
349365                                                            getRelativePath (
@@ -357,7 +373,7 @@ namespace printer {
357373                          { dynamicLinkCommand.toStringWithChangingDirectory () });
358374        } else  {
359375            utbot::LinkCommand dynamicLinkCommand = rootLinkUnitInfo->commands .front ();
360-             dynamicLinkCommand.setLinker (cxxLinker);
376+             dynamicLinkCommand.setLinker (getLinker ( cxxLinker) );
361377            dynamicLinkCommand.setOutput (testExecutablePath);
362378            dynamicLinkCommand.erase_if ([&](std::string const  &argument) {
363379                return  CollectionUtils::contains (rootLinkUnitInfo->files , argument) ||
@@ -390,7 +406,7 @@ namespace printer {
390406                            sharedOutput.value ().parent_path ())));
391407            dynamicLinkCommand.addFlagToBegin (" $(LDFLAGS)" 
392408
393-             auto  linker = getShellByLinker ( cxxLinker);
409+             auto  linker = getRelativePath ( getLinker ( cxxLinker) );
394410            dynamicLinkCommand.setLinker (linker);
395411            dynamicLinkCommand.setOutput (
396412                    getRelativePath (testExecutablePath));
@@ -424,7 +440,9 @@ namespace printer {
424440          artifacts(baseMakefilePrinter.artifacts),
425441          buildResults(baseMakefilePrinter.buildResults),
426442          sharedOutput(baseMakefilePrinter.sharedOutput),
427-           pathToShellVariable(baseMakefilePrinter.pathToShellVariable) {
443+           pathToShellVariable(baseMakefilePrinter.pathToShellVariable),
444+           priorityObjectNameByAbsolutePath(baseMakefilePrinter.priorityObjectNameByAbsolutePath),
445+           priorityObjectByRelativePath(baseMakefilePrinter.priorityObjectByRelativePath) {
428446        resetStream ();
429447        DefaultMakefilePrinter::writeCopyrightHeader ();
430448
@@ -565,7 +583,7 @@ namespace printer {
565583                }
566584
567585                fs::path linker = linkCommand.getLinker ();
568-                 linkCommand.setLinker (getShellByLinker ( linker));
586+                 linkCommand.setLinker (getRelativePath ( getLinker ( linker) ));
569587
570588
571589                for  (std::string& argument : linkCommand.getCommandLine ()) {
@@ -597,7 +615,7 @@ namespace printer {
597615            auto  sharedOutputRelative = getRelativePath (
598616                    sharedOutput.value ());
599617            std::vector<std::string> sharedLinkCommandLine{
600-                 getShellByCompiler (primaryCompiler),      " $(LDFLAGS)" 
618+                 getRelativePath (primaryCompiler),      " $(LDFLAGS)" 
601619                SHARED_FLAG,          coverageLinkFlags,
602620                sanitizerLinkFlags,   " -o" 
603621                sharedOutputRelative, " -Wl,--whole-archive" 
@@ -669,8 +687,16 @@ namespace printer {
669687    }
670688
671689    fs::path NativeMakefilePrinter::getRelativePath (const  fs::path& source) const  {
672-         const  std::vector basePaths = {buildDirectory, projectContext.projectPath ,
673-                                        Paths::getGtestLibPath (), Paths::getUTBotRootDir ()};
690+         std::vector<std::string> basePaths = CollectionUtils::transformTo<std::vector<std::string>>(pathToShellVariable,
691+                 [](auto  const & item) {
692+             return  item.first ;
693+         });
694+         std::sort (basePaths.begin (), basePaths.end (), [](const  std::string& first, const  std::string& second) {
695+             if  (second == Paths::getUTBotRootDir ().string ()) {
696+                 return  true ;
697+             }
698+             return  std::greater<>()(first, second);
699+         });
674700
675701        for  (const  auto & path : basePaths) {
676702            std::optional<fs::path> relative = Paths::getRelativePathWithShellVariable (
@@ -685,67 +711,32 @@ namespace printer {
685711        return  source;
686712    }
687713
688-     fs::path NativeMakefilePrinter::getLinker (const  fs::path& pathToLinker) const  {
689-         if  (StringUtils::contains (pathToLinker.filename ().c_str (), " clang++" 
690-             return  Paths::getUTBotClangPP ();
691-         }
692-         if  (StringUtils::contains (pathToLinker.filename ().c_str (), " clang" 
693-             return  Paths::getUTBotClang ();
694-         }
695-         if  (StringUtils::contains (pathToLinker.filename ().c_str (), " ar" 
696-             return  Paths::getAr ();
697-         }
698-         if  (StringUtils::contains (pathToLinker.filename ().c_str (), " ld.gold" 
699-             return  Paths::getLdGold ();
700-         }
701-         if  (StringUtils::contains (pathToLinker.filename ().c_str (), " ld" 
702-             return  Paths::getLd ();
703-         }
704-         if  (StringUtils::contains (pathToLinker.filename ().c_str (), " gcc" 
705-             return  Paths::getGcc ();
706-         }
707-         if  (StringUtils::contains (pathToLinker.filename ().c_str (), " g++" 
708-             return  Paths::getGpp ();
709-         }
710-     }
711- 
712-     std::string NativeMakefilePrinter::getShellByCompiler (const  fs::path& pathToCompiler) const  {
713-         if  (StringUtils::contains (pathToCompiler.filename ().c_str (), " clang++" 
714-             return  " $(clangpp)" 
715-         }
716-         if  (StringUtils::contains (pathToCompiler.filename ().c_str (), " clang" 
717-             return  " $(clang)" 
718-         }
719-         if  (StringUtils::contains (pathToCompiler.filename ().c_str (), " gcc" 
720-             return  " $(gcc)" 
721-         }
722-         if  (StringUtils::contains (pathToCompiler.filename ().c_str (), " g++" 
723-             return  " $(gpp)" 
714+     void  NativeMakefilePrinter::declareShellVariable (const  std::string& variableName, fs::path path,
715+                               void  (NativeMakefilePrinter::*declareFunc) (const  std::string&, const  std::string&),
716+                               bool isPriorityObjectDeclaration) {
717+         const  fs::path relativePath = getRelativePath (path);
718+         if  (isPriorityObjectDeclaration) {
719+             priorityObjectByRelativePath[relativePath] = priorityObjectNameByAbsolutePath[path];
724720        }
721+         (*this .*declareFunc)(variableName, relativePath.string ());
722+         pathToShellVariable[path] = StringUtils::stringFormat (" $(%s)" 
725723    }
726724
727-     std::string NativeMakefilePrinter::getShellByLinker (const  fs::path& pathToLinker) const  {
728-         if  (StringUtils::contains (pathToLinker.filename ().c_str (), " clang++" 
729-             return  " $(clangpp)" 
730-         }
731-         if  (StringUtils::contains (pathToLinker.filename ().c_str (), " clang" 
732-             return  " $(clang)" 
733-         }
725+     fs::path NativeMakefilePrinter::getLinker (const  fs::path& pathToLinker) const  {
734726        if  (StringUtils::contains (pathToLinker.filename ().c_str (), " ar" 
735-             return  " $(ar)" 
736-         }
737-         if  (StringUtils::contains (pathToLinker.filename ().c_str (), " ld.gold" 
738-             return  " $(ldGold)" 
739-         }
740-         if  (StringUtils::contains (pathToLinker.filename ().c_str (), " ld" 
741-             return  " $(ld)" 
742-         }
743-         if  (StringUtils::contains (pathToLinker.filename ().c_str (), " gcc" 
744-             return  " $(gcc)" 
745-         }
746-         if  (StringUtils::contains (pathToLinker.filename ().c_str (), " g++" 
747-             return  " $(gpp)" 
727+             return  Paths::getAr ();
748728        }
729+         return  pathToLinker;
749730    }
750731
732+     void  NativeMakefilePrinter::declareVariableWithPriority (std::string const  &variableName,
733+                                                             std::string const  &variablePath) {
734+         ss << stringFormat (" ifneq (\" $(wildcard %s)\" ,\"\" )\n " 
735+         Tab ();
736+         declareVariable (variableName, variablePath);
737+         ss << " else\n " 
738+         Tab ();
739+         declareVariable (variableName, priorityObjectByRelativePath.at (variablePath));
740+         ss << " endif\n " 
741+     }
751742}
0 commit comments