How do I compile DDS code into a shared library in Linux?

11 posts / 0 new
Last post
Offline
Last seen: 8 years 3 months ago
Joined: 04/23/2013
Posts: 17
How do I compile DDS code into a shared library in Linux?

Is it possible to compile RTI DDS code into a shared library, like a .so, and call it from another application? It would be nice if someone already done it with Eclipse, and post the instruction here on the forum. Or is there a makefile that RTI have that can compile DDS example code into the shared library? Please help. Thanks

Fernando Garcia's picture
Offline
Last seen: 3 months 3 weeks ago
Joined: 05/18/2011
Posts: 200

Hi Joseph,

I assume that you want to create a shared library with the code generated by rtiddsgen so that you can link it against other applications. If that is the case, you can do the following:

First, generate an example makefile. In this case we are using C++ and the architecture is x64Linux3gcc4.8.2, but this applies to any other platform.

$ rtiddsgen -language C++ -example x64Linux3gcc4.8.2 hello.idl

This should have generated a makefile called makefile_hello_x64Linux3gcc4.8.2. We are going to make a copy of the original makefile and call it makefile_hello_x64Linux3gcc4.8.2.original, that way you can compare the changes to the original file. 

$ cp makefile_hello_x64Linux3gcc4.8.2 makefile_hello_x64Linux3gcc4.8.2.original

From now on we will editing makefile_hello_x64Linux3gcc4.8.2. In that makefile will find that we are actually building two executables: hello_publisher and hello_subscriber. We are now going to make some changes to link those executables against a shared library that we are going to create and that will contain all the type plugins generated by rtiddsgen. To do so modify the makefile as follows:

  1. Add -fPIC to your compiler flags.
     COMPILER_FLAGS = -m64 -Wall -fPIC
    
  2. Declare a variable called SHARED_LIB where you will name your shared library (e.g., libhello.so).
     EXEC          = hello_subscriber hello_publisher
    SHARED_LIB    = libhello.so
    
  3. Create a new target in the makefile called objs/$(TARGET_ARCH)/$(SHARED_LIB)
     objs/$(TARGET_ARCH)/$(SHARED_LIB): $(COMMONOBJS)                                                                                                                               
            $(LINKER) $(LINKER_FLAGS) -shared -o $@ $(COMMONOBJS) $(LIBS)                                                                                                
    
  4. Add the new target to the dependencies of  $(TARGET_ARCH):
     # We actually stick the objects in a sub directory to keep your directory clean.                                                                                               
    $(TARGET_ARCH) : $(DIRECTORIES) $(COMMONOBJS) \                                                                                                                                
            objs/$(TARGET_ARCH)/$(SHARED_LIB) \                                                                                                                                    
            $(EXEC:%=objs/$(TARGET_ARCH)/%.o) \                                                                                                                                    
            $(EXEC:%=objs/$(TARGET_ARCH)/%)                                                                                                                           
    
  5. Modify the objs/$(TARGET_ARCH)/% target to use the new shared library instead of the orignial common object files:
     objs/$(TARGET_ARCH)/% : objs/$(TARGET_ARCH)/$(SHARED_LIB)                                                                                                                      
            $(LINKER) $(LINKER_FLAGS) -o $@ $@.o \                                                                                                                               
            objs/$(TARGET_ARCH)/$(SHARED_LIB) $(LIBS)                                                                                                                           
    

Once you have done those changes, you can run the makefile as follows. You will find the library and executables you have created under objs/$(TARGET_ARCH):

$ make -f makefile_hello_x64Linux3gcc4.8.2
$ ls objs/x64Linux3gcc4.8.2/
hello.o helloPlugin.o hello_publisher hello_publisher.o hello_subscriber hello_subscriber.o helloSupport.o libhello.so
$ ldd objs/x64Linux3gcc4.8.2/hello_publisher
	linux-vdso.so.1 =>  (0x00007fffde1ab000)
	objs/x64Linux3gcc4.8.2/libhello.so (0x00007fb24e117000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fb24deef000)
	libnsl.so.1 => /lib/x86_64-linux-gnu/libnsl.so.1 (0x00007fb24dcd5000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb24dab8000)
	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fb24d8b0000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fb24d52d000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb24d224000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb24ce5b000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fb24cc44000)
	/lib64/ld-linux-x86-64.so.2 (0x0000560240da3000)

Please, let me know if this is what you were looking for or you have doubts on how to make the appropriate changes in your makefile. I think it is probably better to do these changes at the makefile level, so that you can compile both from Eclipse and from the command line.

Thanks,
Fernando.

Offline
Last seen: 8 years 3 months ago
Joined: 04/23/2013
Posts: 17

Thanks Fernando. I didn't expect to get a quick answer, but you did. Thanks again, and it works perfect.

Just little mispell on line 64 "LIKER" should be "LINKER"

Fernando Garcia's picture
Offline
Last seen: 3 months 3 weeks ago
Joined: 05/18/2011
Posts: 200

That is great! I have just fixed line 64, thanks for pointing that out.

Best,
Fernando.

Offline
Last seen: 8 years 3 months ago
Joined: 04/23/2013
Posts: 17

And I am trying to model your makefile to do a static library, but no luck. Would you be kind and show me how to compile and build a static library also? Thanks Fernando.

Fernando Garcia's picture
Offline
Last seen: 3 months 3 weeks ago
Joined: 05/18/2011
Posts: 200

Hi Joseph,

If you want to create a static library as well you will need to use the ar archiver. Plese, modify your makefile as follows:

  1. Declare your archiver:
    ifndef ARCHIVER                                                                                                                                                                                                    
    ARCHIVER = ar                                                                                                                                                                                                      
    endif                                                                                                                                                                                                              
    
  2. Declare the name of your static library:
    STATIC_LIB    = libhello.a
  3. Create a new target to create the static library.
    objs/$(TARGET_ARCH)/$(STATIC_LIB): $(COMMONOBJS)                                                                                                                                                                   
            $(ARCHIVER) rcs $@ $(COMMONOBJS)
    
  4. Add the new target to the list of dependencies for $(TARGET_ARCH):
    # We actually stick the objects in a sub directory to keep your directory clean.                                                                                                                                   
    $(TARGET_ARCH) : $(DIRECTORIES) $(COMMONOBJS) \                                                                                                                                                                    
            objs/$(TARGET_ARCH)/$(SHARED_LIB) \                                                                                                                                                                        
            objs/$(TARGET_ARCH)/$(STATIC_LIB) \                                                                                                                                                                        
            $(EXEC:%=objs/$(TARGET_ARCH)/%.o) \                                                                                                                                                                        
            $(EXEC:%=objs/$(TARGET_ARCH)/%)                                                                                                                                                                            
    
  5. Optionally modify the way you build your executables to link against the new static library:
    objs/$(TARGET_ARCH)/% : objs/$(TARGET_ARCH)/$(SHARED_LIB)                                                                                                                                                          
            $(LINKER) $(LINKER_FLAGS)   -o $@ $@.o \                                                                                                                                                                   
            objs/$(TARGET_ARCH)/$(STATIC_LIB) $(LIBS)                                                                                                                                                                  
    

Please, let me know if this solves your issue.

Thanks,
Fernando 

Offline
Last seen: 8 years 3 months ago
Joined: 04/23/2013
Posts: 17

Yes sir. That solves it. Thank you, thank you.

Offline
Last seen: 8 years 3 months ago
Joined: 04/23/2013
Posts: 17

Fernando,

If I use this static library (libhello.a) to link into another application, do I need to set any RTI DDS compiler/linker flags in that application at all? Just link the library, and specify the path, and add the include file? I am not sure why I can't call the function inside the lib. Do you have any suggestion? Thanks

Offline
Last seen: 7 years 2 months ago
Joined: 03/04/2016
Posts: 1

Hello Mr Fernando

I have incorporated the changes as given by you. But i am getting errors like publisher.o file not found etc. while i am running my makefile. 

Kindly help.

 

 

Fernando Garcia's picture
Offline
Last seen: 3 months 3 weeks ago
Joined: 05/18/2011
Posts: 200

Hi Shikha,

Are you modifying the makefile generated by rtiddsgen? Could you post makefile so that we can help you figure out the problem?

Thanks,
Fernando.

Offline
Last seen: 2 years 7 months ago
Joined: 03/18/2022
Posts: 1

 

Hello Fernando,

I am trying to create shared library( static and dynamic) . I am getting the below error. Also attached the makefile

/usr/lib/gcc/x86_64-redhat-linux/8/../../../../lib64/crt1.o: In function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [makefile_SimulatorIDL_x64Linux4gcc7.3.0:105: objs/x64Linux4gcc7.3.0/libRTISimulator.so] Error 1
[paras@localhost RTI_SIM]$ vi makefile_SimulatorIDL_x64Linux4gcc7.3.0

 

 

Regards

Chand