2

If i have the following block:

#+NAME: my-code
#+BEGIN_SRC C
#include <stdio.h>

int main ()
{
  printf("Hello, World!");
  return 0;
}
#+END_SRC

How can I use the compiled output in another source block?

#+BEGIN_SRC sh :noweb yes
file <<my-code()>>
#+END_SRC
spw
  • 21
  • 1

1 Answers1

0

The org-mode built-in version of org-babel-C-execute creates a temporary file name for the executable locally bound in the function. It does not support referencing the executable in other source blocks.

The following advice adds a header argument :executable where you can set the file name of the executable.

(defun org-babel-C-execute-executable-ad (fun body params)
  "Consider the given :executable header arg when running `org-babel-C-execute'.
This is an around advice for `org-babel-C-execute'."
  (let ((executable (cdr (assq :executable params))))
    (if (stringp executable)
        (cl-letf* ((old-temp-file (symbol-function 'org-babel-temp-file))
                   ((symbol-function 'org-babel-temp-file)
                    `(lambda (prefix &optional suffix)
                       ;; Use given executable as file name.
                       (if (string-equal prefix "C-bin-")
                           ,(expand-file-name executable)
                         (funcall ,old-temp-file prefix suffix)))))
          (funcall fun body params)
          ))
    (funcall fun body params)))

(eval-after-load "ob-C"
  (lambda ()
    (add-to-list 'org-babel-header-args:C '(executable . :any))
    (advice-add 'org-babel-C-execute :around #'org-babel-C-execute-executable-ad)))

Application example:

#+BEGIN_SRC C++ :executable "/tmp/myprog.exe"
#include <iostream>

int main() {
    std::cout << "Hello World!\n";
    return 0;
}
#+END_SRC

#+RESULTS:
: Hello World!

#+BEGIN_SRC shell :results drawer
ls -lh /tmp/myprog.exe
/tmp/myprog.exe
#+END_SRC

#+RESULTS:
:RESULTS:
-rwxrwxrwx 1 toz toz 8.6K Aug  1 07:05 /tmp/myprog.exe
Hello World!
:END:

Tested with emacs-version GNU Emacs 26.2 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.22.30) of 2019-04-12.

Test:

emacs-version: GNU Emacs 26.2 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.22.30) of 2019-04-12

  • Start Emacs with emacs -Q
  • Paste the Elisp code into the *scratch* buffer and run M-x eval-buffer.
  • Load ob-C and ob-shell with M-x load-library ...
  • Open file with above Orgmode code
  • Run org-babel-execute-src-block on the C++ source block and afterwards on the Shell source block via hitting C-c C-c on the source blocks.

You can install the above advice by copying it to your init file.

Tobias
  • 32,569
  • 1
  • 34
  • 75