mirror of
https://github.com/gnustep/apps-projectcenter.git
synced 2025-02-16 00:20:58 +00:00
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/apps/projectcenter/trunk@39155 72102866-910b-0410-8b05-ffd578937521
604 lines
17 KiB
Objective-C
604 lines
17 KiB
Objective-C
/*
|
|
GNUstep ProjectCenter - http://www.gnustep.org/experience/ProjectCenter.html
|
|
|
|
Copyright (C) 2002-2014 Free Software Foundation
|
|
|
|
Authors: Philippe C.D. Robert
|
|
Serg Stoyan
|
|
Riccardo Mottola
|
|
|
|
This file is part of GNUstep.
|
|
|
|
This application is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This application is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public
|
|
License along with this library; if not, write to the Free
|
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
|
*/
|
|
|
|
#import <ProjectCenter/PCDefines.h>
|
|
#import <ProjectCenter/PCProjectManager.h>
|
|
#import <ProjectCenter/PCProject.h>
|
|
#import <ProjectCenter/PCMakefileFactory.h>
|
|
|
|
#import <Protocols/Preferences.h>
|
|
#import "../Modules/Preferences/Build/PCBuildPrefs.h"
|
|
|
|
#define COMMENT_HEADERS @"\n\n#\n# Header files\n#\n"
|
|
#define COMMENT_RESOURCES @"\n\n#\n# Resource files\n#\n"
|
|
#define COMMENT_CLASSES @"\n\n#\n# Objective-C Class files\n#\n"
|
|
#define COMMENT_OCPPCLASSES @"\n\n#\n# Objective-C++ Class files\n#\n"
|
|
#define COMMENT_CFILES @"\n\n#\n# Other sources\n#\n"
|
|
#define COMMENT_SUBPROJECTS @"\n\n#\n# Subprojects\n#\n"
|
|
#define COMMENT_APP @"\n\n#\n# Main application\n#\n"
|
|
#define COMMENT_LIBRARIES @"\n\n#\n# Additional libraries\n#\n"
|
|
#define COMMENT_BUNDLE @"\n\n#\n# Bundle\n#\n"
|
|
#define COMMENT_LIBRARY @"\n\n#\n# Library\n#\n"
|
|
#define COMMENT_TOOL @"\n\n#\n# Tool\n#\n"
|
|
#define COMMENT_LOCALIZATION @"\n\n#\n# Localization\n#\n"
|
|
|
|
@implementation PCMakefileFactory
|
|
|
|
static PCMakefileFactory *_factory = nil;
|
|
|
|
+ (PCMakefileFactory *)sharedFactory
|
|
{
|
|
static BOOL isInitialised = NO;
|
|
|
|
if (isInitialised == NO)
|
|
{
|
|
_factory = [[PCMakefileFactory alloc] init];
|
|
|
|
isInitialised = YES;
|
|
}
|
|
|
|
return _factory;
|
|
}
|
|
|
|
- (void) createMakefileForProject: (PCProject *)project
|
|
{
|
|
id <PCPreferences> prefs = [[project projectManager] prefController];
|
|
NSString *buildDir = [prefs stringForKey:RootBuildDirectory];
|
|
NSString *prName = [project projectName];
|
|
NSString *buildName = [prName stringByAppendingPathExtension: @"build"];
|
|
NSString *instDomain = [[project projectDict] objectForKey:PCInstallDomain];
|
|
|
|
NSAssert(prName, @"No project name given!");
|
|
|
|
AUTORELEASE(mfile);
|
|
mfile = [[NSMutableString alloc] init];
|
|
|
|
AUTORELEASE(pnme);
|
|
pnme = [prName copy];
|
|
|
|
[mfile appendString: @"#\n"];
|
|
[mfile appendString: @"# GNUmakefile - Generated by ProjectCenter\n"];
|
|
[mfile appendString: @"#\n"];
|
|
|
|
[mfile appendString: @"ifeq ($(GNUSTEP_MAKEFILES),)\n"];
|
|
[mfile appendString: @" GNUSTEP_MAKEFILES := $(shell gnustep-config "];
|
|
[mfile appendString: @"--variable=GNUSTEP_MAKEFILES 2>/dev/null)\n"];
|
|
[mfile appendString: @" ifeq ($(GNUSTEP_MAKEFILES),)\n"];
|
|
[mfile appendString: @" $(warning )\n"];
|
|
[mfile appendString: @" $(warning Unable to obtain GNUSTEP_MAKEFILES"];
|
|
[mfile appendString: @" setting from gnustep-config!)\n"];
|
|
[mfile appendString: @" $(warning Perhaps gnustep-make is not properly"];
|
|
[mfile appendString: @" installed,)\n"];
|
|
[mfile appendString: @" $(warning so gnustep-config is not in your"];
|
|
[mfile appendString: @" PATH.)\n"];
|
|
[mfile appendString: @" $(warning )\n"];
|
|
[mfile appendString: @" $(warning Your PATH is currently $(PATH))\n"];
|
|
[mfile appendString: @" $(warning )\n"];
|
|
[mfile appendString: @" endif\n"];
|
|
[mfile appendString: @"endif\n"];
|
|
[mfile appendString: @"ifeq ($(GNUSTEP_MAKEFILES),)\n"];
|
|
[mfile appendString: @" $(error You need to set GNUSTEP_MAKEFILES"];
|
|
[mfile appendString: @" before compiling!)\n"];
|
|
[mfile appendString: @"endif\n"];
|
|
|
|
if ([instDomain isEqualToString: @"LOCAL"]
|
|
|| [instDomain isEqualToString: @"SYSTEM"]
|
|
|| [instDomain isEqualToString: @"USER"]
|
|
|| [instDomain isEqualToString: @"NETWORK"])
|
|
{
|
|
[mfile appendString:
|
|
[NSString stringWithFormat: @"\nGNUSTEP_INSTALLATION_DOMAIN = %@\n",
|
|
instDomain]];
|
|
}
|
|
|
|
/* If GNUSTEP_INSTALLATION_DOMAIN was not set explicitly by the
|
|
* user, it should not be specified; gnustep-make will use the
|
|
* default - normally, but not necessarily, LOCAL.
|
|
*/
|
|
|
|
[mfile appendString: @"\ninclude $(GNUSTEP_MAKEFILES)/common.make\n"];
|
|
|
|
if (![buildDir isEqualToString: @""] && buildDir != nil)
|
|
{
|
|
[mfile appendString:
|
|
[NSString stringWithFormat: @"\nGNUSTEP_BUILD_DIR = %@\n",
|
|
[buildDir stringByAppendingPathComponent:buildName]]];
|
|
}
|
|
}
|
|
|
|
- (BOOL)createPreambleForProject:(PCProject *)project
|
|
{
|
|
NSMutableString *mfp = [[NSMutableString alloc] init];
|
|
NSString *mfl = nil;
|
|
NSArray *array = nil;
|
|
NSDictionary *projectDict = [project projectDict];
|
|
NSString *projectPath = [project projectPath];
|
|
NSString *projectType = [project projectTypeName];
|
|
|
|
// Create the new file
|
|
[mfp appendString: @"#\n"];
|
|
[mfp appendString: @"# GNUmakefile.preamble - Generated by ProjectCenter\n"];
|
|
[mfp appendString: @"#\n\n"];
|
|
|
|
// Preprocessor flags
|
|
[mfp appendString: @"# Additional flags to pass to the preprocessor\n"];
|
|
[mfp appendString:
|
|
[NSString stringWithFormat: @"ADDITIONAL_CPPFLAGS += %@\n\n",
|
|
[projectDict objectForKey:PCPreprocessorOptions]]];
|
|
|
|
// Objective C compiler flags
|
|
[mfp appendString: @"# Additional flags to pass to Objective C compiler\n"];
|
|
[mfp appendString:
|
|
[NSString stringWithFormat: @"ADDITIONAL_OBJCFLAGS += %@\n\n",
|
|
[projectDict objectForKey:PCObjCCompilerOptions]]];
|
|
|
|
// C compiler flags
|
|
[mfp appendString: @"# Additional flags to pass to C compiler\n"];
|
|
[mfp appendString:
|
|
[NSString stringWithFormat: @"ADDITIONAL_CFLAGS += %@\n\n",
|
|
[projectDict objectForKey:PCCompilerOptions]]];
|
|
|
|
// Linker flags
|
|
[mfp appendString: @"# Additional flags to pass to the linker\n"];
|
|
[mfp appendString:
|
|
[NSString stringWithFormat: @"ADDITIONAL_LDFLAGS += %@ ",
|
|
[projectDict objectForKey:PCLinkerOptions]]];
|
|
[mfp appendString: @"\n\n"];
|
|
|
|
// Directories where to search headers
|
|
[mfp appendString:
|
|
@"# Additional include directories the compiler should search\n"];
|
|
[mfp appendString: @"ADDITIONAL_INCLUDE_DIRS += "];
|
|
array = [projectDict objectForKey:PCSearchHeaders];
|
|
if (array && [array count])
|
|
{
|
|
NSString *tmp;
|
|
NSEnumerator *enumerator = [array objectEnumerator];
|
|
|
|
while ((tmp = [enumerator nextObject]))
|
|
{
|
|
[mfp appendString: [NSString stringWithFormat: @"-I%@ ",tmp]];
|
|
}
|
|
}
|
|
[mfp appendString: @"\n\n"];
|
|
|
|
// Directories where to search libraries
|
|
[mfp appendString:
|
|
@"# Additional library directories the linker should search\n"];
|
|
[mfp appendString: @"ADDITIONAL_LIB_DIRS += "];
|
|
array = [projectDict objectForKey:PCSearchLibs];
|
|
if (array && [array count])
|
|
{
|
|
NSString *tmp;
|
|
NSEnumerator *enumerator = [array objectEnumerator];
|
|
|
|
while ((tmp = [enumerator nextObject]))
|
|
{
|
|
[mfp appendString: [NSString stringWithFormat: @"-L%@ ",tmp]];
|
|
}
|
|
}
|
|
[mfp appendString: @"\n\n"];
|
|
|
|
// [mfp appendString: [projectDict objectForKey:PCLibraries]];
|
|
|
|
if ([projectType isEqualToString: @"Tool"])
|
|
{
|
|
// Additional TOOL libraries
|
|
[mfp appendString: @"# Additional TOOL libraries to link\n"];
|
|
[mfp appendString: @"ADDITIONAL_TOOL_LIBS += "];
|
|
array = [projectDict objectForKey:PCLibraries];
|
|
if (array && [array count])
|
|
{
|
|
NSString *tmp;
|
|
NSEnumerator *enumerator = [array objectEnumerator];
|
|
|
|
while ((tmp = [enumerator nextObject]))
|
|
{
|
|
if (![tmp isEqualToString: @"gnustep-base"])
|
|
{
|
|
[mfp appendString: [NSString stringWithFormat: @"-l%@ ",tmp]];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Additional GUI libraries
|
|
// TODO: Let the user select objc, base, gui libraries/frameworks
|
|
// on the gui - the following works well for GUI stuff only.
|
|
[mfp appendString: @"# Additional GUI libraries to link\n"];
|
|
[mfp appendString: @"ADDITIONAL_GUI_LIBS += "];
|
|
array = [projectDict objectForKey:PCLibraries];
|
|
if (array && [array count])
|
|
{
|
|
NSString *tmp;
|
|
NSEnumerator *enumerator = [array objectEnumerator];
|
|
|
|
while ((tmp = [enumerator nextObject]))
|
|
{
|
|
if (![tmp isEqualToString: @"gnustep-base"] &&
|
|
![tmp isEqualToString: @"gnustep-gui"])
|
|
{
|
|
[mfp appendString: [NSString stringWithFormat: @"-l%@ ",tmp]];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
[mfp appendString: @"\n\n"];
|
|
|
|
// Write the new file to disc!
|
|
mfl = [projectPath stringByAppendingPathComponent: @"GNUmakefile.preamble"];
|
|
if (![mfp writeToFile:mfl atomically:YES])
|
|
{
|
|
NSRunAlertPanel(@"Create Makefile",
|
|
@"Couldn't create %@",
|
|
@"Ok",nil,nil, mfl);
|
|
return NO;
|
|
}
|
|
|
|
return YES;
|
|
}
|
|
|
|
- (BOOL)createPostambleForProject:(PCProject *)project
|
|
{
|
|
NSBundle *bundle = nil;
|
|
NSString *template = nil;
|
|
NSString *postamble = nil;
|
|
NSFileManager *fm = [NSFileManager defaultManager];
|
|
|
|
bundle = [NSBundle bundleForClass: [self class]];
|
|
template = [bundle pathForResource: @"postamble" ofType: @"template"];
|
|
postamble = [[project projectPath]
|
|
stringByAppendingPathComponent: @"GNUmakefile.postamble"];
|
|
|
|
if (![fm copyPath:template toPath:postamble handler:nil])
|
|
{
|
|
NSRunAlertPanel(@"Create Makefile",
|
|
@"Couldn't create %@",
|
|
@"Ok",nil,nil, postamble);
|
|
return NO;
|
|
}
|
|
|
|
return YES;
|
|
}
|
|
|
|
- (void)appendString:(NSString *)aString
|
|
{
|
|
NSAssert(mfile, @"No valid makefile available!");
|
|
NSAssert(aString, @"No valid string!");
|
|
|
|
[mfile appendString:aString];
|
|
}
|
|
|
|
- (void)appendLibraries:(NSArray *)array
|
|
{
|
|
NSMutableArray *libs = [NSMutableArray arrayWithArray:array];
|
|
NSString *lib = nil;
|
|
NSEnumerator *enumerator = nil;
|
|
|
|
[libs removeObject: @"gnustep-base"];
|
|
[libs removeObject: @"gnustep-gui"];
|
|
|
|
if (libs == nil || [libs count] == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
[self appendString: @"\n\n#\n# Libraries\n#\n"];
|
|
[self appendString:
|
|
[NSString stringWithFormat: @"%@_LIBRARIES_DEPEND_UPON += ",pnme]];
|
|
|
|
enumerator = [libs objectEnumerator];
|
|
while ((lib = [enumerator nextObject]))
|
|
{
|
|
[self appendString: [NSString stringWithFormat: @"-l%@ ",lib]];
|
|
}
|
|
}
|
|
|
|
- (void)appendHeaders:(NSArray *)array
|
|
{
|
|
if (array == nil || [array count] == 0)
|
|
return;
|
|
|
|
[self appendHeaders:array forTarget:pnme];
|
|
}
|
|
|
|
- (void)appendHeaders:(NSArray *)array forTarget:(NSString *)target
|
|
{
|
|
if (array == nil || [array count] == 0)
|
|
return;
|
|
|
|
[self appendString:COMMENT_HEADERS];
|
|
[self appendString:
|
|
[NSString stringWithFormat: @"%@_HEADER_FILES = \\\n", target]];
|
|
|
|
[self appendString: [array componentsJoinedByString: @" \\\n"]];
|
|
}
|
|
|
|
- (void)appendClasses:(NSArray *)array
|
|
{
|
|
if (array == nil || [array count] == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
[self appendClasses:array forTarget:pnme];
|
|
}
|
|
|
|
- (void)appendClasses:(NSArray *)array forTarget:(NSString *)target
|
|
{
|
|
NSEnumerator *oenum;
|
|
NSMutableArray *marray = nil;
|
|
NSMutableArray *mmarray = nil;
|
|
NSString *file;
|
|
|
|
if (array == nil || [array count] == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
oenum = [array objectEnumerator];
|
|
while ((file = [oenum nextObject]))
|
|
{
|
|
if ([file hasSuffix: @".m"])
|
|
{
|
|
if (marray == nil)
|
|
{
|
|
marray = [NSMutableArray array];
|
|
}
|
|
[marray addObject: file];
|
|
}
|
|
else if ([file hasSuffix: @".mm"])
|
|
{
|
|
if (mmarray == nil)
|
|
{
|
|
mmarray = [NSMutableArray array];
|
|
}
|
|
[mmarray addObject: file];
|
|
}
|
|
}
|
|
|
|
if (marray)
|
|
{
|
|
[self appendString:COMMENT_CLASSES];
|
|
[self appendString: [NSString stringWithFormat: @"%@_OBJC_FILES = \\\n",target]];
|
|
[self appendString: [marray componentsJoinedByString: @" \\\n"]];
|
|
}
|
|
|
|
if (mmarray)
|
|
{
|
|
[self appendString:COMMENT_OCPPCLASSES];
|
|
[self appendString: [NSString stringWithFormat: @"%@_OBJCC_FILES = \\\n",target]];
|
|
[self appendString: [mmarray componentsJoinedByString: @" \\\n"]];
|
|
}
|
|
}
|
|
|
|
- (void)appendOtherSources:(NSArray *)array
|
|
{
|
|
if (array == nil || [array count] == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
[self appendOtherSources: array forTarget: pnme];
|
|
}
|
|
|
|
- (void)appendOtherSources:(NSArray *)array forTarget: (NSString *)target
|
|
{
|
|
NSMutableArray *marray = nil;
|
|
NSMutableArray *mmarray = nil;
|
|
NSMutableArray *oarray = nil;
|
|
NSEnumerator *oenum;
|
|
NSString *file;
|
|
|
|
if (array == nil || [array count] == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Other Sources can have both .m files and non .m files
|
|
oenum = [array objectEnumerator];
|
|
while ((file = [oenum nextObject]))
|
|
{
|
|
if ([file hasSuffix: @".m"])
|
|
{
|
|
if (marray == nil)
|
|
{
|
|
marray = [NSMutableArray array];
|
|
}
|
|
[marray addObject: file];
|
|
}
|
|
else if ([file hasSuffix: @".mm"])
|
|
{
|
|
if (mmarray == nil)
|
|
{
|
|
mmarray = [NSMutableArray array];
|
|
}
|
|
[mmarray addObject: file];
|
|
}
|
|
else // non .m file
|
|
{
|
|
if (oarray == nil)
|
|
{
|
|
oarray = [NSMutableArray array];
|
|
}
|
|
[oarray addObject: file];
|
|
}
|
|
}
|
|
|
|
[self appendString:COMMENT_CFILES];
|
|
|
|
// Add other sources if any
|
|
if (oarray && [oarray count] != 0)
|
|
{
|
|
oenum = [oarray objectEnumerator];
|
|
|
|
[self appendString: [NSString stringWithFormat: @"%@_C_FILES = ", target]];
|
|
|
|
while ((file = [oenum nextObject]))
|
|
{
|
|
[self appendString: [NSString stringWithFormat: @"\\\n%@ ",file]];
|
|
}
|
|
[self appendString: @"\n\n"];
|
|
}
|
|
|
|
// Add .m files if any
|
|
if (marray && [marray count] != 0)
|
|
{
|
|
oenum = [marray objectEnumerator];
|
|
|
|
[self appendString: [NSString stringWithFormat: @"%@_OBJC_FILES += ",pnme]];
|
|
|
|
while ((file = [oenum nextObject]))
|
|
{
|
|
[self appendString: [NSString stringWithFormat: @"\\\n%@ ", file]];
|
|
}
|
|
}
|
|
|
|
// Add .mm files if any
|
|
if (mmarray && [marray count] != 0)
|
|
{
|
|
oenum = [mmarray objectEnumerator];
|
|
|
|
[self appendString: [NSString stringWithFormat: @"%@_OBJCC_FILES += ",pnme]];
|
|
|
|
while ((file = [oenum nextObject]))
|
|
{
|
|
[self appendString: [NSString stringWithFormat: @"\\\n%@ ", file]];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)appendResources:(NSArray *)array inDir:(NSString *)dir
|
|
{
|
|
int i = 0;
|
|
int count = [array count];
|
|
NSString *string = nil;
|
|
NSString *item = nil;
|
|
NSString *eol = @"\\\n";
|
|
|
|
if (array == nil || count <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Header
|
|
[self appendString:COMMENT_RESOURCES];
|
|
[self appendString:
|
|
[NSString stringWithFormat: @"%@_RESOURCE_FILES = \\\n",pnme]];
|
|
|
|
// Items
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
item = [array objectAtIndex:i];
|
|
string = [NSString stringWithFormat: @"%@/%@ %@", dir, item, eol];
|
|
[self appendString:string];
|
|
if (i == (count-2))
|
|
{
|
|
eol = @"\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)appendResourceItems:(NSArray *)array
|
|
{
|
|
if (array == nil || [array count] <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
[self appendString: @"\\\n"];
|
|
[self appendString: [array componentsJoinedByString: @" \\\n"]];
|
|
}
|
|
|
|
- (void)appendLocalizedResources:(NSArray *)resources
|
|
forLanguages:(NSArray *)languages
|
|
{
|
|
NSString *langs = [languages componentsJoinedByString: @" "];
|
|
NSString *string = nil;
|
|
NSString *item = nil;
|
|
NSString *eol = @"\\\n";
|
|
int i = 0;
|
|
int count = [resources count];
|
|
|
|
if (resources == nil || count <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Header
|
|
[self appendString:COMMENT_LOCALIZATION];
|
|
|
|
// Languages
|
|
string = [NSString stringWithFormat: @"%@_LANGUAGES = %@\n", pnme, langs];
|
|
[self appendString:string];
|
|
|
|
// Items
|
|
[self appendString:
|
|
[NSString stringWithFormat: @"%@_LOCALIZED_RESOURCE_FILES = \\\n",pnme]];
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
if (i == (count-1))
|
|
{
|
|
eol = @"\n";
|
|
}
|
|
item = [resources objectAtIndex:i];
|
|
string = [NSString stringWithFormat: @"%@ %@", item, eol];
|
|
[self appendString:string];
|
|
}
|
|
}
|
|
|
|
- (void)appendSubprojects:(NSArray*)array
|
|
{
|
|
NSString *tmp = nil;
|
|
NSEnumerator *enumerator = nil;
|
|
|
|
if (array == nil || [array count] == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
[self appendString:COMMENT_SUBPROJECTS];
|
|
[self appendString: @"SUBPROJECTS = "];
|
|
|
|
enumerator = [array objectEnumerator];
|
|
while ((tmp = [enumerator nextObject]))
|
|
{
|
|
tmp = [tmp stringByAppendingPathExtension: @"subproj"];
|
|
[self appendString: [NSString stringWithFormat: @"\\\n%@ ",tmp]];
|
|
}
|
|
}
|
|
|
|
- (NSData *)encodedMakefile
|
|
{
|
|
NSAssert(mfile, @"No valid makefile available!");
|
|
|
|
return [mfile dataUsingEncoding: [NSString defaultCStringEncoding]];
|
|
}
|
|
|
|
@end
|
|
|