emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Leo Butler <Leo.Butler@umanitoba.ca>
To: Ihor Radchenko <yantar92@posteo.net>
Cc: tbanelwebmin <tbanelwebmin@free.fr>,
	"emacs-orgmode@gnu.org" <emacs-orgmode@gnu.org>
Subject: Re: How to use mpirun with C or C++ Org-babel?
Date: Wed, 13 Dec 2023 16:09:07 +0000	[thread overview]
Message-ID: <87r0jq3x0e.fsf@t14.reltub.ca> (raw)
In-Reply-To: <87msukbadu.fsf@localhost> (Ihor Radchenko's message of "Fri, 08 Dec 2023 22:24:45 +0000")

[-- Attachment #1: Type: text/plain, Size: 672 bytes --]

On Fri, Dec 08 2023, Ihor Radchenko <yantar92@posteo.net> wrote:

> Leo Butler <Leo.Butler@umanitoba.ca> writes:
>
>> I submitted an imperfect patch some time ago [1] that targeted your use
>> case: allow ob-C.el to create a named binary.

> Note that I did not oppose the above behaviour when the result of
> evaluation is just compiling to :file. The problem was with compiling to
> a :file and _also_ executing it.
>
> If you want to propose a patch that will allow compile-only, I see no
> problem at all.

Ok, thank you for the clarification. I had gone on holidays after you
put up the poll and lost track.

Please see the attached patch.

Leo


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-lisp-ob-C.el-add-compile-only-header-to-compile-to-a.patch --]
[-- Type: text/x-diff; name="0001-lisp-ob-C.el-add-compile-only-header-to-compile-to-a.patch", Size: 8800 bytes --]

From 7d8e406bc4a92e2e2eab772b2671dcd72ca8c202 Mon Sep 17 00:00:00 2001
From: Leo Butler <leo.butler@umanitoba.ca>
Date: Tue, 12 Dec 2023 12:32:41 -0600
Subject: [PATCH] lisp/ob-C.el: add :compile-only header to compile to a named
 target

* lisp/ob-C.el (org-babel-C-execute): The new header argument,
`:compile-only', causes source and compiled binary files to be named
using the `:file' header argument.  When `:compile-only' is set,
execution of source block ends at compilation.  The naming of source
and binary filenames is factored out to `org-babel-C-src/bin-file'.
* lisp/ob-C.el (org-babel-C-src/bin-file): A new function that factors
out the setting of source and binary filenames.  It also signals an
error if `:compile-only' is set, but `:file' is not.
* testing/examples/ob-C-test.org: Add three example that exercise the
`:compile-only' header argument, including one that causes an error.
* testing/lisp/test-ob-C.el: Add three tests of the `:compile-only'
header argument.  New tests: ob-C/set-src+bin-file-name-{1,2,3}.

Refs: https://list.orgmode.org/87fs81egk5.fsf@t14.reltub.ca/
https://list.orgmode.org/87msukbadu.fsf@localhost/
---
 lisp/ob-C.el                   | 83 ++++++++++++++++++++--------------
 testing/examples/ob-C-test.org | 26 +++++++++++
 testing/lisp/test-ob-C.el      | 32 +++++++++++++
 3 files changed, 108 insertions(+), 33 deletions(-)

diff --git a/lisp/ob-C.el b/lisp/ob-C.el
index 0278fc02a..dd772dc97 100644
--- a/lisp/ob-C.el
+++ b/lisp/ob-C.el
@@ -53,7 +53,8 @@
 				    (main    . :any)
 				    (flags   . :any)
 				    (cmdline . :any)
-				    (libs    . :any))
+				    (libs    . :any)
+                                    (compile-only . (nil no t yes)))
   "C/C++-specific header arguments.")
 
 (defconst org-babel-header-args:C++
@@ -128,17 +129,32 @@ This function is called by `org-babel-execute-src-block'."
   "Expand C BODY according to its header arguments PARAMS."
   (let ((org-babel-c-variant 'c)) (org-babel-C-expand-C body params)))
 
+(defun org-babel-C-src/bin-file (params src? compile-only?)
+  "Return the src or bin filename to `org-babel-C-execute'.
+
+If `SRC?' is T, a file extension is added to the filename.  By
+default, the filename is created by `org-babel-temp-file'. If
+`COMPILE-ONLY?' is T, the filename is taken from the `:file'
+field in `PARAMS'; if that is NIL, an error occurs."
+  (let ((f (cdr (assq :file params))))
+    (when (and compile-only? (null f))
+      (error "Error: When COMPILE-ONLY is T or YES, output FILE needs to be set"))
+    (let* ((file (cond (compile-only? f) (src? "C-src-") (t "C-bin-")))
+           (ext (if src? (pcase org-babel-c-variant
+	                   (`c ".c") (`cpp ".cpp") (`d ".d"))
+                  org-babel-exeext)))
+      (org-babel-process-file-name
+       (if compile-only? (concat file ext)
+         (org-babel-temp-file file ext))))))
+
 (defun org-babel-C-execute (body params)
   "Execute C/C++/D BODY according to its header arguments PARAMS.
 This function should only be called by `org-babel-execute:C' or
 `org-babel-execute:C++' or `org-babel-execute:D'."
-  (let* ((tmp-src-file (org-babel-temp-file
-			"C-src-"
-			(pcase org-babel-c-variant
-			  (`c ".c") (`cpp ".cpp") (`d ".d"))))
-	 (tmp-bin-file			;not used for D
-	  (org-babel-process-file-name
-	   (org-babel-temp-file "C-bin-" org-babel-exeext)))
+  (let* ((compile-only? (let ((c (cdr (assq :compile-only params))))
+                          (or (string= c "t") (string= c "yes"))))
+         (tmp-src-file (org-babel-C-src/bin-file params t compile-only?))
+	 (tmp-bin-file (org-babel-C-src/bin-file params nil compile-only?)) ;not used for D
 	 (cmdline (cdr (assq :cmdline params)))
 	 (cmdline (if cmdline (concat " " cmdline) ""))
 	 (flags (cdr (assq :flags params)))
@@ -170,31 +186,32 @@ This function should only be called by `org-babel-execute:C' or
 		libs)
 	""))
       (`d nil)) ;; no separate compilation for D
-    (let ((results
-	   (org-babel-eval
-	    (pcase org-babel-c-variant
-	      ((or `c `cpp)
-	       (concat tmp-bin-file cmdline))
-	      (`d
-	       (format "%s %s %s %s"
-		       org-babel-D-compiler
-		       flags
-		       (org-babel-process-file-name tmp-src-file)
-		       cmdline)))
-	    "")))
-      (when results
-	(setq results (org-remove-indentation results))
-	(org-babel-reassemble-table
-	 (org-babel-result-cond (cdr (assq :result-params params))
-	   results
-	   (let ((tmp-file (org-babel-temp-file "c-")))
-	     (with-temp-file tmp-file (insert results))
-	     (org-babel-import-elisp-from-file tmp-file)))
-	 (org-babel-pick-name
-	  (cdr (assq :colname-names params)) (cdr (assq :colnames params)))
-	 (org-babel-pick-name
-	  (cdr (assq :rowname-names params)) (cdr (assq :rownames params)))))
-      )))
+    (unless compile-only?
+      (let ((results
+	     (org-babel-eval
+	      (pcase org-babel-c-variant
+	        ((or `c `cpp)
+	         (concat tmp-bin-file cmdline))
+	        (`d
+	         (format "%s %s %s %s"
+		         org-babel-D-compiler
+		         flags
+		         (org-babel-process-file-name tmp-src-file)
+		         cmdline)))
+	      "")))
+        (when results
+	  (setq results (org-remove-indentation results))
+	  (org-babel-reassemble-table
+	   (org-babel-result-cond (cdr (assq :result-params params))
+	     results
+	     (let ((tmp-file (org-babel-temp-file "c-")))
+	       (with-temp-file tmp-file (insert results))
+	       (org-babel-import-elisp-from-file tmp-file)))
+	   (org-babel-pick-name
+	    (cdr (assq :colname-names params)) (cdr (assq :colnames params)))
+	   (org-babel-pick-name
+	    (cdr (assq :rowname-names params)) (cdr (assq :rownames params)))))
+        ))))
 
 (defun org-babel-C-expand-C++ (body params)
   "Expand C/C++ BODY with according to its header arguments PARAMS."
diff --git a/testing/examples/ob-C-test.org b/testing/examples/ob-C-test.org
index c7a96f665..f636aabe8 100644
--- a/testing/examples/ob-C-test.org
+++ b/testing/examples/ob-C-test.org
@@ -174,3 +174,29 @@ std::cout << "\"line 1\"\n";
 std::cout << "\"line 2\"\n";
 std::cout << "\"line 3\"\n";
 #+end_src
+
+* File naming
+:PROPERTIES:
+:ID:       1a691f36-f9c1-4531-8fc0-ee7b21ef5975
+:END:
+
+Test that the binary file is saved in =./hello-world=.
+
+#+source: bin-file-1
+#+begin_src cpp :includes <iostream> :results none :compile-only t :file ./hello-world
+std::cout << "Hello World!\n";
+#+end_src
+
+Test that =yes= works, in addition to =t=.
+
+#+source: bin-file-2
+#+begin_src cpp :includes <iostream> :results none :compile-only yes :file ./hello-world
+std::cout << "Hello World!\n";
+#+end_src
+
+Error!
+
+#+source: bin-file-3
+#+begin_src cpp :includes <iostream> :results none :compile-only t
+std::cout << "Hello World!\n";
+#+end_src
diff --git a/testing/lisp/test-ob-C.el b/testing/lisp/test-ob-C.el
index c70534a51..11ec262f7 100644
--- a/testing/lisp/test-ob-C.el
+++ b/testing/lisp/test-ob-C.el
@@ -200,5 +200,37 @@ std::cout << (x == y);
                                "\"line 1\"\n\"line 2\"\n\"line 3\"\n"
                                (org-babel-execute-src-block))))))
 
+(ert-deftest ob-C/set-src+bin-file-name-1 ()
+  "Test `:compile-only' header argument."
+  (if (executable-find org-babel-C++-compiler)
+      (unwind-protect
+          (org-test-at-id "1a691f36-f9c1-4531-8fc0-ee7b21ef5975"
+            (org-babel-next-src-block 1)
+            (org-babel-execute-src-block)
+            (should (file-exists-p "./hello-world"))
+            (should (file-exists-p "./hello-world.cpp")))
+        (ignore-errors (delete-file "./hello-world"))
+        (ignore-errors (delete-file "./hello-world.cpp")))))
+
+(ert-deftest ob-C/set-src+bin-file-name-2 ()
+  "Test `:compile-only' header argument."
+  (if (executable-find org-babel-C++-compiler)
+      (unwind-protect
+          (org-test-at-id "1a691f36-f9c1-4531-8fc0-ee7b21ef5975"
+            (org-babel-next-src-block 2)
+            (org-babel-execute-src-block)
+            (should (file-exists-p "./hello-world"))
+            (should (file-exists-p "./hello-world.cpp")))
+        (ignore-errors (delete-file "./hello-world"))
+        (ignore-errors (delete-file "./hello-world.cpp")))))
+
+(ert-deftest ob-C/set-src+bin-file-name-3 ()
+  "Test `:compile-only' header argument."
+  (if (executable-find org-babel-C++-compiler)
+      (should-error
+       (org-test-at-id "1a691f36-f9c1-4531-8fc0-ee7b21ef5975"
+         (org-babel-next-src-block 3)
+         (org-babel-execute-src-block)))))
+
 (provide 'test-ob-C)
 ;;; test-ob-C.el ends here
-- 
2.42.0


  reply	other threads:[~2023-12-13 16:15 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-07 23:10 How to use mpirun with C or C++ Org-babel? Edgar Lux
2023-12-08 10:36 ` tbanelwebmin
2023-12-08 15:47   ` Leo Butler
2023-12-08 22:24     ` Ihor Radchenko
2023-12-13 16:09       ` Leo Butler [this message]
2023-12-14 14:08         ` Ihor Radchenko
2023-12-19 22:14           ` [PATCH] ob-C.el compile-only header argument, was " Leo Butler
2023-12-22 12:20             ` Ihor Radchenko
2024-01-04 17:53               ` Leo Butler
2024-01-05 12:47                 ` Ihor Radchenko
2023-12-20 18:15           ` Leo Butler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87r0jq3x0e.fsf@t14.reltub.ca \
    --to=leo.butler@umanitoba.ca \
    --cc=emacs-orgmode@gnu.org \
    --cc=tbanelwebmin@free.fr \
    --cc=yantar92@posteo.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).