@@ -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