Не обращайте внимания на все комментарии «почему?», «бесполезно?» и «не беспокойтесь». Я хочу скомпилировать программу внутри другой программы, используя clang. Я могу создать NSTask
и настроить аргументы, и он будет работать, если файл существует (т.е. нет потока) и записывает в физический файл. Я не смог получить то, что мне действительно хотелось бы, - использовать потоки как для ввода, так и для вывода. Я знаю, что и clang, и gcc позволяют компилировать стандартный ввод, если вы используете параметры -xc и -, но я не могу реализовать эту функцию с помощью каналов. Я также не уверен, как перенаправить вывод clang в дескриптор файла или поток.
Вот код, который у меня есть, который компилирует его и генерирует правильный вывод в файле outfile
task = [[NSTask alloc] init];
NSPipe* outputPipe = [[NSPipe alloc] init];
[task setStandardOutput:outputPipe ];
[task setStandardError: [task standardOutput]];
NSPipe* inPipe = [NSPipe pipe];
[task setStandardInput:inPipe];
[task setLaunchPath:@"/usr/bin/clang"];
NSString* outfile= [NSString stringWithFormat:@"%@.out",[[filename lastPathComponent] stringByDeletingPathExtension]];
//[data writeToFile:@"file.c" atomically:YES];
[task setArguments:[NSArray arrayWithObjects:filename,@"-S",@"-o",outfile,nil]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(getData:)
name: NSFileHandleReadCompletionNotification
object: [[task standardOutput] fileHandleForReading]];
[[[task standardOutput] fileHandleForReading] readInBackgroundAndNotify];
[task launch];
Я попытался использовать это для входного потока:
/* on pipe creation*/
dup2([[inPipe fileHandleForReading] fileDescriptor], STDIN_FILENO);
NSFileHandle* curInputHandle = [inPipe fileHandleForWriting];
/* tried before launch and after, no output just sits */
[curInputHandle writeData:[NSData dataWithContentsOfFile:filename]];
Иногда я предполагаю, что когда канал закрывается, а NSTask все еще существует, выходной файл создается и запускается. Это заставляет меня думать, что clang просто ждет закрытия стандартного ввода. Есть ли способ закрыть канал, когда данные были прочитаны?
Для вывода я попытался использовать fileHandleForWriting NSPipe в качестве параметра -o, что дает ошибку [NSConcretePipe fileSystemRepresentation]
нераспознанного селектора. Я попытался создать дескриптор файла с файловым дескриптором stdout с той же ошибкой. Я не знаю ни одного аргумента командной строки, который перенаправляет его. Я пытался использовать |
для перенаправления, но не смог заставить его работать. Если есть какая-то магия unix для перенаправления, я могу дублировать stdout куда захочу.
Итак, есть ли способ закрыть канал, когда все данные будут прочитаны? И перенаправить лязг выход? Если есть какой-либо другой способ сделать то же самое проще или чище, я открыт для любой реализации. Любая помощь по этим двум пунктам была бы очень кстати.