2

The title says it all, and I've included the relevant sections of my file below. I'm trying to create a src block that uses some functionality of the boost libraries, the first src block sets up the compiler, including the libraries to link to. The second src block is just a test function, but it quits with a linker error.

#+begin_src elisp :exports results
   (setq org-babel-C++-compiler
       (concat "g++ -std=c++0x"
               " -lboost_system -lboost_filesystem"
               " -I"
               (expand-file-name ".")
       )
   )
#+end_src


#+begin_src C++ :exports both :includes (list "\"boost/filesystem.hpp\"" "<stdio.h>")
 printf("testing\n");
#+end_src

The error:

/tmp/ccvz9bRM.o: In function __static_initialization_and_destruction_0(int, int)': C-src-2374gem.cpp:(.text+0x51): undefined reference toboost::system::generic_category()' C-src-2374gem.cpp:(.text+0x5d): undefined reference to boost::system::generic_category()' C-src-2374gem.cpp:(.text+0x69): undefined reference toboost::system::system_category()' collect2: error: ld returned 1 exit status /bin/bash: /tmp/babel-2374l5F/C-bin-2374tos: No such file or directory

  • Perhaps the directory containing the boost library is not in the path searched by ld. Try adding -L/path/to/boost before -lboost_system – deprecated Jan 13 '15 at 18:35
  • I tried adding the path and the error still occurred. Judging by stackoverflow.com/questions/11893996/…, it's the order it's being linked in that's causing the problem. – user2699 Jan 13 '15 at 19:35
  • Hmm yes. I see what the problem is now. You need the -lboost_system argument to go after the name of the source file in the compilation command. Looking at the source for org-babel-C-execute, there seems to be no provision for doing that. There is a :flags argument, but that gets put before the source file name. If my understanding is right you will have to hack that function by hand, or send a feature request to the orgmode mailing list. – deprecated Jan 14 '15 at 1:48
  • It's an easy enough fix, it's only two lines that need to be switched. I sent a bug report, and I've changed it in my own file. @deprecated, thanks for looking at it. Should this question be closed then? – user2699 Jan 14 '15 at 15:31
  • Great! I suggest that you write up a summary of your fix as an answer below, which you can then accept. – deprecated Jan 14 '15 at 16:41
2

Use :libs to specify libraries.

((or `c `cpp)
 (org-babel-eval
  (format "%s -o %s %s %s %s"
    (pcase org-babel-c-variant
      (`c org-babel-C-compiler)
      (`cpp org-babel-C++-compiler))
    tmp-bin-file
    flags
    (org-babel-process-file-name tmp-src-file)
    libs)
   ""))

As we can see, org-babel-C-execute will inserts :flags in front of the source file and :libs behind it.

0

First off, it's not necessary to use the elisp code included. The flags property lets compiler flags be passed,

:flags "-lboost_system -std=c++0x"

Unfortunately, due to the order the flags are passed in it's necessary to do some lisp hacking in order to allow linking.

  1. Open the file with the definition of org-babel-C-execute: C-h f org-babel-C-execute, then click on the source file to open it.
  2. Switch the last two arguments to format. It should be (format "%s -o %s %s %s" (cond ((equal org-babel-c-variant 'c) org-babel-C-compiler) ((equal org-babel-c-variant 'cpp) org-babel-C++-compiler)) (org-babel-process-file-name tmp-bin-file) (org-babel-process-file-name tmp-src-file) (mapconcat 'identity (if (listp flags) flags (list flags)) " ") ) ""))))
  3. Load the new function with M-x compile-defun
  4. If you had the file byte compiled, recompile the file with byte-compile-file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.