Menu

Using lincan in a shared object

Help
2008-09-09
2013-06-04
  • Justin Teems

    Justin Teems - 2008-09-09

    Hey all,

    I'm using lincan on the Technologic Systems TS-CAN1, which uses the OCERA LinCAN and VCA libraries. I'm trying to link the VCA library into a shared object, and its giving me a world of grief. Doing the following in the makefile:

    CXX = g++
    CXXFLAGS = -O2 -Wall -fPIC -D__ALIGN_32
    LDFLAGS = -Ur -shared
    INCS = -I../include

    LIBS :=  $(LIBS) -L./lincan-7800/lib -lvca -lulut

    all: examplePlugin.ecp

    examplePlugin.ecp: examplePlugin.cpp toolcatInterface.o
        $(CXX) $(LDFLAGS) $(INCS) $(LIBS) $? -o $@

    This compiles, but it isn't linking to the VCA and ULUT libraries properly. The symbols for the vca_* remain undefined. If anyone could point me in the right direction or lend a helping hand, I'd greatly appreciate it. Thanks!

    Justin

     
    • Pavel Pisa

      Pavel Pisa - 2008-09-09

      Hello Justin,

      I do not see, where is the problem.
      Please, could you send me even directly some minimal code which does not work.
      Your report does not specify LinCAN and VCA version etc.

      Can you reproduce the problem with versions build form CVS

      http://cmp.felk.cvut.cz/~pisa/#can

      You need to specify compiler and kernel sources directory in config.omk if you want
      to cross-compile code for different target. There is some example
      which I use for our ARM build

      LINUX_DIR=/usr/src/linux-2.6.23/_build/arm
      CC=arm-linux-gcc
      CXX=arm-linux-g++
      AR=arm-linux-ar
      LD=arm-linux-ld

      CFLAGS+=-ggdb
      CFLAGS+=-O2
      CFLAGS+=-Wall

      You can use driver provided with your board with newly compiled VCA.
      I have re-tested even build of VCA as shared library

      This requires to add

      CONFIG_OC_SOLIBS=y

      into config.omk

      The next advanced linker option specifies, that binaries
      dependent on shared libraries should add library search path
      even to directory ../lib relative to binary

        LDFLAGS += '-Wl,-rpath,$$ORIGIN/../lib'  --enable-new-dtags

      This allows to run binaries even without specifying LD_LIBRARY_PATH
      or copying libraries to the directories which ldconfig knows about.

      May it be, that you want to use libvca.a and link from it into your .so
      library. You can try to add

      CXXFLAGS = -O2 -Wall -fPIC
      CFLAGS = -O2 -Wall -fPIC

      into config.omk and build without CONFIG_OC_SOLIBS.
      Than the code should became part of your library.

      You can try to use OMK rules and makefiles even for your
      library or program. But it is not be required.
      Your Makefile fragment should be OK. Check, that
      -L./lincan-7800/lib in LIBS exactly points to the right
      directory for compilation or use absolute path.

      You should send at least shortened make output to allow me analyze problem.

        make >make.out 2>&1

      Best wishes,

                            Pavel

       
    • Justin Teems

      Justin Teems - 2008-09-10

      Hi Pavel,

      >>May it be, that you want to use libvca.a and link from it into your .so
      >> library. You can try to add

      >> CXXFLAGS = -O2 -Wall -fPIC
      >> CFLAGS = -O2 -Wall -fPIC

      >> into config.omk and build without CONFIG_OC_SOLIBS.
      >> Than the code should became part of your library.

      >> You can try to use OMK rules and makefiles even for your
      >> library or program. But it is not be required.
      >> Your Makefile fragment should be OK. Check, that
      >> -L./lincan-7800/lib in LIBS exactly points to the right
      >> directory for compilation or use absolute path.

      >> You should send at least shortened make output to allow me analyze problem.

      The scenario you describe above is exactly what I am trying to do, but I have not been able to get this to work.

      I followed your instructions above, (adding the -O2 -Wall -fPIC flags) successfully rebuilding libulut.a and libvca.a.

      The complete makefile for my build is as follows:
      CXX = g++
      CXXFLAGS = -O2 -Wall -fPIC -D__ALIGN_32
      LDFLAGS = -Ur -shared -rdynamic
      INCS = -I../include

      #general.make and jLib.make include flags neccesary to link to these internal libraries. No issues with these libraries
      include $(ENV_DIR)/general.make
      include $(JLIB_HOME)/include/jLib.make

      LIBS := -L./lincan-7800/lib -lvca -lulut  $(LIBS)

      all: examplePlugin.ecp

      examplePlugin.ecp: examplePlugin.o toolcatInterface.o
          $(CXX) -fPIC $(LDFLAGS) $(INCS) $(CPPFLAGS) $(LIBS) $? -o $@

      examplePlugin.o: examplePlugin.cpp
          $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCS) -c $< -o $@

      toolcatInterface.o: toolcatInterface.cpp
          $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCS) -c $< -o $@

      clean:
          rm *.o *.ecp

      The make.out file is as follows:

      g++ -O2 -Wall -fPIC -D__ALIGN_32 -DLENDIAN -DSYSV5  -DLINUX -DTARGET_NAME=\&quot;\&quot; -DVERSION=""   -I. -I/home/tagscx/software/environment -I /home/tagscx/software/jLib/include -DPARAM_JLIB_SUPPORT -I /home/tagscx/software/jLib/include -DPARAM_JLIB_SUPPORT -I../include -c examplePlugin.cpp -o examplePlugin.o
      g++ -O2 -Wall -fPIC -D__ALIGN_32 -DLENDIAN -DSYSV5  -DLINUX -DTARGET_NAME=\&quot;\&quot; -DVERSION=""   -I. -I/home/tagscx/software/environment -I /home/tagscx/software/jLib/include -DPARAM_JLIB_SUPPORT -I /home/tagscx/software/jLib/include -DPARAM_JLIB_SUPPORT -I../include -c toolcatInterface.cpp -o toolcatInterface.o
      g++ -fPIC -Ur -shared -rdynamic -I../include -DLENDIAN -DSYSV5  -DLINUX -DTARGET_NAME=\&quot;\&quot; -DVERSION=""   -I. -I/home/tagscx/software/environment -I /home/tagscx/software/jLib/include -DPARAM_JLIB_SUPPORT -I /home/tagscx/software/jLib/include -DPARAM_JLIB_SUPPORT -L./lincan-7800/lib -lvca -lulut  -lrt -lm -L /home/tagscx/software/jLib/lib -ljLib examplePlugin.o toolcatInterface.o -o examplePlugin.ecp

      nm examplePlugin.ecp | grep -i vca_ provides:

               U vca_close_handle
               U vca_open_handle
               U vca_rec_msg_seq
               U vca_send_msg_seq
               U vca_wait

      Where there clearly should be a T to have text associated with the symbol! This should not be happening, as when I call dlopen in my application, the symbols cannot be found.

      I am at a complete loss as to why the OCERA VCA library will not link into my shared object. Everything I have referenced tells me that examplePlugin.ecp should link to libvca.a and libulut.a. nm does show that symbols for my internal libraries are being linked in. Any and all help is appreciated. Thanks much!!

      Justin

       
    • Pavel Pisa

      Pavel Pisa - 2008-09-15

      Hello Justin,

      I do not see problem source yet. I have tested shared compilation of libraries
      and programs and it works. Please, check next things:

        - that you are compiling VCA and your code by same compiler
        - that you do not use g++ to compile VCA, but even that should not
          be a problem
        - that you do not have dynamic versions of uLUt ulut.so and VCA
           vca.so

      You can try to use   -Wl,-Map,$^.lib.map for g++ invocation when
      linking library and program.

      And last but most probable, try to omit -Ur from LDFLAGS.
      It commands g++/ld to link relocatable object which should be
      used as input for g++/ld program again.

      Best wishes,

                             Pavel

       

Log in to post a comment.