2 * Copyright (C) 2006 Christoph von Wittich
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #pragma warning ( disable : 4786 )
29 #include "codeblocks.h"
30 #include "../mingw/mingw.h"
40 #define IsStaticLibrary( module ) ( ( module.type == StaticLibrary ) || ( module.type == HostStaticLibrary ) )
42 static class CBFactory
: public Backend::Factory
46 CBFactory() : Factory("CB", "Code::Blocks") {}
47 Backend
*operator() (Project
&project
,
48 Configuration
& configuration
)
50 return new CBBackend(project
, configuration
);
56 CBBackend::CBBackend(Project
&project
,
57 Configuration
& configuration
) : Backend(project
, configuration
)
62 void CBBackend::Process()
65 while ( m_configurations
.size () > 0 )
67 const CBConfiguration
* cfg
= m_configurations
.back();
68 m_configurations
.pop_back();
72 m_configurations
.push_back ( new CBConfiguration( Debug
));
73 m_configurations
.push_back ( new CBConfiguration( Release
));
75 string
filename_wrkspace ( ProjectNode
.name
);
76 filename_wrkspace
+= "_auto.workspace";
78 printf ( "Creating Code::Blocks workspace: %s\n", filename_wrkspace
.c_str() );
81 m_wrkspaceFile
= fopen ( filename_wrkspace
.c_str(), "wb" );
83 if ( !m_wrkspaceFile
)
85 printf ( "Could not create file '%s'.\n", filename_wrkspace
.c_str() );
89 _generate_workspace ( m_wrkspaceFile
);
91 fclose ( m_wrkspaceFile
);
95 void CBBackend::ProcessModules()
97 for( std::map
<std::string
, Module
*>::const_iterator p
= ProjectNode
.modules
.begin(); p
!= ProjectNode
.modules
.end(); ++ p
)
99 Module
&module
= *p
->second
;
100 MingwAddImplicitLibraries( module
);
101 _generate_cbproj ( module
);
106 GetExtension ( const std::string
& filename
)
108 size_t index
= filename
.find_last_of ( '/' );
109 if (index
== string::npos
) index
= 0;
110 string tmp
= filename
.substr( index
, filename
.size() - index
);
111 size_t ext_index
= tmp
.find_last_of( '.' );
112 if (ext_index
!= string::npos
)
113 return filename
.substr ( index
+ ext_index
, filename
.size() );
117 static bool FileExists(string
&filename
)
119 ifstream
file(filename
.c_str());
128 void CBBackend::ProcessFile(string
&filepath
)
130 // Remove the .\ at the start of the filenames
131 if ( filepath
[0] == '.' && strchr ( "/\\", filepath
[1] ) )
132 filepath
.erase(0, 2);
134 if(!FileExists(filepath
))
138 for(size_t i
= 0; i
< filepath
.length(); i
++)
140 if(filepath
[i
] == '\\')
144 // Remove the filename from the path
147 size_t pos
= filepath
.rfind(string("/"), filepath
.length() - 1);
149 if(pos
!= string::npos
)
152 folder
.erase(pos
, folder
.length() - pos
);
156 fileUnit
.filename
= filepath
;
157 fileUnit
.folder
= folder
;
159 m_fileUnits
.push_back(fileUnit
);
167 bool CBBackend::CheckFolderAdded(string
&folder
)
169 for(size_t i
= 0; i
< m_folders
.size(); i
++)
171 if(m_folders
[i
] == folder
)
178 void CBBackend::AddFolders(string
&folder
)
180 // Check if this folder was already added. true if it was, false otherwise.
181 if(CheckFolderAdded(folder
))
184 m_folders
.push_back(folder
);
186 size_t pos
= folder
.rfind(string("/"), folder
.length() - 1);
188 if(pos
== string::npos
)
191 folder
.erase(pos
, folder
.length() - pos
);
195 void CBBackend::OutputFolders()
198 m_devFile
<< "Folders=";
200 for(size_t i
= 0; i
< m_folders
.size(); i
++)
205 m_devFile
<< m_folders
[i
];
211 CBBackend::CbpFileName ( const Module
& module
) const
214 ReplaceExtension ( module
.output
->relative_path
+ sSep
+ module
.output
->name
, "_auto.cbp" )
219 CBBackend::LayoutFileName ( const Module
& module
) const
222 ReplaceExtension ( module
.output
->relative_path
+ sSep
+ module
.output
->name
, "_auto.layout" )
227 CBBackend::DependFileName ( const Module
& module
) const
230 ReplaceExtension ( module
.output
->relative_path
+ sSep
+ module
.output
->name
, "_auto.depend" )
235 CBBackend::_get_object_files ( const Module
& module
, vector
<string
>& out
) const
237 string basepath
= module
.output
->relative_path
;
239 string intenv
= Environment::GetIntermediatePath () + sSep
+ basepath
+ sSep
;
240 string outenv
= Environment::GetOutputPath () + sSep
+ basepath
+ sSep
;
244 if ( configuration
.UseConfigurationInPath
)
246 cfgs
.push_back ( intenv
+ "Debug" );
247 cfgs
.push_back ( intenv
+ "Release" );
248 cfgs
.push_back ( outenv
+ "Debug" );
249 cfgs
.push_back ( outenv
+ "Release" );
253 cfgs
.push_back ( intenv
);
254 cfgs
.push_back ( outenv
);
257 vector
<const IfableData
*> ifs_list
;
258 ifs_list
.push_back ( &module
.project
.non_if_data
);
259 ifs_list
.push_back ( &module
.non_if_data
);
260 while ( ifs_list
.size () )
262 const IfableData
& data
= *ifs_list
.back();
264 const vector
<File
*>& files
= data
.files
;
265 for ( i
= 0; i
< files
.size (); i
++ )
267 string file
= files
[i
]->file
.relative_path
+ sSep
+ files
[i
]->file
.name
;
268 string::size_type pos
= file
.find_last_of (sSep
);
269 if ( pos
!= string::npos
)
270 file
.erase ( 0, pos
+1 );
271 if ( !stricmp ( Right(file
,3).c_str(), ".rc" ) )
272 file
= ReplaceExtension ( file
, ".res" );
274 file
= ReplaceExtension ( file
, ".obj" );
275 for ( size_t j
= 0; j
< cfgs
.size () / 2; j
++ )
276 out
.push_back ( cfgs
[j
] + sSep
+ file
);
283 CBBackend::_clean_project_files ( void )
285 for( std::map
<std::string
, Module
*>::const_iterator p
= ProjectNode
.modules
.begin(); p
!= ProjectNode
.modules
.end(); ++ p
)
287 Module
& module
= *p
->second
;
289 printf("Cleaning project %s %s\n", module
.name
.c_str (), module
.output
->relative_path
.c_str () );
291 string basepath
= module
.output
->relative_path
;
292 remove ( CbpFileName ( module
).c_str () );
293 remove ( DependFileName ( module
).c_str () );
294 remove ( LayoutFileName ( module
).c_str () );
296 _get_object_files ( module
, out
);
297 for ( size_t j
= 0; j
< out
.size (); j
++)
299 //printf("Cleaning file %s\n", out[j].c_str () );
300 remove ( out
[j
].c_str () );
304 string filename_wrkspace
= ProjectNode
.name
+ ".workspace";
306 remove ( filename_wrkspace
.c_str () );
310 CBBackend::_generate_workspace ( FILE* OUT
)
312 fprintf ( OUT
, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\r\n" );
313 fprintf ( OUT
, "<CodeBlocks_workspace_file>\r\n" );
314 fprintf ( OUT
, "\t<Workspace title=\"ReactOS\">\r\n" );
315 for( std::map
<std::string
, Module
*>::const_iterator p
= ProjectNode
.modules
.begin(); p
!= ProjectNode
.modules
.end(); ++ p
)
317 Module
& module
= *p
->second
;
319 if ((module
.type
!= Iso
) &&
320 (module
.type
!= LiveIso
))
322 std::string Cbp_file
= CbpFileName ( module
);
323 fprintf ( OUT
, "\t\t<Project filename=\"%s\">\r\n", Cbp_file
.c_str());
326 vector
<const IfableData
*> ifs_list
;
327 ifs_list
.push_back ( &module
.project
.non_if_data
);
328 ifs_list
.push_back ( &module
.non_if_data
);
329 while ( ifs_list
.size() )
331 const IfableData
& data
= *ifs_list
.back();
333 const vector
<Library
*>& libs
= data
.libraries
;
334 for ( size_t j
= 0; j
< libs
.size(); j
++ )
335 fprintf ( OUT
, "\t\t\t<Depends filename=\"%s%s%s_auto.cbp\" />\r\n", libs
[j
]->importedModule
->output
->relative_path
.c_str(), sSep
.c_str(), libs
[j
]->name
.c_str() );
337 fprintf ( OUT
, "\t\t</Project>\r\n" );
340 fprintf ( OUT
, "\t</Workspace>\r\n" );
341 fprintf ( OUT
, "</CodeBlocks_workspace_file>\r\n" );
345 CBBackend::_generate_cbproj ( const Module
& module
)
350 string cbproj_file
= CbpFileName(module
);
353 string path_basedir
= module
.GetPathToBaseDir ();
354 string intenv
= Environment::GetIntermediatePath ();
355 string outenv
= Environment::GetOutputPath ();
356 string module_type
= GetExtension(*module
.output
);
357 string cbproj_path
= module
.output
->relative_path
;
360 string windres_defines
;
362 string project_linker_flags
= "-Wl,--enable-stdcall-fixup ";
363 project_linker_flags
+= GenerateProjectLinkerFlags();
365 bool lib
= (module
.type
== ObjectLibrary
) ||
366 (module
.type
== RpcClient
) ||
367 (module
.type
== RpcServer
) ||
368 (module
.type
== RpcProxy
) ||
369 (module_type
== ".lib") ||
370 (module_type
== ".a");
371 bool dll
= (module_type
== ".dll") || (module_type
== ".cpl");
372 bool exe
= (module_type
== ".exe") || (module_type
== ".scr");
373 bool sys
= (module_type
== ".sys");
375 vector
<string
> source_files
, resource_files
, includes
, libraries
, libpaths
;
376 vector
<string
> header_files
, common_defines
, compiler_flags
;
377 vector
<string
> vars
, values
;
379 /* do not create project files for these targets
380 use virtual targets instead */
390 compiler_flags
.push_back ( "-Wall" );
392 // Always force disabling of sibling calls optimisation for GCC
393 // (TODO: Move to version-specific once this bug is fixed in GCC)
394 compiler_flags
.push_back ( "-fno-optimize-sibling-calls" );
396 if ( module
.pch
!= NULL
)
398 string pch_path
= Path::RelativeFromDirectory (
399 module
.pch
->file
->name
,
400 module
.output
->relative_path
);
402 header_files
.push_back ( pch_path
);
405 if ( intenv
== "obj-i386" )
406 intdir
= path_basedir
+ "obj-i386"; /* append relative dir from project dir */
410 if ( outenv
== "output-i386" )
411 outdir
= path_basedir
+ "output-i386";
415 vector
<const IfableData
*> ifs_list
;
416 ifs_list
.push_back ( &module
.project
.non_if_data
);
417 ifs_list
.push_back ( &module
.non_if_data
);
418 while ( ifs_list
.size() )
420 const IfableData
& data
= *ifs_list
.back();
422 const vector
<File
*>& files
= data
.files
;
423 for ( i
= 0; i
< files
.size(); i
++ )
425 string fullpath
= files
[i
]->file
.relative_path
+ sSep
+ files
[i
]->file
.name
;
426 string file
= string(".") + &fullpath
[cbproj_path
.size()];
428 if ( !stricmp ( Right(file
,3).c_str(), ".rc" ) )
429 resource_files
.push_back ( file
);
431 source_files
.push_back ( file
);
433 const vector
<Include
*>& incs
= data
.includes
;
434 for ( i
= 0; i
< incs
.size(); i
++ )
436 string path
= Path::RelativeFromDirectory (
437 incs
[i
]->directory
->relative_path
,
438 module
.output
->relative_path
);
440 includes
.push_back ( path
);
441 widl_options
+= "-I" + path
+ " ";
443 const vector
<Library
*>& libs
= data
.libraries
;
444 for ( i
= 0; i
< libs
.size(); i
++ )
446 string libpath
= intdir
+ sSep
+ libs
[i
]->importedModule
->output
->relative_path
;
447 libraries
.push_back ( libs
[i
]->name
);
448 libpaths
.push_back ( libpath
);
450 const vector
<CompilerFlag
*>& cflags
= data
.compilerFlags
;
451 for ( i
= 0; i
< cflags
.size(); i
++ )
453 compiler_flags
.push_back ( cflags
[i
]->flag
);
455 const vector
<Define
*>& defs
= data
.defines
;
456 for ( i
= 0; i
< defs
.size(); i
++ )
458 if ( defs
[i
]->value
[0] )
460 const string
& escaped
= _replace_str(defs
[i
]->value
, "\"",""");
461 common_defines
.push_back( defs
[i
]->name
+ "=" + escaped
);
462 windres_defines
+= "-D" + defs
[i
]->name
+ "=" + escaped
+ " ";
466 common_defines
.push_back( defs
[i
]->name
);
467 windres_defines
+= "-D" + defs
[i
]->name
+ " ";
470 /*const vector<Property*>& variables = data.properties;
471 for ( i = 0; i < variables.size(); i++ )
473 vars.push_back( variables[i]->name );
474 values.push_back( variables[i]->value );
476 for ( std::map
<std::string
, Property
*>::const_iterator p
= data
.properties
.begin(); p
!= data
.properties
.end(); ++ p
)
478 Property
& prop
= *p
->second
;
479 if ( strstr ( module
.baseaddress
.c_str(), prop
.name
.c_str() ) )
480 baseaddr
= prop
.value
;
484 if ( !module
.allowWarnings
)
485 compiler_flags
.push_back ( "-Werror" );
487 if ( IsStaticLibrary ( module
) && module
.isStartupLib
)
488 compiler_flags
.push_back ( "-Wno-main" );
491 FILE* OUT
= fopen ( cbproj_file
.c_str(), "wb" );
493 fprintf ( OUT
, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\r\n" );
494 fprintf ( OUT
, "<CodeBlocks_project_file>\r\n" );
495 fprintf ( OUT
, "\t<FileVersion major=\"1\" minor=\"6\" />\r\n" );
496 fprintf ( OUT
, "\t<Project>\r\n" );
497 fprintf ( OUT
, "\t\t<Option title=\"%s\" />\r\n", module
.name
.c_str() );
498 fprintf ( OUT
, "\t\t<Option pch_mode=\"2\" />\r\n" );
499 fprintf ( OUT
, "\t\t<Option default_target=\"\" />\r\n" );
500 fprintf ( OUT
, "\t\t<Option compiler=\"gcc\" />\r\n" );
501 fprintf ( OUT
, "\t\t<Option extended_obj_names=\"1\" />\r\n" );
502 fprintf ( OUT
, "\t\t<Option virtualFolders=\"\" />\r\n" );
503 fprintf ( OUT
, "\t\t<Build>\r\n" );
505 bool console
= exe
&& (module
.type
== Win32CUI
);
507 for ( size_t icfg
= 0; icfg
< m_configurations
.size(); icfg
++ )
509 const CBConfiguration
& cfg
= *m_configurations
[icfg
];
510 fprintf ( OUT
, "\t\t\t<Target title=\"%s\">\r\n", cfg
.name
.c_str() );
512 if ( configuration
.UseConfigurationInPath
)
514 if ( IsStaticLibrary ( module
) ||module
.type
== ObjectLibrary
)
515 fprintf ( OUT
, "\t\t\t\t<Option output=\"%s%s%s%s%s%s%s\" prefix_auto=\"0\" extension_auto=\"0\" />\r\n", intdir
.c_str (), sSep
.c_str(), module
.output
->relative_path
.c_str (), cfg
.name
.c_str(), sSep
.c_str(), module
.name
.c_str(), module_type
.c_str());
517 fprintf ( OUT
, "\t\t\t\t<Option output=\"%s%s%s%s%s%s%s\" prefix_auto=\"0\" extension_auto=\"0\" />\r\n", outdir
.c_str (), sSep
.c_str(), module
.output
->relative_path
.c_str (), cfg
.name
.c_str(), sSep
.c_str(), module
.name
.c_str(), module_type
.c_str());
518 fprintf ( OUT
, "\t\t\t\t<Option object_output=\"%s%s%s%s\" />\r\n", intdir
.c_str(), sSep
.c_str(), module
.output
->relative_path
.c_str (), cfg
.name
.c_str() );
522 if ( IsStaticLibrary ( module
) || module
.type
== ObjectLibrary
)
523 fprintf ( OUT
, "\t\t\t\t<Option output=\"%s%s%s%s%s%s\" prefix_auto=\"0\" extension_auto=\"0\" />\r\n", intdir
.c_str (), sSep
.c_str(), module
.output
->relative_path
.c_str (), sSep
.c_str(), module
.name
.c_str(), module_type
.c_str() );
525 fprintf ( OUT
, "\t\t\t\t<Option output=\"%s%s%s%s%s%s\" prefix_auto=\"0\" extension_auto=\"0\" />\r\n", outdir
.c_str (), sSep
.c_str(), module
.output
->relative_path
.c_str (), sSep
.c_str(), module
.name
.c_str(), module_type
.c_str() );
526 fprintf ( OUT
, "\t\t\t\t<Option object_output=\"%s%s%s\" />\r\n", intdir
.c_str(), sSep
.c_str(), module
.output
->relative_path
.c_str () );
531 fprintf ( OUT
, "\t\t\t\t<Option type=\"2\" />\r\n" );
534 fprintf ( OUT
, "\t\t\t\t<Option type=\"3\" />\r\n" );
536 fprintf ( OUT
, "\t\t\t\t<Option type=\"5\" />\r\n" );
539 if ( module
.type
== Kernel
)
540 fprintf ( OUT
, "\t\t\t\t<Option type=\"5\" />\r\n" );
541 else if ( module
.type
== NativeCUI
)
542 fprintf ( OUT
, "\t\t\t\t<Option type=\"5\" />\r\n" );
543 else if ( module
.type
== Win32CUI
|| module
.type
== Win32GUI
|| module
.type
== Win32SCR
)
546 fprintf ( OUT
, "\t\t\t\t<Option type=\"1\" />\r\n" );
548 fprintf ( OUT
, "\t\t\t\t<Option type=\"0\" />\r\n" );
552 fprintf ( OUT
, "\t\t\t\t<Option compiler=\"gcc\" />\r\n" );
554 if ( module_type
== ".cpl" )
556 fprintf ( OUT
, "\t\t\t\t<Option parameters=\"shell32,Control_RunDLL "$exe_output",@\" />\r\n" );
557 fprintf ( OUT
, "\t\t\t\t<Option host_application=\"rundll32.exe\" />\r\n" );
559 fprintf ( OUT
, "\t\t\t\t<Compiler>\r\n" );
561 bool debug
= ( cfg
.optimization
== Debug
);
564 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-g\" />\r\n" );
567 for ( i
= 0; i
< compiler_flags
.size(); i
++ )
569 const string
& cflag
= compiler_flags
[i
];
570 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"%s\" />\r\n", cflag
.c_str() );
574 for ( i
= 0; i
< common_defines
.size(); i
++ )
576 const string
& define
= common_defines
[i
];
577 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-D%s\" />\r\n", define
.c_str() );
580 for ( i
= 0; i
< includes
.size(); i
++ )
582 const string
& include
= includes
[i
];
583 fprintf ( OUT
, "\t\t\t\t\t<Add directory=\"%s\" />\r\n", include
.c_str() );
585 fprintf ( OUT
, "\t\t\t\t</Compiler>\r\n" );
588 fprintf ( OUT
, "\t\t\t\t<ResourceCompiler>\r\n" );
589 for ( i
= 0; i
< includes
.size(); i
++ )
591 const string
& include
= includes
[i
];
592 fprintf ( OUT
, "\t\t\t\t\t<Add directory=\"%s\" />\r\n", include
.c_str() );
594 fprintf ( OUT
, "\t\t\t\t</ResourceCompiler>\r\n" );
596 fprintf ( OUT
, "\t\t\t\t<Linker>\r\n" );
597 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"%s\" />\r\n", project_linker_flags
.c_str() );
601 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-Wl,--entry,%s%s\" />\r\n", "_", module
.GetEntryPoint(false) == "" ? "DriverEntry@8" : module
.GetEntryPoint(false).c_str ());
602 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-Wl,--image-base,%s\" />\r\n", baseaddr
== "" ? "0x10000" : baseaddr
.c_str () );
603 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-nostartfiles -Wl,--nostdlib\" />\r\n" );
607 if ( module
.type
== Kernel
)
609 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-Wl,--entry,_KiSystemStartup\" />\r\n" );
610 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-Wl,--image-base,%s\" />\r\n", baseaddr
.c_str () );
612 else if ( module
.type
== NativeCUI
)
614 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-Wl,--entry,_NtProcessStartup@4\" />\r\n" );
615 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-Wl,--image-base,%s\" />\r\n", baseaddr
.c_str () );
616 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-nostartfiles -Wl,--nostdlib\" />\r\n" );
620 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"%s\" />\r\n", module
.cplusplus
? "-nostartfiles" : "-nostartfiles -Wl,--nostdlib" );
621 fprintf ( OUT
, "\t\t\t\t\t<Add library=\"gcc\" />\r\n" );
626 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-Wl,--entry,%s%s\" />\r\n", "_", module
.GetEntryPoint(false).c_str () );
627 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-Wl,--image-base,%s\" />\r\n", baseaddr
== "" ? "0x40000" : baseaddr
.c_str () );
629 if ( module
.type
== Win32DLL
)
630 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-Wl,--shared\" />\r\n" );
631 else if ( module
.type
== NativeDLL
)
632 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-Wl,--shared\" />\r\n" );
633 else if ( module
.type
== NativeDLL
)
634 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-nostartfiles -Wl,--shared\" />\r\n" );
636 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"%s\" />\r\n", module
.cplusplus
? "-nostartfiles" : "-nostartfiles -Wl,--nostdlib" );
637 fprintf ( OUT
, "\t\t\t\t\t<Add library=\"gcc\" />\r\n" );
640 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-Wl,--file-alignment,0x1000\" />\r\n" );
641 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"-Wl,--section-alignment,0x1000\" />\r\n" );
644 fprintf ( OUT
, "\t\t\t\t\t<Add option=\"%s.temp.exp\" />\r\n", module
.name
.c_str() );
647 for ( i
= 0; i
< libraries
.size(); i
++ )
649 const string
& lib
= libraries
[i
];
650 fprintf ( OUT
, "\t\t\t\t\t<Add library=\"%s\" />\r\n", lib
.c_str() );
652 for ( i
= 0; i
< libpaths
.size(); i
++ )
654 const string
& lib
= libpaths
[i
];
655 fprintf ( OUT
, "\t\t\t\t\t<Add directory=\"%s\" />\r\n", lib
.c_str() );
657 fprintf ( OUT
, "\t\t\t\t</Linker>\r\n" );
659 fprintf ( OUT
, "\t\t\t\t<ExtraCommands>\r\n" );
662 if ( IsStaticLibrary ( module
) && module
.importLibrary
)
663 fprintf ( OUT
, "\t\t\t\t\t<Add after=\"dlltool --dllname %s --def %s --output-lib $exe_output; %s -U\" />\r\n", module
.importLibrary
->dllname
.c_str (), module
.importLibrary
->definition
.c_str(), module
.mangledSymbols
? "" : "--kill-at" );
664 else if ( module
.importLibrary
!= NULL
)
665 fprintf ( OUT
, "\t\t\t\t\t<Add after=\"dlltool --dllname %s --def %s --output-lib "$(TARGET_OBJECT_DIR)lib$(TARGET_OUTPUT_BASENAME).a" %s\" />\r\n", module
.GetTargetName ().c_str(), module
.importLibrary
->definition
.c_str(), module
.mangledSymbols
? "" : "--kill-at" );
669 for ( i
= 0; i
< resource_files
.size(); i
++ )
671 const string
& resource_file
= resource_files
[i
];
673 fprintf ( OUT
, "\t\t\t\t\t<Add after=\"cmd /c del $(TARGET_OBJECT_DIR)%s%s.rci.tmp 2>NUL\" />\r\n", sSep
.c_str(), resource_file
.c_str() );
674 fprintf ( OUT
, "\t\t\t\t\t<Add after=\"cmd /c del $(TARGET_OBJECT_DIR)%s%s.res.tmp 2>NUL\" />\r\n", sSep
.c_str(), resource_file
.c_str() );
676 fprintf ( OUT
, "\t\t\t\t\t<Add after=\"rm $(TARGET_OBJECT_DIR)/%s.rci.tmp 2>/dev/null\" />\r\n", resource_file
.c_str() );
677 fprintf ( OUT
, "\t\t\t\t\t<Add after=\"rm $(TARGET_OBJECT_DIR)/%s.res.tmp 2>/dev/null\" />\r\n", resource_file
.c_str() );
684 if (IsSpecDefinitionFile( module
))
685 fprintf ( OUT
, "\t\t\t\t\t<Add before=\"%s%stools%swinebuild%swinebuild.exe -o %s --def -E %s.spec\" />\r\n", outdir
.c_str(), sSep
, sSep
, sSep
, module
.importLibrary
->definition
.c_str(), module
.name
.c_str());
686 fprintf ( OUT
, "\t\t\t\t\t<Add before=\"dlltool --dllname %s --def %s --output-exp %s.temp.exp %s\" />\r\n", module
.GetTargetName ().c_str(), module
.importLibrary
->definition
.c_str(), module
.name
.c_str(), module
.mangledSymbols
? "" : "--kill-at" );
687 fprintf ( OUT
, "\t\t\t\t\t<Add after=\"%s%stools%spefixup $exe_output -exports\" />\r\n", outdir
.c_str(), sSep
, sSep
);
689 fprintf ( OUT
, "\t\t\t\t\t<Add after=\"cmd /c del %s.temp.exp 2>NUL\" />\r\n", module
.name
.c_str() );
691 fprintf ( OUT
, "\t\t\t\t\t<Add after=\"rm %s.temp.exp 2>/dev/null\" />\r\n", module
.name
.c_str() );
693 fprintf ( OUT
, "\t\t\t\t\t<Mode after=\"always\" />\r\n" );
697 fprintf ( OUT
, "\t\t\t\t</ExtraCommands>\r\n" );
699 fprintf ( OUT
, "\t\t\t</Target>\r\n" );
704 fprintf ( OUT, "\t\t\t<Environment>\r\n" );
705 for ( i = 0; i < vars.size(); i++ )
707 const string& var = vars[i];
708 const string& value = values[i];
709 fprintf ( OUT, "\t\t\t\t<Variable name=\"%s\" value=\"%s\" />\r\n", var.c_str(), value.c_str() );
711 fprintf ( OUT, "\t\t\t</Environment>\r\n" ); */
713 fprintf ( OUT
, "\t\t</Build>\r\n" );
718 if ( module
.cplusplus
)
725 for ( i
= 0; i
< header_files
.size(); i
++ )
727 const string
& header_file
= header_files
[i
];
728 fprintf ( OUT
, "\t\t<Unit filename=\"%s\">\r\n", header_file
.c_str() );
729 fprintf ( OUT
, "\t\t\t<Option compilerVar=\"%s\" />\r\n", CompilerVar
.c_str() );
730 fprintf ( OUT
, "\t\t\t<Option compile=\"0\" />\r\n" );
731 fprintf ( OUT
, "\t\t\t<Option link=\"0\" />\r\n" );
732 for ( size_t icfg
= 0; icfg
< m_configurations
.size(); icfg
++ )
734 const CBConfiguration
& cfg
= *m_configurations
[icfg
];
735 fprintf ( OUT
, "\t\t\t<Option target=\"%s\" />\r\n" , cfg
.name
.c_str() );
737 fprintf ( OUT
, "\t\t</Unit>\r\n" );
741 for ( size_t isrcfile
= 0; isrcfile
< source_files
.size(); isrcfile
++ )
743 string source_file
= DosSeparator(source_files
[isrcfile
]);
744 fprintf ( OUT
, "\t\t<Unit filename=\"%s\">\r\n", source_file
.c_str() );
745 fprintf ( OUT
, "\t\t\t<Option compilerVar=\"%s\" />\r\n", CompilerVar
.c_str() );
747 string extension
= GetExtension ( source_file
);
748 if ( extension
== ".s" || extension
== ".S" )
750 fprintf ( OUT
, "\t\t\t<Option compile=\"1\" />\r\n" );
751 fprintf ( OUT
, "\t\t\t<Option link=\"1\" />\r\n" );
752 fprintf ( OUT
, "\t\t\t<Option compiler=\"gcc\" use=\"1\" buildCommand=\"gcc -x assembler-with-cpp -c $file -o $link_objects $includes -D__ASM__ $options\" />\r\n" );
754 else if ( extension
== ".asm" || extension
== ".ASM" )
756 fprintf ( OUT
, "\t\t\t<Option compile=\"1\" />\r\n" );
757 fprintf ( OUT
, "\t\t\t<Option link=\"1\" />\r\n" );
758 fprintf ( OUT
, "\t\t\t<Option compiler=\"gcc\" use=\"1\" buildCommand=\"nasm -f win32 $file -o $link_objects\" />\r\n" );
760 else if ( extension
== ".idl" || extension
== ".IDL" )
762 fprintf ( OUT
, "\t\t\t<Option compile=\"1\" />\r\n" );
763 fprintf ( OUT
, "\t\t\t<Option compiler=\"gcc\" use=\"1\" buildCommand=\"%s%stools%swidl%swidl.exe %s %s -h -H "$(TARGET_OUTPUT_DIR)$filetitle_c.h" -c -C "$(TARGET_OUTPUT_DIR)$filetitle_c.c" $file%sngcc %s -c "$(TARGET_OUTPUT_DIR)$filetitle_c.c" -o "$(TARGET_OUTPUT_DIR)$file_c.o"\" />\r\n", outdir
.c_str(), sSep
.c_str(), sSep
.c_str(), sSep
.c_str(), widl_options
.c_str(), windres_defines
.c_str(), sSep
.c_str(), widl_options
.c_str() );
765 else if ( extension
== ".spec" || extension
== ".SPEC" )
767 fprintf ( OUT
, "\t\t\t<Option compile=\"1\" />\r\n" );
768 fprintf ( OUT
, "\t\t\t<Option link=\"1\" />\r\n" );
769 fprintf ( OUT
, "\t\t\t<Option compiler=\"gcc\" use=\"1\" buildCommand=\"%s%stools%swinebuild%swinebuild.exe -o $file.stubs.c --pedll $file\\n$compiler -c $options $includes $file.stubs.c -o $(TARGET_OBJECT_DIR)%s$file.o\" />\r\n", outdir
.c_str(), sSep
.c_str(), sSep
.c_str(), sSep
.c_str(), sSep
.c_str() );
772 for ( size_t icfg
= 0; icfg
< m_configurations
.size(); icfg
++ )
774 const CBConfiguration
& cfg
= *m_configurations
[icfg
];
775 fprintf ( OUT
, "\t\t\t<Option target=\"%s\" />\r\n" , cfg
.name
.c_str() );
777 fprintf ( OUT
, "\t\t</Unit>\r\n" );
781 for ( i
= 0; i
< resource_files
.size(); i
++ )
783 const string
& resource_file
= resource_files
[i
];
784 fprintf ( OUT
, "\t\t<Unit filename=\"%s\">\r\n", resource_file
.c_str() );
785 fprintf ( OUT
, "\t\t\t<Option compilerVar=\"WINDRES\" />\r\n" );
786 string extension
= GetExtension ( resource_file
);
787 fprintf ( OUT
, "\t\t\t<Option compiler=\"gcc\" use=\"1\" buildCommand=\"gcc -xc -E -DRC_INVOKED $includes %s $file -o $(TARGET_OBJECT_DIR)%s$file.rci.tmp\\n%s%stools%swrc%swrc.exe $includes %s $(TARGET_OBJECT_DIR)%s$file.rci.tmp $(TARGET_OBJECT_DIR)%s$file.res.tmp\\n$rescomp --output-format=coff $(TARGET_OBJECT_DIR)%s$file.res.tmp -o $resource_output\" />\r\n" , windres_defines
.c_str(), sSep
.c_str(), outdir
.c_str(), sSep
.c_str(), sSep
.c_str(), sSep
.c_str(), windres_defines
.c_str(), sSep
.c_str(), sSep
.c_str(), sSep
.c_str() );
788 for ( size_t icfg
= 0; icfg
< m_configurations
.size(); icfg
++ )
790 const CBConfiguration
& cfg
= *m_configurations
[icfg
];
791 fprintf ( OUT
, "\t\t\t<Option target=\"%s\" />\r\n" , cfg
.name
.c_str() );
793 fprintf ( OUT
, "\t\t</Unit>\r\n" );
796 fprintf ( OUT
, "\t\t<Extensions />\r\n" );
797 fprintf ( OUT
, "\t</Project>\r\n" );
798 fprintf ( OUT
, "</CodeBlocks_project_file>\r\n" );
804 CBConfiguration::CBConfiguration ( const OptimizationType optimization
, const std::string
&name
)
806 this->optimization
= optimization
;
811 if ( optimization
== Debug
)
812 this->name
= "Debug";
813 else if ( optimization
== Release
)
814 this->name
= "Release";
816 this->name
= "Unknown";
821 CBBackend::_replace_str(std::string string1
, const std::string
&find_str
, const std::string
&replace_str
)
823 std::string::size_type pos
= string1
.find(find_str
, 0);
824 int intLen
= find_str
.length();
826 while(std::string::npos
!= pos
)
828 string1
.replace(pos
, intLen
, replace_str
);
829 pos
= string1
.find(find_str
, intLen
+ pos
);
836 CBBackend::GenerateProjectLinkerFlags() const
839 for ( size_t i
= 0; i
< ProjectNode
.linkerFlags
.size (); i
++ )
841 LinkerFlag
& linkerFlag
= *ProjectNode
.linkerFlags
[i
];
842 if ( lflags
.length () > 0 )
844 lflags
+= linkerFlag
.flag
;
850 CBBackend::MingwAddImplicitLibraries( Module
&module
)
854 if ( !module
.isDefaultEntryPoint
)
857 if ( module
.IsDLL () )
859 //pLibrary = new Library ( module, "__mingw_dllmain" );
860 //module.non_if_data.libraries.insert ( module.non_if_data.libraries.begin(), pLibrary );
864 pLibrary
= new Library ( module
, module
.isUnicode
? "mingw_wmain" : "mingw_main" );
865 module
.non_if_data
.libraries
.insert ( module
.non_if_data
.libraries
.begin(), pLibrary
);
868 pLibrary
= new Library ( module
, "mingw_common" );
869 module
.non_if_data
.libraries
.insert ( module
.non_if_data
.libraries
.begin() + 1, pLibrary
);
871 if ( module
.name
!= "msvcrt" )
873 // always link in msvcrt to get the basic routines
874 pLibrary
= new Library ( module
, "msvcrt" );
875 module
.non_if_data
.libraries
.push_back ( pLibrary
);
880 CBBackend::_lookup_property ( const Module
& module
, const std::string
& name
) const
882 std::map
<std::string
, Property
*>::const_iterator p
;
884 /* Check local values */
885 p
= module
.non_if_data
.properties
.find(name
);
887 if ( p
!= module
.non_if_data
.properties
.end() )
890 // TODO FIXME - should we check local if-ed properties?
891 p
= module
.project
.non_if_data
.properties
.find(name
);
893 if ( p
!= module
.project
.non_if_data
.properties
.end() )
896 // TODO FIXME - should we check global if-ed properties?
901 CBBackend::IsSpecDefinitionFile ( const Module
& module
) const
903 if ( module
.importLibrary
== NULL
)
906 size_t index
= module
.importLibrary
->source
->name
.rfind ( ".spec" );
907 return ( index
!= string::npos
);