1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #include "cmQTWrapUICommand.h"
4 
5 #include "cmCustomCommandLines.h"
6 #include "cmExecutionStatus.h"
7 #include "cmMakefile.h"
8 #include "cmPolicies.h"
9 #include "cmRange.h"
10 #include "cmSourceFile.h"
11 #include "cmStringAlgorithms.h"
12 #include "cmSystemTools.h"
13 
cmQTWrapUICommand(std::vector<std::string> const & args,cmExecutionStatus & status)14 bool cmQTWrapUICommand(std::vector<std::string> const& args,
15                        cmExecutionStatus& status)
16 {
17   if (args.size() < 4) {
18     status.SetError("called with incorrect number of arguments");
19     return false;
20   }
21 
22   cmMakefile& mf = status.GetMakefile();
23 
24   // Get the uic and moc executables to run in the custom commands.
25   std::string const& uic_exe = mf.GetRequiredDefinition("QT_UIC_EXECUTABLE");
26   std::string const& moc_exe = mf.GetRequiredDefinition("QT_MOC_EXECUTABLE");
27 
28   // Get the variable holding the list of sources.
29   std::string const& headerList = args[1];
30   std::string const& sourceList = args[2];
31   std::string headerListValue = mf.GetSafeDefinition(headerList);
32   std::string sourceListValue = mf.GetSafeDefinition(sourceList);
33 
34   // Create rules for all sources listed.
35   for (std::string const& arg : cmMakeRange(args).advance(3)) {
36     cmSourceFile* curr = mf.GetSource(arg);
37     // if we should wrap the class
38     if (!(curr && curr->GetPropertyAsBool("WRAP_EXCLUDE"))) {
39       // Compute the name of the files to generate.
40       std::string srcName =
41         cmSystemTools::GetFilenameWithoutLastExtension(arg);
42       std::string hName =
43         cmStrCat(mf.GetCurrentBinaryDirectory(), '/', srcName, ".h");
44       std::string cxxName =
45         cmStrCat(mf.GetCurrentBinaryDirectory(), '/', srcName, ".cxx");
46       std::string mocName =
47         cmStrCat(mf.GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx");
48 
49       // Compute the name of the ui file from which to generate others.
50       std::string uiName;
51       if (cmSystemTools::FileIsFullPath(arg)) {
52         uiName = arg;
53       } else {
54         if (curr && curr->GetIsGenerated()) {
55           uiName = mf.GetCurrentBinaryDirectory();
56         } else {
57           uiName = mf.GetCurrentSourceDirectory();
58         }
59         uiName += "/";
60         uiName += arg;
61       }
62 
63       // create the list of headers
64       if (!headerListValue.empty()) {
65         headerListValue += ";";
66       }
67       headerListValue += hName;
68 
69       // create the list of sources
70       if (!sourceListValue.empty()) {
71         sourceListValue += ";";
72       }
73       sourceListValue += cxxName;
74       sourceListValue += ";";
75       sourceListValue += mocName;
76 
77       // set up .ui to .h and .cxx command
78       cmCustomCommandLines hCommandLines =
79         cmMakeSingleCommandLine({ uic_exe, "-o", hName, uiName });
80       cmCustomCommandLines cxxCommandLines = cmMakeSingleCommandLine(
81         { uic_exe, "-impl", hName, "-o", cxxName, uiName });
82       cmCustomCommandLines mocCommandLines =
83         cmMakeSingleCommandLine({ moc_exe, "-o", mocName, hName });
84 
85       std::vector<std::string> depends;
86       depends.push_back(uiName);
87       std::string no_main_dependency;
88       const char* no_comment = nullptr;
89       const char* no_working_dir = nullptr;
90       mf.AddCustomCommandToOutput(hName, depends, no_main_dependency,
91                                   hCommandLines, no_comment, no_working_dir,
92                                   mf.GetPolicyStatus(cmPolicies::CMP0116));
93 
94       depends.push_back(hName);
95       mf.AddCustomCommandToOutput(cxxName, depends, no_main_dependency,
96                                   cxxCommandLines, no_comment, no_working_dir,
97                                   mf.GetPolicyStatus(cmPolicies::CMP0116));
98 
99       depends.clear();
100       depends.push_back(hName);
101       mf.AddCustomCommandToOutput(mocName, depends, no_main_dependency,
102                                   mocCommandLines, no_comment, no_working_dir,
103                                   mf.GetPolicyStatus(cmPolicies::CMP0116));
104     }
105   }
106 
107   // Store the final list of source files and headers.
108   mf.AddDefinition(sourceList, sourceListValue);
109   mf.AddDefinition(headerList, headerListValue);
110   return true;
111 }
112