Showing posts with label Linux. Show all posts
Showing posts with label Linux. Show all posts

Thursday, October 25, 2018

Compiling C++ Codes into shared Library and Linking Them


Compiling C++ Codes into shared library and linking them

Let's say you have files print.h and print.cpp, shown below that contains C++ codes you wish to compile as .so (shared object) file and they are stored in ~/demo/lib folder.

#ifndef __PRINT__
#define __PRINT__

#include <iostream>
#include <stdio.h>
void print(const char* p, bool endl = true);

#endif
#include <print.h>

void print(const char* p, bool endl)
{
std::cout << "print: " << p;
if (endl) std::cout << std::endl;
}

You can compile the above code into .o (static library) file with the command

~/demo/g++ -o lib.o -c ./lib/print.cpp

But we want to compile it as .so (shared library) file so we use the command instead

~/demo/g++ -o ./lib/liblib.so -shared -fpic ./lib/print.cpp

Note that with the above commands, liblib.so and lib.o is created in ~/demo/lib folder upon successful compilation.

Now let's say you have another set of C++ files loop.cpp and loop.h, shown below and you wish to compile them together with another C++ file into an .so file...

#ifndef __LOOP__
#define __LOOP__

#include <iostream>
#include <unistd.h>

class loop
{
public:
loop()
{
std::cout << "loop constructor"<< std::endl;
}
virtual ~loop()
{
std::cout << "loop destructor"<< std::endl;
}

void run(int i, int r);
};

#endif

#include <loop.h>

void loop::run(int i, int r)
{
while(r)
{
sleep(i);
std::cout << "loop..." << std::endl;
r--;
}
}

To compile print.cpp and loop.cpp files into a single .so file, do the command as shown below

~/demo/g++ -o ./lib/liblib.so -shared -fpic ./lib/print.cpp ./lib/loop.cpp

Now that we have .so file already, let's create a C++ program that will use this shared library and use the function and class it contains.
The C++ file below will be our C++ program. It is stored as main.cpp in ~/demo folder.
It uses print() from print.cpp to print "hello world" and uses loop class to perform a loop of 5 intervals.

#include <iostream>
#include <print.h>
#include <loop.h>

int main()
{
print("hello world");
loop p;
p.run(1,5);
return 0;
}

Let's compile this code and link the shared library with it. The command below shows how to compile it into "run".

g++ -o run main.cpp -L/lib -llib -I./lib -I./

If compile is successful, and executable named 'run' should appear in ~/demo folder. If you execute it, you might encounter an error as shown below. This is because when executing a program that has dependency on a shared library, it needs to know where the library is.

run: error while loading shared libraries: liblib.so: cannot open shared object file: No such file or directory

To fix this, you can do either of the two possible solutions

1. Copy the liblib.so into any folder listed in the system's LD_LIBRARY_PATH environment variable. This is a more consistent solution because you only do this once.

2. add ~/demo/lib folder into LD_LIBRARY_PATH environment variable. You have to keep setting this every time you try to execute your program in a new terminal. To do this, follow the command below:

~/setenv LD_LIBRARY_PATH ~/demo/lib:${LD_LIBRARY_PATH}

Now try to run the program again.

Using Makefile 

You can create a makefile to simplify this process. Copy the code below into ~/demo/makefile

all: so main

so : ./lib/print.cpp ./lib/loop.cpp
g++ -o ./lib/liblib.so -shared -fpic ./lib/print.cpp ./lib/loop.cpp -I./lib

main : ./lib/liblib.so
g++ -o run main.cpp -L./lib -llib -I./lib -I ./

Then just call 'make' and the whole compiling process will be done.


Linking the Shared Library (.so) in Unison

In this guide, we will link a share library (.so) in a Unison test program and use the functions and classes defined in the shared library.

1. Optional: copy the .so file as well as its .h header files into test program folder

2. After loading test program, open TestTool



3. In the TestTool, select the application library you want to link the .so file. double-click it to open its settings. Below shows that I selected ST_DLOG application library from my test program.



4.  Click on "Compiler and Linker" tab. Click the "Add Path.." button and select the path where the .so file is located.



5. Once done, you will see the path in the "Linker Paths" list box.



6. In the "Linker Flags" list box, click an empty row. then type -L<.so path> -l<.so name w/o lib prefix>. The -l flag lets me specify the filename of the .so file I want to use, but I without the 'lib' prefix and .so extension. My .so file's filename is liblib.so so removing the prefix and extension, it becomes -llib.



7. Click "Include Paths" tab.



8. Click the "Add Path.." button and select the path where the .h file is selected. Once done, you will see the path in the "Include Paths" list box.



9. Add the include file in the application library's source code. Below shows I declared the include on ST_Datalog.cpp. I included the 2 header files from my shared library - loop.h and print.h



10. Somewhere in ST_Datalog.cpp, i called mydemo::print() function which is defined in the shared library.


11. Finally, compile your application library.










Wednesday, February 8, 2017

How To Install X11VNC on Red Hat Linux (ITE)

1. download installer here
Click me to download X11vnc installer
download the file > x11vnc-0.9.13.tar.gz

2. unzip the file and cd to source directory
(un-tar the x11vnc+libvncserver tarball)
# gzip -dc x11vnc-0.9.13.tar.gz | tar -xvf -
# cd x11vnc-0.9.13

3. compile the source code
(run configure and then run make)
# ./configure
# make
> you may notice some warnings about missing libraries. ignore it for now unless it says critical error

4. run x11vnc server
# cd x11vnc
# ./x11vnc

5. if you need the IP of the linux machine
#ifconfig


Friday, July 15, 2016

EIM FAQ

  • MethodCompiler location
    • Solaris 8 Sun OS: /opt/ltx/bin/, /opt/ltx/releases/<release>/DNT/customer/bin
    • CentOS 4.6: /opt/ltx/releases/<release>/i686*/bin
  • Default EIM source code location
    • enVision (Solaris): /opt/ltx/releases/<version>/customer/test_methods/
    • enVision (CentOS 4.6): 
  • Custom EIM binary location (where the compiled "evso" file is to be placed)
    • enVision (Solaris): 
      • /opt/ltx/releases/<version>/customer/custom_methods/DNT
      • /opt/ltx/releases/<version>/customer/custom_methods/FX1
      • DNT for CX testers while FX1 for FX testers but need to confirm this 
    • enVision (CentOS 4.6): 
      • /opt/ltx/releases/<version>/i686*/custom_methods/DNT
      • /opt/ltx/releases/<version>/i686*/custom_methods/FX1
      • DNT for CX testers while FX1 for FX testers 
  • Command to compile EIM source code
    • >MethodCompiler -t DNT/FX1 -f <file>.tmk
      • Note: Some systems required you to set the full path of MethodCompiler command. 
      • Specify either DNT for DX systems,  or FX1 for X-series systems
  • Do's in Developing EIM 
  • Don'ts in Developing EIMl
  • How to Properly load an EIM into MethodTool
    • enVision only loads EIM's (evso files) that are located in default EIM source code location and custom EIM binary locations.
    • If you have an EIM source code and wishes to load it into MethodTool, follow this:
      • open OpTool>MethodTool
      • in OpTool>MethodTool>Method Directory:, specify the path where your EIM source code is located (cxx, hxx, mid, makefile, etc...)
      • set OpTool>MethodTool>Edit>Tool Mode>External Interface. If you are in the right path, a pop-up will appear letting you select which EIM object to load. select which one you prefer
      • press OpTool>MethodTool>Reload
      • If successful, press OpTool>MethodTool>ExternalInterface and select your EIM. Press OK and your EIM will be loaded successfully