Makefileコンパイルダイナミックライブラリファイルとリンクダイナミックライブラリ

38347 ワード

原文の回転:http://www.cnblogs.com/ljtknowns/p/5647793.html
ファイルディレクトリの構造は以下の通りです.
1 dynamiclibapp.c
2 Makefile
3 comm/inc/apue.h
4 comm/errorhandle.c
5 dynamiclib/Makefile
6 dynamiclib/dynamiclib_add.c
7 dynamiclib/dynamiclib_mul.c
8 dynamiclib/inc/dynamiclibs.h
9 dynamiclib/libs/

1.dynamiclibディレクトリ
    dynamiclib/inc/dynamiclibs.hファイルの内容は以下の通りです.
1 #ifndef __dynamic_libs_h__
2 #define __dynamic_libs_h__
3 
4 #include "apue.h"
5 int dynamic_lib_func_add(int i1, int i2);
6 int dynamic_lib_func_mul(int i1, int i2);
7 
8 #endif

    dynamiclib/dynamiclib_add.cファイルの内容は以下の通りです.
1 #include "dynamiclibs.h"
2 
3 int dynamic_lib_func_add(int i1, int i2) 
4 {
5     int iret = i1 + i2; 
6     printf("... in .so func, %d add %d,return %d
", i1, i2, iret); 7 return iret; 8 }

    dynamiclib/dynamiclib_mul.clファイルの内容は以下の通りです.
1 #include "dynamiclibs.h"
2 
3 int dynamic_lib_func_mul(int i1, int i2) 
4 {
5     int iret = i1 * i2; 
6     printf("... in .so func, %d multiplys %d, retun %d
", i1, i2, iret); 7 return iret; 8 }

    dynamiclib/Makefileファイルの内容は以下の通りです.
 1 CC       = gcc 
 2 CFLAGS   = -Wall -g -O -fPIC          -fPIC
 3 CXXFLAGS = 
 4 INCLUDE  = -I ./inc -I ../comm/inc
 5 TARGET   = libmytest.so
 6 LIBPATH  = ./libs/
 7 
 8 vpath %.h ./inc
 9 
10 OBJS     = dynamiclib_add.o dynamiclib_mul.o
11 SRCS     = dynamiclib_add.c dynamiclib_mul.c
12 
13 $(OBJS):$(SRCS)
14    $(CC) $(CFLAGS) $(INCLUDE) -c $^
15 
16 all:$(OBJS)
17    $(CC) -shared -fPIC -o $(TARGET) $(OBJS)         -shared -fPIC
18    mv $(TARGET) $(LIBPATH)
19 
20 clean:
21    rm -f *.o
22    rm -f $(LIBPATH)*

    以上のファイルはダイナミックライブラリファイルlibmystest.soを生成できます.アプリケーションは2つの方法でダイナミックライブラリ関数をロードします.
2.アプリケーションをコンパイルするときにダイナミックライブラリを読み込みます.
    dynamiclibapp.cファイルの内容は以下の通りです.
 1 #include "apue.h"
 2 #include "dynamiclibs.h"
 3 
 4 int main(int argc, char *argv[])
 5 {
 6     err_msg("step in main
"); 7 dynamic_lib_func_add(1, 9); 8 dynamic_lib_func_mul(1, 9); 9 err_msg("step out main
"); 10 11 return 0; 12 }

    Makefileファイルの内容は以下の通りです.
 1 CC       = gcc 
 2 CFLAGS   = -Wall -O -g
 3 CXXFLAGS = 
 4 INCLUDE  = -I ./comm/inc -I ./dynamiclib/inc
 5 TARGET   = dynamiclibapp
 6 LIBVAR   = -lmytest                       libmytest.so
 7 LIBPATH  = -L./dynamiclib/libs     libmytest.so    
 8 #search paths for errorhandler.c
 9 vpath %.c ./comm
10 #        apue.h    ,   [errorhandler.o:errorhandler.c apue.h]    apue.h
11 vpath %.h ./comm/inc
12 
13 OBJS     = errorhandler.o dynamiclibapp.o
14 #    apue.h,       
15 errorhandler.o:errorhandler.c apue.h
16    $(CC) $(CFLAGS) $(INCLUDE) -c $^
17 dynamiclibapp.o:dynamiclibapp.c apue.h
18    $(CC) $(CFLAGS) $(INCLUDE) -c $^
19 
20 all:$(OBJS) $(LIB)
21    cd ./dynamiclib && make all
22    $(CC) $(CFLAGS) $(INCLUDE) -o $(TARGET) $(OBJS) $(LIBPATH) $(LIBVAR)
23        ,      ,    libmytest.so    
24 clean:
25    rm -f *.o
26    rm -f comm/inc/*.gch
27    rm -f $(TARGET)
28    cd ./dynamiclib && make clean

    このようにコンパイルされたダイナミックライブラリファイルには、/etc/ld.so.com nf.d/ディレクトリにlibmystest.soライブラリファイルのパス説明を追加する必要があります.
    すなわち、/etc/ld.so.com nf.d/ディレクトリに、プロファイルmystes.com nfを新規作成し、かつ、ldconfig、/etc/ld.so.com nf.d/mystest.com nfの文を実行する.
    この内容はlibmystest.soライブラリファイルの絶対パスです.例えば:
1 /home/lijiangtao/dynamiclib/libs
    アプリケーションをコンパイルするときにダイナミックライブラリファイルの関数を読み込まずに、アプリケーション実行時に変更します.
    libmystest.so里関数をプログラム実行中にロードすると、/etc/ld.so.co.com f.d/ディレクトリにlibmystest.soを配置しなくてもいいです.
    経路は、以下の通りである.
3.アプリケーション実行時にダイナミックライブラリを読み込みます.
    dynamiclibapp.cファイルの内容は以下の通りです.
 1 #include "apue.h"
 2 #include "dynamiclibs.h"
 3 #include 
 4 
 5 typedef int (*fp_lib_add)(int, int);
 6 typedef int (*fp_lib_mul)(int, int);
 7 typedef void* dlhandle;
 8 
 9 dlhandle      dll      = NULL;
10 fp_lib_add    func_add = NULL;
11 fp_lib_mul    func_mul = NULL;
12 
13 dlhandle load_dynamic_func(char *psopath, fp_lib_add *padd, fp_lib_mul *pmul);
14 
15 int main(int argc, char *argv[])
16 {
17     char *pso = "/home/lijiangtao/dynamiclib/libs/libmytest.so";//   .so   
18     dll = load_dynamic_func(pso, &func_add, &func_mul);//     ,      
19     err_msg("step in main
"); 20 func_add(1, 9);// add 21 func_mul(1, 9);// mul 22 err_msg("step out main
"); 23 24 return 0; 25 } 26 27 dlhandle load_dynamic_func(char *psopath, fp_lib_add *padd, fp_lib_mul *pmul) 28 { 29 if(NULL == psopath ||'\0' == psopath[0]) 30 return NULL; 31 char *perrormsg = NULL; 32 dlhandle dllhandle = dlopen(psopath, RTLD_LAZY); 33 if(NULL == dllhandle) 34 { 35 printf("%s
", dlerror()); 36 return NULL; 37 } 38 if(NULL != padd) 39 { 40 *padd = dlsym(dllhandle, "dynamic_lib_func_add");// add 41 perrormsg = dlerror(); 42 if(NULL != perrormsg) 43 printf("%s
", perrormsg); 44 } 45 if(NULL != pmul) 46 { 47 *pmul = dlsym(dllhandle, "dynamic_lib_func_mul");// mul 48 perrormsg = dlerror(); 49 if(NULL != perrormsg) 50 printf("%s
", perrormsg); 51 } 52 return dllhandle; 53 }

    Makefileファイルの内容は以下の通りです.
 1 CC       = gcc 
 2 CFLAGS   = -Wall -O -g
 3 CXXFLAGS = 
 4 INCLUDE  = -I ./comm/inc -I ./dynamiclib/inc
 5 TARGET   = dynamiclibapp
 6 LIBVAR   = -ldl         libdl.so  
 7 LIBPATH  = 
 8 #search paths for errorhandler.c
 9 vpath %.c ./comm
10 #        apue.h    ,   [errorhandler.o:errorhandler.c apue.h]    apue.h
11 vpath %.h ./comm/inc
12 
13 OBJS     = errorhandler.o dynamiclibapp.o
14 #    apue.h,       
15 errorhandler.o:errorhandler.c apue.h
16    $(CC) $(CFLAGS) $(INCLUDE) -c $^
17 dynamiclibapp.o:dynamiclibapp.c apue.h
18    $(CC) $(CFLAGS) $(INCLUDE) -c $^
19 
20 all:$(OBJS) $(LIB)
21    cd ./dynamiclib && make all
22    $(CC) $(CFLAGS) -rdynamic $(INCLUDE) -o $(TARGET) $(OBJS) $(LIBPATH) $(LIBVAR)
23       ,                ,             ;   -rdynamic   ,
      dlopen
24 clean: 25 rm -f *.o 26 rm -f $(TARGET) 27 cd ./dynamiclib && make clean

    このようにコンパイルされたダイナミックライブラリファイルについては、/etc/ld.so.com nf.d/ディレクトリにlibmystest.soライブラリファイルを配置する経路説明は不要です.