[llvm-dev] How to make LLVM clang linker self-contained?
Edmund Furse via llvm-dev
llvm-dev at lists.llvm.org
Mon Mar 23 04:36:36 PDT 2020
Dear llvm dev community I need your help please.
I am new to llvm-dev and not an expert in LLVM or UNIX or C.
I am trying to build a MacOSX app that can compile and link Objective C files.
I can succeed in doing this if sandboxing is turned off.
However, when sandboxing is turned on, the compiling works but linking fails with the error:
clang-9 xcrun: error: cannot be used within an App Sandbox.
I have downloaded the LLVM binary and created a Tools folder that contains the folders of the binary, namely bin, include, li, libexec, share.
My example app uses NSTask to call clang from Tools/bin/clang.
If you call clang from usr/bin/clang then sandboxing will not allow compilation.
I presume that linking fails because the LLVM clang linker is calling routines that are external to the LLVM binary.
Is it possible to make the LLVM clang linker self-contained? and if so, how?
Alternatively, I might have got some of the linker flags wrong.
Or do I need a completely different approach?
My code follows.
Error Message:
2020-03-20 11:57:13.664406+0000 NewClangM21[669:9420] Compilation was successfull.
2020-03-20 11:57:13.797517+0000 NewClangM21[669:9420] There was a linking error: clang version 9.0.0 (git://github.com/llvm/llvm-project.git 0399d5a9682b3cef71c653373e38890c63c4c365)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Users/edmundfurse/Documents/NewClang/NewClangM21/DerivedData/NewClangM21/Build/Products/Debug/NewClangM21.app/Contents/Resources/Tools/bin
"/Applications/Xcode.app/Contents/Developer/usr/bin/ld" -demangle -lto_library /Users/edmundfurse/Documents/NewClang/NewClangM21/DerivedData/NewClangM21/Build/Products/Debug/NewClangM21.app/Contents/Resources/Tools/lib/libLTO.dylib -dynamic -arch x86_64 -bundle -macosx_version_min 10.14.0 -o "/Users/edmundfurse/Library/Containers/com.uk.imitation.NewClangM21/Data/Library/Application Support/NewClangM21/ImitateScriptSystem/TemporaryFiles/TestMain" -L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk "/Users/edmundfurse/Library/Containers/com.uk.imitation.NewClangM21/Data/Library/Application Support/NewClangM21/ImitateScriptSystem/TemporaryFiles/TestMain.o" -framework Cocoa -framework Foundation -lSystem /Users/edmundfurse/Documents/NewClang/NewClangM21/DerivedData/NewClangM21/Build/Products/Debug/NewClangM21.app/Contents/Resources/Tools/lib/clang/9.0.0/lib/darwin/libclang_rt.osx.a "-F/Users/edmundfurse/Library/Containers/com.uk.imitation.NewClangM21/Data/Library/Application Support/NewClangM21/ImitateScriptSystem/TemporaryFiles/"
xcrun: error: cannot be used within an App Sandbox.
clang-9: error: linker command failed with exit code 1 (use -v to see invocation)
2020-03-20 11:57:13.798321+0000 NewClangM21[669:9420] CASE 1 LINK ERROR
Code:
#import "AppDelegate.h"
#import "NSFileManager+DirectoryLocations.h"
@interface AppDelegate ()
@property (weak) IBOutlet NSWindow *window;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
NSString* compileResult = [self compileScriptFile:@"TestMain"];
if ([compileResult isEqualToString:@""])
{
NSLog(@"Compilation was successfull.");
}
BOOL linkResult = [self linkScriptFiles:@"TestMain"];
if (linkResult)
{
NSLog(@"Linking was successfull.");
}
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
- (NSString*)compileScriptFile:(NSString*)theScriptName
{
NSString *applicationSupportDirectoryPath = [[NSFileManager defaultManager] applicationSupportDirectory];
NSString* temporaryFilesDirectoryName = concatenate(applicationSupportDirectoryPath, @"/ImitateScriptSystem/TemporaryFiles/");
NSString* result = [self compileFile:theScriptName
inDirectory:temporaryFilesDirectoryName
toDirectory:temporaryFilesDirectoryName];
if (![result isEqualToString:@""])
{
NSLog(@"There was an error compiling the file");
return result;
}
return @"";
}
- (NSString*)compileFile:(NSString*)fileName
inDirectory:(NSString*)fromDirectoryPath
toDirectory:(NSString*)toDirectoryPath
// compiles the file using clang
{
NSTask* compileTask = [[NSTask alloc] init];
NSString* clangPath = [[NSBundle mainBundle] pathForResource:@"clang" ofType:@"" inDirectory:@"Tools/bin/"];
[compileTask setLaunchPath:clangPath];
[compileTask setArguments:[NSArray arrayWithObjects:@"-c",concatenate3(fromDirectoryPath, fileName, @".m"),
@"-isysroot",
@"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk",
// macosxSDKPath,
@"-o",
concatenate3(toDirectoryPath, fileName, @".o"),
nil]];
NSPipe* errorPipe = [[NSPipe alloc] init];
NSFileHandle* errorReader = [errorPipe fileHandleForReading];
[compileTask setStandardError:errorPipe];
[compileTask launch];
[compileTask waitUntilExit];
NSString* errorString = [[NSString alloc] initWithData:[errorReader readDataToEndOfFile]
encoding:NSUTF8StringEncoding];
if ([errorString length] != 0)
{
NSLog(@"There was a Compilation error: %@", errorString);
return errorString;
}
return @"";
}
- (BOOL)linkScriptFiles:(NSString*)theScriptName
{
// NSLog(@"IN LoadScript: linkScriptFiles:");
NSString *applicationSupportDirectoryPath = [[NSFileManager defaultManager] applicationSupportDirectory];
NSString* temporaryFilesDirectoryName = concatenate(applicationSupportDirectoryPath, @"/ImitateScriptSystem/TemporaryFiles/");
NSString* linkResult = [self linkTheScriptFilesToScriptName:theScriptName
intoDirectory:temporaryFilesDirectoryName];
if (![linkResult isEqualToString:@""])
{
if (searchOfString(@"error", linkResult) != -1 || searchOfString(@"Error", linkResult) != -1 || searchOfString(@"ERROR", linkResult) != -1)
{
NSLog(@"CASE 1 LINK ERROR");
return NO;
}
else if (searchOfString(@"warning", linkResult) != -1 || searchOfString(@"Warning", linkResult) != -1 || searchOfString(@"WARNING", linkResult) != -1)
{
NSLog(@"CASE 2 LINK WARNING");
return YES;
}
else
{
NSLog(@"CASE 3 UNKNOWN LINK PROBLEM");
return NO;
}
}
return YES;
}
- (NSString*)linkTheScriptFilesToScriptName:(NSString*)theScriptName intoDirectory:(NSString*)dir
// links the file using clang
{
NSString *applicationSupportDirectoryPath = [[NSFileManager defaultManager] applicationSupportDirectory];
NSString* temporaryFilesDirectoryName = concatenate(applicationSupportDirectoryPath, @"/ImitateScriptSystem/TemporaryFiles/");
NSTask* linkTask = [[NSTask alloc] init];
NSString* clangPath = [[NSBundle mainBundle] pathForResource:@"clang" ofType:@"" inDirectory:@"Tools/bin/"];
[linkTask setLaunchPath:clangPath];
[linkTask setArguments:[NSArray arrayWithObjects:
concatenate3(temporaryFilesDirectoryName, theScriptName, @".o"),
@"-framework",
@"Cocoa",
@"-framework",
@"Foundation",
concatenate(@"-F", temporaryFilesDirectoryName),
@"-v",
@"-L",
@"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk",
@"-bundle",
@"-o",
concatenate(dir, theScriptName),
nil]];
NSPipe* errorPipe = [[NSPipe alloc] init];
NSFileHandle* errorReader = [errorPipe fileHandleForReading];
[linkTask setStandardError:errorPipe];
[linkTask launch];
[linkTask waitUntilExit];
NSString* errorString = [[NSString alloc] initWithData:[errorReader readDataToEndOfFile]
encoding:NSUTF8StringEncoding];
if ([errorString length] != 0)
{
NSLog(@"There was a linking error: %@", errorString);
if ((searchOfString(@"error", errorString) != -1) ||
(searchOfString(@"ERROR", errorString) != -1))
{
return errorString;
}
else
{
return @""; // ALLOW WARNINGS.
}
return errorString;
}
return @"";
}
NSString* concatenate(NSString* x, NSString* y)
{
if (!x && !y) return @"";
else if(!x) return y;
else if (!y) return x;
return [x stringByAppendingString:y];
}
NSString* concatenate3(NSString* x, NSString* y, NSString* z)
{
if (!x) x = @"";
if (!y) y = @"";
if (!z) z = @"";
return [[x stringByAppendingString:y] stringByAppendingString:z];
}
NSString* concatenate4(NSString* w, NSString* x, NSString* y, NSString* z)
{
if (!x) x = @"";
if (!y) y = @"";
if (!z) z = @"";
if (!w) w = @"";
return [[[w stringByAppendingString:x] stringByAppendingString:y] stringByAppendingString:z];
}
int searchOfString(NSString* x, NSString* str)
//searches for x within str, if not found returns -1
//otherwise returns its location.
{
if ((int)[str length] == 0) return -1;
if ((int)[x length] > (int)[str length]) return -1;
NSRange myRange = [str rangeOfString:x];
if (myRange.location != NSNotFound)
return (int)myRange.location;
else return -1;
}
@end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200323/3db2f3c8/attachment.html>
More information about the llvm-dev
mailing list