Skip to content

Commit e0351e0

Browse files
committed
feat: add ob cmake-cpp
1 parent 4dac6d8 commit e0351e0

1 file changed

Lines changed: 161 additions & 15 deletions

File tree

README.org

Lines changed: 161 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2320,21 +2320,21 @@ ref:https://github.com/manateelazycat/toggle-one-window
23202320
(org-confirm-babel-evaluate nil)
23212321
(org-export-use-babel nil)
23222322
(org-src-lang-modes '(("C" . c-ts)
2323-
("C++" . c++-ts)
2324-
("asymptote" . asy)
2325-
("bash" . sh)
2326-
("beamer" . latex)
2327-
("calc" . fundamental)
2328-
("cpp" . c++-ts)
2329-
("ditaa" . artist)
2330-
("desktop" . conf-desktop)
2331-
("dot" . fundamental)
2332-
("elisp" . emacs-lisp)
2333-
("ocaml" . tuareg)
2334-
("screen" . shell-script)
2335-
("shell" . sh)
2336-
("sqlite" . sql)
2337-
("toml" . conf-toml)))
2323+
("C++" . c++-ts)
2324+
("asymptote" . asy)
2325+
("bash" . sh)
2326+
("beamer" . latex)
2327+
("calc" . fundamental)
2328+
("cpp" . c++-ts)
2329+
("ditaa" . artist)
2330+
("desktop" . conf-desktop)
2331+
("dot" . fundamental)
2332+
("elisp" . emacs-lisp)
2333+
("ocaml" . tuareg)
2334+
("screen" . shell-script)
2335+
("shell" . sh)
2336+
("sqlite" . sql)
2337+
("toml" . conf-toml)))
23382338
:config
23392339
(org-babel-do-load-languages 'org-babel-load-languages
23402340
'((emacs-lisp . t)
@@ -2369,6 +2369,152 @@ ref:https://github.com/manateelazycat/toggle-one-window
23692369
))
23702370
(advice-add #'org-babel-C-execute :filter-args 'my*org-babel-execute-add-stdin)
23712371

2372+
(defun org-babel-execute:cmake-cpp (body params)
2373+
"Execute a C++ code block with CMake.
2374+
BODY is the source code. PARAMS is the header arguments alist.
2375+
2376+
Header arguments:
2377+
:pkgs - Package(s) for find_package.
2378+
:libs - Library(ies) for target_link_libraries.
2379+
:includes - Include directory(ies).
2380+
:defines - Compile definition(s).
2381+
:cmake-flags - Flags passed to cmake configure step.
2382+
:flags - Extra compiler flags (appended to CMAKE_CXX_FLAGS).
2383+
:std - C++ standard version (default \"20\").
2384+
:cmdline - Arguments passed to the compiled binary at runtime.
2385+
:extra-src - Named block(s) prepended to main source before compilation."
2386+
(cl-labels
2387+
((listify
2388+
(val)
2389+
(cond ((null val) nil)
2390+
((listp val) val)
2391+
(t (list val))))
2392+
2393+
(parse-params
2394+
()
2395+
(list :packages (listify (cdr (assq :pkgs params)))
2396+
:libs (listify (cdr (assq :libs params)))
2397+
:includes (listify (cdr (assq :includes params)))
2398+
:defines (listify (cdr (assq :defines params)))
2399+
:extra-srcs (listify (cdr (assq :extra-src params)))
2400+
:cmake-flags (cdr (assq :cmake-flags params))
2401+
:flags (cdr (assq :flags params))
2402+
:std (or (cdr (assq :std params)) "20")
2403+
:cmdline (cdr (assq :cmdline params))))
2404+
2405+
(resolve-block
2406+
(name)
2407+
"Return the expanded source body of the named org block NAME.
2408+
Must be called from the org buffer."
2409+
(let ((info (org-babel-find-named-block name)))
2410+
(unless info
2411+
(error "Named block '%s' not found" name))
2412+
(save-excursion
2413+
(goto-char info)
2414+
(org-babel-expand-src-block))))
2415+
2416+
(resolve-all-extra-srcs
2417+
(parsed)
2418+
"Resolve all extra source blocks while still in the org buffer.
2419+
Returns a list of source strings."
2420+
(mapcar #'resolve-block (plist-get parsed :extra-srcs)))
2421+
2422+
(write-source
2423+
(src-file extra-bodies)
2424+
"Write assembled C++ source to SRC-FILE.
2425+
EXTRA-BODIES is a list of already-resolved source strings."
2426+
(with-temp-file src-file
2427+
(dolist (body-str extra-bodies)
2428+
(insert body-str)
2429+
(insert "\n"))
2430+
(insert body)))
2431+
2432+
(write-cmakelists
2433+
(cmake-file parsed)
2434+
(with-temp-file cmake-file
2435+
(insert "cmake_minimum_required(VERSION 3.15)\n"
2436+
"project(org-babel-cmake CXX)\n"
2437+
"if(POLICY CMP0144)\n"
2438+
" cmake_policy(SET CMP0144 NEW)\n"
2439+
"endif()\n"
2440+
(format "set(CMAKE_CXX_STANDARD %s)\n"
2441+
(plist-get parsed :std))
2442+
"set(CMAKE_CXX_STANDARD_REQUIRED ON)\n"
2443+
"set(CMAKE_CXX_EXTENSIONS OFF)\n")
2444+
(let ((flags (plist-get parsed :flags)))
2445+
(when flags
2446+
(insert (format "set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} %s\")\n"
2447+
flags))))
2448+
(dolist (pkg (plist-get parsed :packages))
2449+
(insert (format "find_package(%s REQUIRED)\n" pkg)))
2450+
(dolist (inc (plist-get parsed :includes))
2451+
(insert (format "include_directories(%s)\n" inc)))
2452+
(dolist (def (plist-get parsed :defines))
2453+
(insert (format "add_definitions(-D%s)\n" def)))
2454+
(insert "add_executable(main main.cpp)\n")
2455+
(dolist (lib (plist-get parsed :libs))
2456+
(insert (format "target_link_libraries(main %s)\n" lib)))))
2457+
2458+
(configure
2459+
(tmp-dir parsed)
2460+
(org-babel-eval
2461+
(format "cmake -S %s -B %s %s"
2462+
(shell-quote-argument tmp-dir)
2463+
(shell-quote-argument tmp-dir)
2464+
(or (plist-get parsed :cmake-flags) ""))
2465+
""))
2466+
2467+
(build
2468+
(tmp-dir)
2469+
(org-babel-eval
2470+
(format "cmake --build %s -- -j$(nproc)"
2471+
(shell-quote-argument tmp-dir))
2472+
""))
2473+
2474+
(run
2475+
(bin-file parsed)
2476+
(org-babel-eval
2477+
(concat (shell-quote-argument bin-file)
2478+
(let ((cmdline (plist-get parsed :cmdline)))
2479+
(when cmdline (concat " " cmdline))))
2480+
""))
2481+
2482+
(format-result
2483+
(raw-result)
2484+
(when raw-result
2485+
(let ((result (org-remove-indentation raw-result)))
2486+
(org-babel-reassemble-table
2487+
(org-babel-result-cond (cdr (assq :result-params params))
2488+
result
2489+
(let ((tmp-file (org-babel-temp-file "c-")))
2490+
(with-temp-file tmp-file (insert result))
2491+
(org-babel-import-elisp-from-file tmp-file)))
2492+
(org-babel-pick-name
2493+
(cdr (assq :colname-names params))
2494+
(cdr (assq :colnames params)))
2495+
(org-babel-pick-name
2496+
(cdr (assq :rowname-names params))
2497+
(cdr (assq :rownames params))))))))
2498+
2499+
;; ---------- main ----------
2500+
(let* ((parsed (parse-params))
2501+
(extra-bodies (resolve-all-extra-srcs parsed)) ;; ← 在 org buffer 中解析
2502+
(tmp-dir (make-temp-file "ob-cmake-" t))
2503+
(src-file (expand-file-name "main.cpp" tmp-dir))
2504+
(bin-file (expand-file-name "main" tmp-dir))
2505+
(cmake-file (expand-file-name "CMakeLists.txt" tmp-dir))
2506+
(result nil))
2507+
(unwind-protect
2508+
(progn
2509+
(write-source src-file extra-bodies) ;; ← 传入已解析的字符串
2510+
(write-cmakelists cmake-file parsed)
2511+
(configure tmp-dir parsed)
2512+
(build tmp-dir)
2513+
(setq result (run bin-file parsed)))
2514+
(delete-directory tmp-dir t))
2515+
(format-result result))))
2516+
2517+
23722518
)
23732519
#+end_src
23742520

0 commit comments

Comments
 (0)