0

このアクションで、アプリケーションからファイルをコンパイルしようとしています。

- (IBAction)build:(id)sender
{
    pid_t pid=fork();
    int status;
    if(!pid)
    {
        execl("/Developer/usr/bin/gcc","-o main ~/main.c");
        exit(0);
    }
    waitpid(pid, &status, 0);
}

ホームディレクトリのmain.cファイルがコンパイルされていません(実行可能ファイルが見つかりません)。
そして私は知っているでしょう:
1)引数をgccに渡す方法は?〜/ main.cを渡していますが、ドキュメントのフルパスを含むファイル名を渡したいのですが、NSDocumentのファイル名を取得するにはどうすればよいですか?
2)コンソール出力を取得するにはどうすればよいですか?gcc出力も印刷する必要がありますが、これを行うにはどうすればよいですか?

編集:アプリケーションから保存されたファイルをコンパイルするようにコードを変更しました:

- (IBAction)build:(id)sender
{
    NSTask *task = [[NSTask alloc] init];
    [task setLaunchPath:@"/Developer/usr/bin/gcc"];
    [task setArguments: @[@"-o",@"main",[self fileURL]] ];
    NSPipe *pipe = [NSPipe pipe];
    [task setStandardOutput:pipe];
    NSFileHandle *file = [pipe fileHandleForReading];
    [task launch];
    NSData *data = [file readDataToEndOfFile];
    NSString *output = [[NSString alloc] initWithData:data
                                             encoding:NSUTF8StringEncoding];
    NSLog (@"gcc output:\n%@", output);
}

しかし、buildメソッドが実行されるたびに、それが得られます。

2012-11-07 19:04:30.636 Coder[1856:303] -[NSURL fileSystemRepresentation]: unrecognized selector sent to instance 0x100154c40
2012-11-07 19:04:30.638 Coder[1856:303] -[NSURL fileSystemRepresentation]: unrecognized selector sent to instance 0x100154c40
2012-11-07 19:04:30.642 Coder[1856:303] (
    0   CoreFoundation                      0x00007fff95b060a6 __exceptionPreprocess + 198
    1   libobjc.A.dylib                     0x00007fff909793f0 objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff95b9c6ea -[NSObject(NSObject) doesNotRecognizeSelector:] + 186
    3   CoreFoundation                      0x00007fff95af45ce ___forwarding___ + 414
    4   CoreFoundation                      0x00007fff95af43b8 _CF_forwarding_prep_0 + 232
    5   Foundation                          0x00007fff8cbf8e67 -[NSConcreteTask launchWithDictionary:] + 814
    6   Coder                               0x0000000100001734 -[Document build:] + 452
    7   AppKit                              0x00007fff8d266a59 -[NSApplication sendAction:to:from:] + 342
    8   AppKit                              0x00007fff8d2668b7 -[NSControl sendAction:to:] + 85
    9   AppKit                              0x00007fff8d2667eb -[NSCell _sendActionFrom:] + 138
    10  AppKit                              0x00007fff8d264cd3 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 1855
    11  AppKit                              0x00007fff8d264521 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 504
    12  AppKit                              0x00007fff8d263c9c -[NSControl mouseDown:] + 820
    13  AppKit                              0x00007fff8d25b60e -[NSWindow sendEvent:] + 6853
    14  AppKit                              0x00007fff8d257744 -[NSApplication sendEvent:] + 5761
    15  AppKit                              0x00007fff8d16d2fa -[NSApplication run] + 636
    16  AppKit                              0x00007fff8d111cb6 NSApplicationMain + 869
    17  Coder                               0x00000001000011a2 main + 34
    18  libdyld.dylib                       0x00007fff93a577e1 start + 0
    19  ???                                 0x0000000000000003 0x0 + 3
)

trojanfoeコードは機能していましたが、この変更では機能しません。

4

2 に答える 2

1

NSTask代わりに使用してください(参照

未テスト:

NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *sourceFile = [docDir stringByAppendingPathComponent:@"main.c"];
NSString *outFile = [docDir stringByAppendingPathComponent:@"main"];

NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/Developer/usr/bin/gcc"];
[task setArguments:[NSArray arrayWithObjects: @"-o", outFile, sourceFile, nil]];

NSPipe *pipe = [NSPipe pipe];
[task setStandardOutput:pipe];

NSFileHandle *file = [pipe fileHandleForReading];

[task launch];

NSData *data = [file readDataToEndOfFile];

NSString *output = [[NSString alloc] initWithData:data
                                         encoding:NSUTF8StringEncoding];
NSLog (@"gcc output:\n%@", output);

[output release];
[task release];
于 2012-11-07T12:19:51.490 に答える
1

パラメータリストは。execl()で終了します(char *) NULL

したがって、呼び出しは次のようになります。

execl("/Developer/usr/bin/gcc","-o main ~/main.c", (char *) NULL);

またはgcc、引数が何であるかを見つけることができるようにすることをお勧めします。個別の引数:

execl("/Developer/usr/bin/gcc", "-o", "main", "~/main.c", (char *) NULL);

アップデート:

trojanfoeが言及しているように、ここでは拡張が問題になります。したがって、~in~/main.cをユーザーのホームに拡張するには、次のようにシェルを関与させる必要があります。

execl("/bin/sh", "-c", "gcc -o main ~/main.c", (char *) NULL);
于 2012-11-07T12:20:18.867 に答える