1 2 #include "makefilegen.h" 3 4 #include <sdk.h> 5 #ifndef CB_PRECOMP 6 #include <wx/file.h> 7 8 #include <cbproject.h> 9 #include <compiler.h> 10 #include <compilerfactory.h> 11 #endif 12 13 #include "makefiledlg.h" 14 #include "nativeparserf.h" 15 16 void MakefileGen::GenerateMakefile(cbProject* project, ProjectDependencies* projDep, NativeParserF* pNativeParser) 17 { 18 if (!project || !projDep) 19 return; 20 21 ProjectBuildTarget* buildTarget = project->GetBuildTarget(project->GetActiveBuildTarget()); 22 if (!buildTarget) 23 return; 24 25 wxString projDir = project->GetBasePath(); 26 wxFileName mffn = wxFileName(projDir,_T("Makefile")); \x21mffn.IsOknull27 if (!mffn.IsOk()) 28 return; 29 if (!SelectMikefileName(mffn)) 30 return; 31 32 wxFile mfile; mffn.GetFullPathnull33 if(!mfile.Create(mffn.GetFullPath(), true)) 34 { 35 cbMessageBox(_T("Makefile can't be created!"), _("Error"), wxICON_ERROR); 36 return; 37 } 38 39 mfile.Write(_T("#\n# This Makefile was generated by Code::Blocks IDE.\n#\n")); 40 41 42 FilesList& filesList = buildTarget->GetFilesList(); 43 44 wxArrayString src_dirs; 45 wxArrayString src_ext; 46 wxArrayString src_files; 47 wxArrayString obj_files; 48 wxString sfiles; 49 wxString ofiles; 50 51 52 53 FilesList::iterator it; filesList.endnull54 for( it = filesList.begin(); it != filesList.end(); ++it ) 55 { 56 ProjectFile* projFile = *it; 57 const pfDetails& pfd = projFile->GetFileDetails(buildTarget); 58 59 wxFileName sfn(pfd.source_file_absolute_native); 60 sfn.MakeRelativeTo(mffn.GetPath(wxPATH_GET_SEPARATOR)); 61 wxString dir = sfn.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR, wxPATH_UNIX); 62 int didx = src_dirs.Index(dir); 63 if (didx == wxNOT_FOUND) 64 didx = src_dirs.Add(dir); sfn.GetExtnull65 wxString ext = sfn.GetExt(); 66 ext << _T("d") << didx+1; 67 int eidx = src_ext.Index(ext); 68 if (eidx == wxNOT_FOUND) 69 { 70 eidx = src_ext.Add(ext); 71 sfiles = wxEmptyString; 72 src_files.Add(wxEmptyString); 73 ofiles = wxEmptyString; 74 obj_files.Add(wxEmptyString); 75 } 76 else 77 { 78 sfiles = src_files.Item(eidx); 79 ofiles = obj_files.Item(eidx); 80 } 81 82 sfiles << sfn.GetFullName() << _T(" \\\n"); 83 src_files[eidx] = sfiles; 84 85 if (projFile->compile) 86 { 87 ofiles << sfn.GetName() << _T(".o") << _T(" \\\n"); 88 obj_files[eidx] = ofiles; 89 } 90 } 91 for (size_t i=0; i<src_ext.Count(); i++) 92 { 93 wxString str; 94 str << _T("\nSRCS_") << src_ext.Item(i) << _T(" = \\\n"); 95 mfile.Write(str); 96 mfile.Write(src_files[i].Mid(0,src_files[i].Find('\\', true))); 97 mfile.Write(_T("\n")); 98 } 99 for (size_t i=0; i<src_ext.Count(); i++) 100 { 101 wxString str; 102 str << _T("\nOBJS_") << src_ext.Item(i) << _T(" = \\\n"); 103 mfile.Write(str); 104 mfile.Write(obj_files[i].Mid(0,obj_files[i].Find('\\', true))); 105 mfile.Write(_T("\n")); 106 } 107 108 wxString objdir = _T("OBJS_DIR = "); 109 110 for( it = filesList.begin(); it != filesList.end(); ++it ) 111 { 112 ProjectFile* projFile = *it; 113 const pfDetails& pfd = projFile->GetFileDetails(buildTarget); 114 115 wxFileName sfn(pfd.source_file_absolute_native); 116 wxString ffpath = sfn.GetFullName(); 117 if (pNativeParser->IsFileFortran(ffpath) && projFile->compile) 118 { 119 wxFileName ofn(pfd.object_file_absolute_native); 120 ofn.MakeRelativeTo(mffn.GetPath(wxPATH_GET_SEPARATOR)); 121 ofn.SetExt(_T("o")); 122 objdir << ofn.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR, wxPATH_UNIX) + _T("\n"); 123 break; 124 } 125 } 126 127 bool containsNonFortranFiles = false; 128 129 wxString depsFiles; 130 for( it = filesList.begin(); it != filesList.end(); ++it ) 131 { 132 ProjectFile* projFile = *it; 133 const pfDetails& pfd = projFile->GetFileDetails(buildTarget); 134 135 if (pNativeParser->IsFileFortran(pfd.source_file) && projFile->compile) 136 { 137 wxFileName sfn(pfd.source_file); 138 sfn.SetExt(_T("o")); 139 depsFiles << sfn.GetFullName(); 140 wxFileName sfn2(pfd.source_file); 141 depsFiles << _T(": \\\n ") << sfn2.GetFullName(); 142 wxArrayString use; 143 projDep->GetUseFilesFile(pfd.source_file_absolute_native, use); 144 for (size_t i=0; i<use.size(); i++) 145 { 146 wxFileName ufn(use.Item(i)); 147 ufn.SetExt(_T("o")); 148 depsFiles << _T(" \\\n ") << ufn.GetFullName(); 149 } 150 151 wxArrayString extends; 152 projDep->GetExtendsFilesFile(pfd.source_file_absolute_native, extends); 153 for (size_t i=0; i<extends.size(); i++) 154 { 155 wxFileName ufn(extends.Item(i)); 156 ufn.SetExt(_T("o")); 157 depsFiles << _T(" \\\n ") << ufn.GetFullName(); 158 } 159 160 wxArrayString incl; 161 projDep->GetIncludeFilesFile(pfd.source_file_absolute_native, incl); 162 for (size_t i=0; i<incl.size(); i++) 163 { 164 wxFileName ifn(incl.Item(i)); 165 depsFiles << _T(" \\\n ") << ifn.GetFullName(); 166 } 167 depsFiles << _T("\n"); 168 } 169 else if (!pNativeParser->IsFileFortran(pfd.source_file) && projFile->compile) 170 { 171 containsNonFortranFiles = true; 172 } 173 } 174 175 for (size_t i=0; i<src_ext.Count(); i++) 176 { 177 wxString sdir; 178 wxString ext = src_ext.Item(i); 179 sdir << _T("\nSRC_DIR_") << ext << _T(" = "); 180 int dpos = ext.Find('d', true); 181 if (dpos != wxNOT_FOUND) 182 { 183 wxString idxstr; 184 idxstr = ext.Mid(dpos+1); 185 long longint; 186 if (idxstr.ToLong(&longint)) 187 { 188 sdir << src_dirs.Item(longint-1); 189 } 190 } 191 sdir << _T("\n"); 192 mfile.Write(sdir); 193 } 194 mfile.Write(objdir); 195 196 TargetType tagTyp = buildTarget->GetTargetType(); 197 wxFileName exefile(buildTarget->GetOutputFilename()); 198 wxFileName basepath; 199 basepath.Assign(buildTarget->GetBasePath(), wxEmptyString, wxEmptyString); 200 wxArrayString bpdirs = basepath.GetDirs(); 201 if (bpdirs.GetCount() > 0) 202 { 203 for (size_t i=bpdirs.GetCount(); i>0; i--) 204 exefile.PrependDir(bpdirs.Item(i-1)); 205 exefile.SetVolume(basepath.GetVolume()+wxFileName::GetVolumeSeparator()); 206 } 207 208 wxString exeStr; 209 if (basepath.HasVolume()) 210 exeStr << basepath.GetVolume() << wxFileName::GetVolumeSeparator() << wxFileName::GetPathSeparator(); 211 else 212 { 213 wxString sep = wxFileName::GetPathSeparator(); 214 if (!exefile.GetPath(wxPATH_GET_SEPARATOR).StartsWith(sep)) 215 exeStr << wxFileName::GetPathSeparator(); 216 } 217 exeStr << exefile.GetPath(wxPATH_GET_SEPARATOR); 218 exefile = wxFileName(exeStr, exefile.GetName(), exefile.GetExt()); 219 exefile.MakeRelativeTo(mffn.GetPath(wxPATH_GET_SEPARATOR)); 220 221 mfile.Write(_T("EXE_DIR = ") + exefile.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR, wxPATH_UNIX) + _T("\n")); 222 mfile.Write(_T("\nEXE = ") + exefile.GetFullName() + _T("\n")); 223 Compiler * compiler = CompilerFactory::GetCompiler(buildTarget->GetCompilerID()); 224 wxString compStr = _T("FC = "); 225 wxString linkerStr = _T("LD = "); 226 if (compiler) 227 { 228 compStr << compiler->GetPrograms().C; 229 compStr << _T("\n"); 230 if (tagTyp == ttDynamicLib) 231 linkerStr << compiler->GetPrograms().LD; 232 else if (tagTyp == ttStaticLib) 233 linkerStr << compiler->GetPrograms().LIB; 234 else 235 linkerStr << compiler->GetPrograms().LD; 236 linkerStr << _T("\n"); 237 } 238 else 239 compStr << _T("\n"); 240 mfile.Write(compStr); 241 mfile.Write(linkerStr); 242 243 wxString idir = _T("IDIR = "); 244 const wxArrayString& idirs = project->GetIncludeDirs(); 245 for(size_t i=0; i<idirs.size(); i++) 246 { 247 idir << _T("-I") << idirs.Item(i) << _T(" "); 248 } 249 const wxArrayString& idirst = buildTarget->GetIncludeDirs(); 250 for(size_t i=0; i<idirst.size(); i++) 251 { 252 idir << _T("-I") << idirst.Item(i) << _T(" "); 253 } 254 mfile.Write(idir + _T("\n")); 255 256 wxString cflags = _T("CFLAGS = "); 257 const wxArrayString& copt = project->GetCompilerOptions(); 258 for(size_t i=0; i<copt.size(); i++) 259 { 260 cflags << copt.Item(i) << _T(" "); 261 } 262 const wxArrayString& copt_t = buildTarget->GetCompilerOptions(); 263 for(size_t i=0; i<copt_t.size(); i++) 264 { 265 cflags << copt_t.Item(i) << _T(" "); 266 } 267 268 if(compiler) 269 { 270 const wxArrayString& copt2 = compiler->GetCompilerOptions(); 271 for(size_t i=0; i<copt2.size(); i++) 272 { 273 cflags << copt2.Item(i) << _T(" "); 274 } 275 } 276 277 if (CompilerFactory::CompilerInheritsFrom(buildTarget->GetCompilerID(), _T("g95"))) 278 cflags << _T(" -fmod=$(OBJS_DIR) $(IDIR)"); 279 else if (CompilerFactory::CompilerInheritsFrom(buildTarget->GetCompilerID(), _T("ifclin"))) 280 cflags << _T(" -module $(OBJS_DIR) $(IDIR)"); 281 else if (CompilerFactory::CompilerInheritsFrom(buildTarget->GetCompilerID(), _T("ifcwin"))) 282 cflags << _T(" /nologo /module:$(OBJS_DIR) $(IDIR)"); 283 else if (CompilerFactory::CompilerInheritsFrom(buildTarget->GetCompilerID(), _T("pgfortran"))) 284 cflags << _T(" -module $(OBJS_DIR) $(IDIR)"); 285 else //gfortran 286 cflags << _T(" -J$(OBJS_DIR) $(IDIR)"); 287 288 mfile.Write(cflags + _T("\n")); 289 290 wxString lflags = _T("LFLAGS = "); 291 const wxArrayString& lopt = project->GetLinkerOptions(); 292 for(size_t i=0; i<lopt.size(); i++) 293 { 294 wxString optstr = lopt.Item(i); 295 optstr.Trim(); 296 int ipos = optstr.Find(_T("--rpath=\\\\$$$ORIGIN")); 297 if (ipos != wxNOT_FOUND) 298 { 299 wxString optstr1 = optstr.Mid(0, ipos+8); 300 wxString optstr2 = _T("'$$ORIGIN") + optstr.Mid(ipos+19) + _T("'"); 301 optstr = optstr1 + optstr2; 302 } 303 lflags << optstr << _T(" "); 304 } 305 const wxArrayString& lopt_t = buildTarget->GetLinkerOptions(); 306 for(size_t i=0; i<lopt_t.size(); i++) 307 { 308 wxString optstr = lopt_t.Item(i); 309 optstr.Trim(); 310 int ipos = optstr.Find(_T("--rpath=\\\\$$$ORIGIN")); 311 if (ipos != wxNOT_FOUND) 312 { 313 wxString optstr1 = optstr.Mid(0, ipos+8); 314 wxString optstr2 = _T("'$$ORIGIN") + optstr.Mid(ipos+19) + _T("'"); 315 optstr = optstr1 + optstr2; 316 } 317 lflags << optstr << _T(" "); 318 } 319 mfile.Write(lflags + _T("\n")); 320 321 wxString libs = _T("LIBS = "); 322 const wxArrayString& ldirs = project->GetLibDirs(); 323 for(size_t i=0; i<ldirs.size(); i++) 324 { 325 libs << _T("-L") << ldirs.Item(i) << _T(" "); 326 } 327 const wxArrayString& ldirst = buildTarget->GetLibDirs(); 328 for(size_t i=0; i<ldirst.size(); i++) 329 { 330 libs << _T("-L") << ldirst.Item(i) << _T(" "); 331 } 332 const wxArrayString& lbsarr = project->GetLinkLibs(); 333 for(size_t i=0; i<lbsarr.size(); i++) 334 { 335 wxString lnam; 336 if (lbsarr.Item(i).StartsWith(_T("lib"))) 337 lnam = lbsarr.Item(i).Mid(3); 338 else 339 lnam = lbsarr.Item(i); 340 libs << _T("-l") << lnam << _T(" "); 341 } 342 const wxArrayString& lbsarrt = buildTarget->GetLinkLibs(); 343 for(size_t i=0; i<lbsarrt.size(); i++) 344 { 345 wxString lnam; 346 if (lbsarrt.Item(i).StartsWith(_T("lib"))) 347 lnam = lbsarrt.Item(i).Mid(3); 348 else 349 lnam = lbsarrt.Item(i); 350 libs << _T("-l") << lnam << _T(" "); 351 } 352 mfile.Write(libs + _T("\n")); 353 354 355 wxString vpath; 356 vpath << _T("\nVPATH = "); 357 for (size_t i=0; i<src_ext.Count(); i++) 358 { 359 vpath << _T("$(SRC_DIR_") << src_ext.Item(i) << _T(")"); 360 vpath << _T(":$(OBJS_DIR)"); 361 if (i < src_ext.Count()-1) 362 { 363 vpath << _T(":"); 364 } 365 } 366 // vpath << _T("\nendif\n"); 367 vpath << _T("\n"); 368 mfile.Write(vpath); 369 370 wxString objsstr = _T("OBJS = $(addprefix $(OBJS_DIR),"); 371 for (size_t i=0; i<src_ext.Count(); i++) 372 { 373 objsstr << _T(" $(OBJS_") << src_ext.Item(i) << _T(")"); 374 } 375 objsstr << _T(")\n"); 376 mfile.Write(objsstr); 377 378 mfile.Write(_T("\nall : $(EXE)\n")); 379 380 wxString lstr = _T("\n$(EXE) :"); 381 382 for (size_t i=0; i<src_ext.Count(); i++) 383 { 384 lstr << _T(" $(OBJS_") << src_ext.Item(i) << _T(")"); 385 } 386 lstr << _T("\n\t@mkdir -p $(EXE_DIR)"); 387 if (tagTyp == ttDynamicLib) 388 { 389 lstr << _T("\n\t$(LD)"); 390 lstr << _T(" -shared $(OBJS) -o $(EXE_DIR)$(EXE) $(LFLAGS) $(LIBS)\n"); 391 } 392 else if (tagTyp == ttStaticLib) 393 { 394 lstr << _T("\n\trm -f $(EXE_DIR)$(EXE)"); 395 lstr << _T("\n\t$(LD)"); 396 lstr << _T(" -r -s $(EXE_DIR)$(EXE) $(OBJS)\n"); 397 } 398 else 399 { 400 lstr << _T("\n\t$(LD)"); 401 lstr << _T(" -o $(EXE_DIR)$(EXE) $(OBJS) $(LFLAGS) $(LIBS)\n"); 402 } 403 mfile.Write(lstr); 404 405 for (size_t i=0; i<src_ext.Count(); i++) 406 { 407 wxString sdir; 408 sdir << _T("$(SRC_DIR_") << src_ext.Item(i) << _T(")"); 409 410 wxString ext = src_ext.Item(i); 411 int dpos = ext.Find('d',true); 412 if (dpos != wxNOT_FOUND) 413 ext = ext.Mid(0,dpos); 414 415 wxString cstr; 416 cstr << _T("\n$(OBJS_") << src_ext.Item(i) << _T("):\n"); 417 cstr << _T("\t@mkdir -p $(OBJS_DIR)\n"); 418 if (CompilerFactory::CompilerInheritsFrom(buildTarget->GetCompilerID(), _T("ifcwin"))) 419 cstr << _T("\t$(FC) $(CFLAGS) /c ") << sdir << _T("$(@:.o=.") << ext << _T(")") << _T(" /object: $(OBJS_DIR)$@\n"); 420 else 421 cstr << _T("\t$(FC) $(CFLAGS) -c ") << sdir << _T("$(@:.o=.") << ext << _T(")") << _T(" -o $(OBJS_DIR)$@\n"); 422 423 mfile.Write(cstr); 424 } 425 426 wxString clean; 427 clean << _T("\nclean :\n"); 428 clean << _T("\trm -f $(OBJS_DIR)*.*\n"); 429 clean << _T("\trm -f $(EXE_DIR)$(EXE)\n"); 430 mfile.Write(clean); 431 432 mfile.Write(_T("\n# Dependencies of files\n")); 433 mfile.Write(depsFiles); 434 mfile.Write(_T("\n")); 435 436 437 if (containsNonFortranFiles) 438 cbMessageBox(_("The build target includes non Fortran files. They were added to the list of files, however the plugin doesn't know how to handle these files correctly."), _("Warning"), wxICON_WARNING); 439 440 wxString msg = _("The make file \""); 441 msg << mffn.GetFullPath(); 442 msg << _("\" was generated seccessfully."); 443 cbMessageBox(msg); 444 } 445 446 bool MakefileGen::SelectMikefileName(wxFileName& mffn) 447 { 448 MakefileDlg mfdlg(Manager::Get()->GetAppWindow()); 449 mfdlg.SetFilename(mffn.GetFullPath()); 450 int imax = 5; 451 int i; 452 for (i=0; i<imax; i++) 453 { 454 if (mfdlg.ShowModal() != wxID_OK) 455 return false; 456 mffn = mfdlg.GetFilename(); 457 if (!mffn.IsOk()) 458 { 459 cbMessageBox(_("Error in the file name!"), _("Error"), wxICON_ERROR); 460 continue; 461 } 462 463 if (mffn.FileExists()) 464 { 465 int answ = cbMessageBox(_T("File \"")+mffn.GetFullPath()+_T("\" already exist.\nWould you like to overwrite it?"), _("Question"), wxYES_NO | wxICON_QUESTION); 466 if (answ == wxID_YES) 467 break; 468 } 469 else 470 break; 471 } 472 473 if (i == imax) 474 { 475 cbMessageBox(_("I am tired. Maybe next time..."), _("Info"), wxICON_INFORMATION); 476 return false; 477 } 478 return true; 479 } 480