1

I suspect this is a bone-headed newbie question, but it's one I cannot answer on my own.

I want to develop a program on Ubuntu 12.04 LTS (32-bit) with an embedded javascript engine. I've tried downloading SpiderMonkey but couldn't work out how to link against it. So, I've downloaded the V8 sources, which at least have an example program with linking instructions on the Google Developers site.

I've downloaded the sources and built in /some/path/or/other/v8 and have put the example source into v8Ex1 (I had hoped to move swiftly to examples 2, 3 and 4 - but no luck so far) in /some/path/or/other.

Once I worked out what to change for a 32-bit rather than 64-bit build, I was able to build and run the example using the command line

g++ -Iv8/include v8Ex1.cc -o v8Ex1 -Wl,--start-group v8/out/ia32.release/obj.target/{tools/gyp/libv8_{base.ia32,snapshot},third_party/icu/libicu{uc,i18n,data}}.a -Wl,--end-group -lrt

My next step was to determine how bash expanded that command line:

g++ -Iv8/include v8Ex1.cc -o v8Ex1 \
  -Wl,--start-group v8/out/ia32.release/obj.target/tools/gyp/libv8_base.ia32.a \
  v8/out/ia32.release/obj.target/tools/gyp/libv8_snapshot.a \
  v8/out/ia32.release/obj.target/third_party/icu/libicuuc.a \
  v8/out/ia32.release/obj.target/third_party/icu/libicui18n.a \
  v8/out/ia32.release/obj.target/third_party/icu/libicudata.a \
  -Wl,--end-group -lrt

This command works fine, building an executable without producing any errors or warnings.

I anticipate having multiple source files in my program, so I'll eventually have several object files and will need to link them together.

My next step was to construct separate compiler and linker commands

g++ -c -Iv8/include v8Ex1.cc -o v8Ex1.o

compiles the program just fine, but I haven't been able to work out what the corresponding linker command should be. My best guess is

ld -o v8Ex1 v8Ex1.o --start-group \
  v8/out/ia32.release/obj.target/tools/gyp/libv8_base.ia32.a \
  v8/out/ia32.release/obj.target/tools/gyp/libv8_snapshot.a \
  v8/out/ia32.release/obj.target/third_party/icu/libicuuc.a \
  v8/out/ia32.release/obj.target/third_party/icu/libicui18n.a \
  v8/out/ia32.release/obj.target/third_party/icu/libicudata.a --end-group -lrt

But this gives me 3257 errors, starting with the below:

/usr/bin/ld.bfd.real: warning: cannot find entry symbol _start; defaulting to 000000000804a2e0
v8Ex1.o: In function `main':
v8Ex1.cc:(.text+0x1ab): undefined reference to `_Unwind_Resume'
v8Ex1.o:(.eh_frame+0x4b): undefined reference to `__gxx_personality_v0'
v8/out/ia32.release/obj.target/v8_base.ia32/src/isolate.o: In function `v8::internal::DateCache::~DateCache()':
isolate.cc:(.text._ZN2v88internal9DateCacheD0Ev[_ZN2v88internal9DateCacheD5Ev]+0xb): undefined reference to `operator delete(void*)'
v8/out/ia32.release/obj.target/v8_base.ia32/src/isolate.o: In function `v8::internal::Isolate::FindOrAllocatePerThreadDataForThisThread()':
isolate.cc(.text._ZN2v88internal7Isolate40FindOrAllocatePerThreadDataForThisThreadEv+0x88): undefined reference to `operator new(unsigned int)'
v8/out/ia32.release/obj.target/v8_base.ia32/src/isolate.o: In function `v8::internal::Isolate::StackTraceString()':
isolate.cc:(.text._ZN2v88internal7Isolate16StackTraceStringEv+0x15a): undefined reference to `operator delete[](void*)'
v8/out/ia32.release/obj.target/v8_base.ia32/src/isolate.o: In function `v8::internal::Isolate::PrintStack(_IO_FILE*)':
isolate.cc:(.text._ZN2v88internal7Isolate10PrintStackEP8_IO_FILE+0x15f): undefined reference to `operator delete[](void*)'
isolate.cc:(.text._ZN2v88internal7Isolate10PrintStackEP8_IO_FILE+0x1f0): undefined reference to `operator new(unsigned int)'
isolate.cc:(.text._ZN2v88internal7Isolate10PrintStackEP8_IO_FILE+0x218): undefined reference to `operator new(unsigned int)'

Please can someone help me out with the correct linker command. I think I'll be able to wrap it into a Makefile OK on my own and then it'll be full speed ahead with my program.

nurdglaw
  • 2,107
  • 19
  • 37
  • Learn how libraries work you must, linking against spider monkey, hard it is not. If you never learn this, screwed, you will be. Talk backwards I do, thinking of Yoda I am (for some reason). – Alec Teal Mar 06 '14 at 21:51
  • Seriously though, compiling a library is not the same as using it; there's a huge difference between static and dynamic linking. – Alec Teal Mar 06 '14 at 21:52
  • Screwed I am; admit it I do. Help I beg – nurdglaw Mar 06 '14 at 21:53
  • Search for "creating a shared library linux" and enjoy, it's really easy. Then linking will make sense and you can write it confidently. I was like you once (noob I was :P) and I hate that red-faced "C'MON IT'S SIMPLE!" feeling you get when copy-and-pasting doesn't work, you need to relax and learn. Unix stuff is REALLY easy because you can deduce how it all works just from knowing what it does. – Alec Teal Mar 06 '14 at 21:56
  • Please forgive me for responding without searching for how to create a shared library, but surely I'm trying to create an executable, not a shared library. I agree that shared libraries in a sensible place somewhere would probably be easier to link against than the current selection of archive files in assorted places, but I have to start somewhere and I think my choice of trying to build an executable, hiding all the nastiness in a Makefile is a good one. By all means, persuade me otherwise... – nurdglaw Mar 06 '14 at 22:02
  • The linker is STUPID, right, every object file just contains a list of stuff it needs, and a list of stuff it defines, the linker finds definitions and writes where it found them to wherever it is needed. When you link with a library the linker (depending on static or dynamic) does the same thing, it just copies where it finds functions in the library to where you use them. Linker commands just tell it where to look. – Alec Teal Mar 06 '14 at 22:05
  • This is because in ye-olden days, computers didn't have much memory. Function prototypes in C/C++ just say "this exists" (something the linker will find in the object files afterwards) see here http://stackoverflow.com/questions/18543980/symbol-not-found-when-using-template-defined-in-a-library/18544093#18544093 that shows this in action – Alec Teal Mar 06 '14 at 22:06
  • Addendum: The runtime (dynamic) linker isn't much better, the linking that happened during complication writes a note to the dynamic linker saying "try and find these libraries" then that linker has a gander for them, and simply copies the definitions in the library to where they are needed in the program. – Alec Teal Mar 06 '14 at 22:09
  • You now know all there is to know about linking – Alec Teal Mar 06 '14 at 22:09
  • Alec, I **think** I understand what a linker does. I need some help in working out how to tell it what to do. I have a lot of experience using an old-time o/s from ye-olden days called VMS. I have less experience using UNIX. As far as I can make out, the `g++` command from the Google Developers site says to take the object file produced by the compiler and resolve the symbols by looking in several archives and to keep looking in them until no additional unresolved symbols are introduced; it will also search for symbols in librt.so. I'm obviously missing something as I can't make it do that. – nurdglaw Mar 06 '14 at 22:13
  • ...with an `ld` command. – nurdglaw Mar 06 '14 at 22:14
  • You should avoid using ld these days, GCC can link it's own binaries, infact g++ and gcc link by default, you use -c to make them only compile. g++ differs from gcc in only that gcc will not include c++ stdlibs (you must explicitly tell it to). `g++ a.o b.o` will create an `a.out` (use `-o` to specify an output). This is because they add info to it, for example link time optimisation, remember the linker is thick, it wouldn't know what to do with it. – Alec Teal Mar 06 '14 at 22:17
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/49185/discussion-between-nurdglaw-and-alec-teal) – nurdglaw Mar 06 '14 at 22:18
  • +1 for tech support. Good luck to all. – shellter Mar 06 '14 at 22:27
  • http://academia.stackexchange.com/questions/17830/how-to-tell-an-over-confident-student-he-still-has-a-lot-to-learn was this you? :P (from hot questions, weird right?) – Alec Teal Mar 06 '14 at 22:34

1 Answers1

0

You haven't specified the linker errors you're seeing, so I can't help with that, but the following information may be helpful:

  1. If you have multiple source files, you can still compile/link them in one go:

    g++ -Iv8/include v8Ex1.cc othersource.cc othersource2.cc -o v8Ex1 \ 
      -Wl,--start-group v8/out/ia32.release/obj.target/tools/gyp/libv8_base.ia32.a \ 
      v8/out/ia32.release/obj.target/tools/gyp/libv8_snapshot.a \ 
      v8/out/ia32.release/obj.target/third_party/icu/libicuuc.a \ 
      v8/out/ia32.release/obj.target/third_party/icu/libicui18n.a \ 
      v8/out/ia32.release/obj.target/third_party/icu/libicudata.a \ 
      -Wl,--end-group -lrt
    
  2. If you want to compile them separately (e.g. to save time on incremental builds), you can link using g++ - just specify the .o files in place of the .c/.cc files:

    g++ -Iv8/include v8Ex1.o othersource.o othersource2.o -o v8Ex1 \
      -Wl,--start-group v8/out/ia32.release/obj.target/tools/gyp/libv8_base.ia32.a \
      v8/out/ia32.release/obj.target/tools/gyp/libv8_snapshot.a \
      v8/out/ia32.release/obj.target/third_party/icu/libicuuc.a \
      v8/out/ia32.release/obj.target/third_party/icu/libicui18n.a \
      v8/out/ia32.release/obj.target/third_party/icu/libicudata.a \
      -Wl,--end-group -lrt
    

This might save some wrestling with the arguments to ld.

psmears
  • 26,070
  • 4
  • 40
  • 48
  • Apologies for not including errors in the original post; also for the tardy reply - I've been away for a week. – nurdglaw Mar 16 '14 at 09:12