Как перенаправить llvm :: outs () в файл?

Я использую некоторые инструменты LLVM (например, llvm-nm) как статические библиотеки. То есть я скопировал источник llvm-nm.cpp, переименовал main(..) в llvm_nm(..) и скомпилировал его как статическую библиотеку. Я хотел бы переслать стандартный вывод в мой файл.

Я попытался использовать следующий подход:

  int    out_fd, err_fd;
fpos_t out_pos, err_pos;

// redirect out
fflush(stdout);
fgetpos(stdout, &out_pos);
out_fd = dup(fileno(stdout));
freopen(outFilename, "w", stdout);

// execute
int ret = llvm_nm(argc_, argv_);

// restore output
fflush(stdout);
dup2(out_fd, fileno(stdout));
close(out_fd);
clearerr(stdout);
fsetpos(stdout, &out_pos);

Проблема в том, что он не пересылается (работает, если я добавлю printf() в исходном коде нм, но не для nm выход). Я обращаюсь к источнику, и я вижу, что вывод сделан с использованием llvm::outs() поток:

outs() << "Archive map" << "\n";

А также это реализовано следующим образом:

/// outs() - This returns a reference to a raw_ostream for standard output.
00702 /// Use it like: outs() << "foo" << "bar";
00703 raw_ostream &llvm::outs() {
00704   // Set buffer settings to model stdout behavior.
00705   // Delete the file descriptor when the program exits, forcing error
00706   // detection. If you don't want this behavior, don't use outs().
00707   static raw_fd_ostream S(STDOUT_FILENO, true);
00708   return S;
00709 }

Как я могу перенаправить этот вывод в мой файл?

9

Решение

Я понимаю, что это старый вопрос, однако я наткнулся на его поиск простой информации для потока llvm outs (), которую я нашел Вот.

Один из примеров, который поставляется с llvm «BrainF», использует его так:

  ...

raw_ostream *out = &outs();
if (!JIT) {
if (OutputFilename == "") {
std::string base = InputFilename;
if (InputFilename == "-") { base = "a"; }

// Use default filename.
OutputFilename = base+".bc";
}
if (OutputFilename != "-") {
std::error_code EC;
out = new raw_fd_ostream(OutputFilename, EC, sys::fs::F_None);
}
}

...

if (out != &outs())
delete out;

...

Таким образом, кажется, что вы можете безопасно перенаправить.

Примечание: в этом примере OutputFilename / InputFilename являются типами std :: string, созданными с помощью библиотеки поддержки llvm Командная строка.

5

Другие решения

Кажется, нет простого способа сделать это: нет конструктора копирования / присваивания в llvm::raw_fd_ostream ни в llvm::raw_ostream, И freopen Трюк также не работает, потому что целочисленный дескриптор файла используется для инициализации объекта, возвращаемого llvm::outs(),

Единственный способ, которым я вижу, это использовать LD_PRELOAD изменить реализацию llvm::outs() на лету, или аналогичные трюки с линкерами, но для меня это звучит очень глупо. Может быть, пометить оригинальный символ как слабый, а затем переопределить его в вашей библиотеке?

2

По вопросам рекламы [email protected]