关于动态链接库。so 文件的 Makefile 该怎么写

时间:2022-02-01 06:51:49
  如附件图所见~  图传不上来~~我就简化说下
   
  文件夹中有 些 .c和.h 文件 ~~分别是 A.c B.c C.c D.c  相应的的需要用的自定义头文件

  A.h B.h C.h D.h      

  我想把该文件的这些文件合起来编成一个 动态链接库.so 文件

  该如何写 Makefile ~~

  谢谢

18 个解决方案

#1



#
# Simple .so Makefile
#

CC      := gcc
LD      := ld
CFLAGS  :=
LDFLAGS := -shared -fpic
SOURCE  := $(wildcard *.c)
OBJS    := $(patsubst %.c,%.o,$(SOURCE))
TARGET_LIB := x.so

all:$(OBJS)
    echo $(OBJS)
    $(LD) $(LDFLAGS) -o $(TARGET_LIB) $(OBJS) 

%.o:%.c
    @echo Compiling $< ...
    $(CC) -c $(CFLAGS)  $< -o $*.o

.PHONY: clean

clean:
    rm *.so *.o -rf


我写了个简单的,自己更具情况修改! 

GOOD LUCK!

#2


-shared 

#3


.SUFFIXES:.c

HOMEDIR=/code
COMDIR=$(HOMEDIR)/comlib
INCDIR=-I$(COMDIR)/include 
    
CC=gcc
CFLAG=-O -DUNIX -DLIB -DDEBUG -DTRACE_FILE='"./trace"' 
EDF=

help: 
@echo Please input filename that will be made 
@echo 'syntax: make <help|all|"filename">'

all: config debug file msg pid sem shm str tcp time udp

.c:
if [ -f $(COMDIR)/lib/libcom.a ]; then ar -x $(COMDIR)/lib/libcom.a; fi
$(CC) -c $< $(CFLAG) $(INCDIR)
ar -rv libcom.a *.o
rm *.o
mv libcom.a $(COMDIR)/lib



把.c文件和此makefile文件放在一起!

另外把/code/include中  
就 OK!  
最终的 库存放在/code/lib中

#4


3楼的是静态库
1楼的是动态库

#5


我想调用 这 动态库~~里的函数~

怎么编译

#6


和一般程序一样编译
源码里面要include你的需要的头文件,当然了编译时要指定头文件位置

运行时需要指定一定lib的路径,你也可以把你的动态库拷到lib目录下,活正当前路径都可以运行

#7


我想把 这些头文件也编进去~该怎么写

~~

另外我想用动态加载 。so文件~~

编译时语句怎么用?~

直接   

GCC -C TEST.C  -ldl  

这样OK?

#8


// "test.c"

#include <stdio.h>
#include <dlfcn.h>
//#include "types.h"     //这个不加的话会出错  ,uint32 int32 等都是这里定义的
int main(int argc, char* argv[])

        void* pdlhandle;
char* pszerror;
// open rtl8306.so
pdlhandle = dlopen("./rtl8306.so", RTLD_LAZY);
pszerror = dlerror();
if (0 != pszerror) {
printf("%s\n", pszerror);
exit(1);
}
// get  func
   
   int (*switchTest)(void)= dlsym(pdlhandle, "switchTest");
pszerror = dlerror();
if (0 != pszerror) {
printf("%s\n", pszerror);
exit(1);
}

// get smiWrite func
   int32 (*smiWrite)(uint32,uint32,uint32 ) = dlsym(pdlhandle, "smiWrite");
pszerror = dlerror();
if (0 != pszerror) {
printf("%s\n", pszerror);
exit(1);
}
// call fun

printf("Test=%\n", switchTest());
printf("Write=\n", smiWrite(54,54,1111));

// close rtl8306.so
dlclose(pdlhandle);

}


然后我编译时 ~~  gcc -c test.c -ldl 

1.如果没加types.h 
提示 switchTest、switchWrite  undeclared (first use……)

2.加了 types。h

-ldl:linker input file unused beause linking not done

~~~

所以我想把这些。c和。h全部 编成一个.so 文件~~ 而动态.so文件时 不需要 再另外添加其中的头文件

#9



ot@xiaoke home]# gcc -c test.c -ldl
test.c: In function `main':
test.c:31: `smiWrite' undeclared (first use in this function)
test.c:31: (Each undeclared identifier is reported only once
test.c:31: for each function it appears in.)
test.c:31: `uint32' undeclared (first use in this function)
test.c:31: called object is not a function
test.c:41: `smiWrite' used prior to declaration

#10


mark

#11


无敌Makefile:

EXECUTABLE := test
LIBS :=
 
CFLAGS := -g -Wall
CXXFLAGS := $(CFLAGS)
 
 
ifneq ($(wildcard $(DJDIR)/bin/rm.exe),)
        RM-F := rm -f
EXECUTABLE := test
LIBS :=
 
CFLAGS := -g -Wall
CXXFLAGS := $(CFLAGS)
 
 
ifneq ($(wildcard $(DJDIR)/bin/rm.exe),)
        RM-F := rm -f
else
        RM-F := rm -f
endif
 
# You shouldn't need to change anything below this point.
#
# 从这里开始,你应该不需要改动任何东西。(我是不太相信,太NB了!)
 
SOURCE := $(wildcard *.c) $(wildcard *.cc)
OBJS := $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCE)))
DEPS := $(patsubst %.o,%.d,$(OBJS))
MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS))
MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.c,$(MISSING_DEPS)) \
$(patsubst %.d,%.cc,$(MISSING_DEPS)))
CPPFLAGS += -MD
 
.PHONY : everything deps objs clean veryclean rebuild
 
everything : $(EXECUTABLE)
 
deps : $(DEPS)
 
objs : $(OBJS)
 
clean :
        $(RM-F) *.o
        $(RM-F) *.d
 
veryclean: clean
        $(RM-F) $(EXECUTABLE)
 
rebuild: veryclean everything
 
ifneq ($(MISSING_DEPS),)
$(MISSING_DEPS) :
          $(RM-F) $(patsubst %.d,%.o,$@)
endif
 
-include $(DEPS)
 
$(EXECUTABLE) : $(OBJS)
        gcc -o $(EXECUTABLE) $(OBJS) $(addprefix -l,$(LIBS))

#12


CXX =g++
RM = rm
LIBNAME:=libxxx.so
LIBVERSION:=0.01
HDRNAME:=a.h b.h c.h d.h
TARGETNAME:=a b c d
CNAME:=$(patsubst %,%.c,$(TARGETNAME))
ONAME:=$(patsubst %,%.o,$(TARGETNAME))

all:libxxx
libxxx: $(ONAME)

        $(CXX) -g -shared -Wl,-soname,$(LIBNAME) \
-o $(LIBNAME).$(LIBVERSION) $(ONAME) -lc


%.o: %.c
$(CXX) -fPIC -c -Wall  $(CNAME)

clean:
$(RM) *.o *.so

#13


首先我感觉lz对编译的一些概念还不是很清晰,我来简单说下:

1. 头文件问题
   头文件是否编译进入到你最终的.so或者可执行文件,是看你是否在你的.c 源文件中用 #include "" 包含了头文件。如果需要的头文件没有包含,编译会出错(记住,是编译阶段,而不是链接阶段);
   另外,如果头文件找不到,可以在编译时候用 -I/your_headfile_path/ 来指定你头文件的路径!

2. 关于如何使用动态库
   动态库是在链接的时候链入最终的可执行文件的,用-lname来指定,其中name的是动态库的名字。如: 如果动态库为libxyz.so,那么name就是xyz,需要用-lxyz来链接该动态库。如果找不到该库,可以用 -L/your_lib_path/来指定库所在路径;

     你编译的时候用: gcc -c test.c -ldl;有两个问题:(1) -c选项是编译为目标文件,而不是可执行文件;(2)你的库名字叫做libdl.so? 麼?
     建议修改成如下命令试试: gcc -o test test.c -ldl    (dl为动态库libdl.so)

GOOD LUCK! 去熟悉下GCC和LD吧


#14


8楼~~ 

库文件 ~~rtl8306.so

~~

是不太懂~~ 所以正在学习中

#15


引用 14 楼 xiaoke3344 的回复:
8楼~~

库文件 ~~rtl8306.so

~~

是不太懂~~ 所以正在学习中


最好将库文件编译为lib开头的,比如对你的情况编译为: librtl8306.so,然后就可以用 -lrtl8306 在link的时候使用该库了。

如果你一定要写成rtl8306.so这个形式,也不是不可。那么编译的时候直接用:gcc -o test test.c rtl8306.so

good luck!

#16


fuck ~~~要学的东西还很多~~

#17


3年前的帖子,今天突然看到依然受用,根据1楼的回复我把自己的makefile 整了一下,确实不错,看起来比我自己写的专业多了

#18


我先试试一楼的看看管不管用

#1



#
# Simple .so Makefile
#

CC      := gcc
LD      := ld
CFLAGS  :=
LDFLAGS := -shared -fpic
SOURCE  := $(wildcard *.c)
OBJS    := $(patsubst %.c,%.o,$(SOURCE))
TARGET_LIB := x.so

all:$(OBJS)
    echo $(OBJS)
    $(LD) $(LDFLAGS) -o $(TARGET_LIB) $(OBJS) 

%.o:%.c
    @echo Compiling $< ...
    $(CC) -c $(CFLAGS)  $< -o $*.o

.PHONY: clean

clean:
    rm *.so *.o -rf


我写了个简单的,自己更具情况修改! 

GOOD LUCK!

#2


-shared 

#3


.SUFFIXES:.c

HOMEDIR=/code
COMDIR=$(HOMEDIR)/comlib
INCDIR=-I$(COMDIR)/include 
    
CC=gcc
CFLAG=-O -DUNIX -DLIB -DDEBUG -DTRACE_FILE='"./trace"' 
EDF=

help: 
@echo Please input filename that will be made 
@echo 'syntax: make <help|all|"filename">'

all: config debug file msg pid sem shm str tcp time udp

.c:
if [ -f $(COMDIR)/lib/libcom.a ]; then ar -x $(COMDIR)/lib/libcom.a; fi
$(CC) -c $< $(CFLAG) $(INCDIR)
ar -rv libcom.a *.o
rm *.o
mv libcom.a $(COMDIR)/lib



把.c文件和此makefile文件放在一起!

另外把/code/include中  
就 OK!  
最终的 库存放在/code/lib中

#4


3楼的是静态库
1楼的是动态库

#5


我想调用 这 动态库~~里的函数~

怎么编译

#6


和一般程序一样编译
源码里面要include你的需要的头文件,当然了编译时要指定头文件位置

运行时需要指定一定lib的路径,你也可以把你的动态库拷到lib目录下,活正当前路径都可以运行

#7


我想把 这些头文件也编进去~该怎么写

~~

另外我想用动态加载 。so文件~~

编译时语句怎么用?~

直接   

GCC -C TEST.C  -ldl  

这样OK?

#8


// "test.c"

#include <stdio.h>
#include <dlfcn.h>
//#include "types.h"     //这个不加的话会出错  ,uint32 int32 等都是这里定义的
int main(int argc, char* argv[])

        void* pdlhandle;
char* pszerror;
// open rtl8306.so
pdlhandle = dlopen("./rtl8306.so", RTLD_LAZY);
pszerror = dlerror();
if (0 != pszerror) {
printf("%s\n", pszerror);
exit(1);
}
// get  func
   
   int (*switchTest)(void)= dlsym(pdlhandle, "switchTest");
pszerror = dlerror();
if (0 != pszerror) {
printf("%s\n", pszerror);
exit(1);
}

// get smiWrite func
   int32 (*smiWrite)(uint32,uint32,uint32 ) = dlsym(pdlhandle, "smiWrite");
pszerror = dlerror();
if (0 != pszerror) {
printf("%s\n", pszerror);
exit(1);
}
// call fun

printf("Test=%\n", switchTest());
printf("Write=\n", smiWrite(54,54,1111));

// close rtl8306.so
dlclose(pdlhandle);

}


然后我编译时 ~~  gcc -c test.c -ldl 

1.如果没加types.h 
提示 switchTest、switchWrite  undeclared (first use……)

2.加了 types。h

-ldl:linker input file unused beause linking not done

~~~

所以我想把这些。c和。h全部 编成一个.so 文件~~ 而动态.so文件时 不需要 再另外添加其中的头文件

#9



ot@xiaoke home]# gcc -c test.c -ldl
test.c: In function `main':
test.c:31: `smiWrite' undeclared (first use in this function)
test.c:31: (Each undeclared identifier is reported only once
test.c:31: for each function it appears in.)
test.c:31: `uint32' undeclared (first use in this function)
test.c:31: called object is not a function
test.c:41: `smiWrite' used prior to declaration

#10


mark

#11


无敌Makefile:

EXECUTABLE := test
LIBS :=
 
CFLAGS := -g -Wall
CXXFLAGS := $(CFLAGS)
 
 
ifneq ($(wildcard $(DJDIR)/bin/rm.exe),)
        RM-F := rm -f
EXECUTABLE := test
LIBS :=
 
CFLAGS := -g -Wall
CXXFLAGS := $(CFLAGS)
 
 
ifneq ($(wildcard $(DJDIR)/bin/rm.exe),)
        RM-F := rm -f
else
        RM-F := rm -f
endif
 
# You shouldn't need to change anything below this point.
#
# 从这里开始,你应该不需要改动任何东西。(我是不太相信,太NB了!)
 
SOURCE := $(wildcard *.c) $(wildcard *.cc)
OBJS := $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCE)))
DEPS := $(patsubst %.o,%.d,$(OBJS))
MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS))
MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.c,$(MISSING_DEPS)) \
$(patsubst %.d,%.cc,$(MISSING_DEPS)))
CPPFLAGS += -MD
 
.PHONY : everything deps objs clean veryclean rebuild
 
everything : $(EXECUTABLE)
 
deps : $(DEPS)
 
objs : $(OBJS)
 
clean :
        $(RM-F) *.o
        $(RM-F) *.d
 
veryclean: clean
        $(RM-F) $(EXECUTABLE)
 
rebuild: veryclean everything
 
ifneq ($(MISSING_DEPS),)
$(MISSING_DEPS) :
          $(RM-F) $(patsubst %.d,%.o,$@)
endif
 
-include $(DEPS)
 
$(EXECUTABLE) : $(OBJS)
        gcc -o $(EXECUTABLE) $(OBJS) $(addprefix -l,$(LIBS))

#12


CXX =g++
RM = rm
LIBNAME:=libxxx.so
LIBVERSION:=0.01
HDRNAME:=a.h b.h c.h d.h
TARGETNAME:=a b c d
CNAME:=$(patsubst %,%.c,$(TARGETNAME))
ONAME:=$(patsubst %,%.o,$(TARGETNAME))

all:libxxx
libxxx: $(ONAME)

        $(CXX) -g -shared -Wl,-soname,$(LIBNAME) \
-o $(LIBNAME).$(LIBVERSION) $(ONAME) -lc


%.o: %.c
$(CXX) -fPIC -c -Wall  $(CNAME)

clean:
$(RM) *.o *.so

#13


首先我感觉lz对编译的一些概念还不是很清晰,我来简单说下:

1. 头文件问题
   头文件是否编译进入到你最终的.so或者可执行文件,是看你是否在你的.c 源文件中用 #include "" 包含了头文件。如果需要的头文件没有包含,编译会出错(记住,是编译阶段,而不是链接阶段);
   另外,如果头文件找不到,可以在编译时候用 -I/your_headfile_path/ 来指定你头文件的路径!

2. 关于如何使用动态库
   动态库是在链接的时候链入最终的可执行文件的,用-lname来指定,其中name的是动态库的名字。如: 如果动态库为libxyz.so,那么name就是xyz,需要用-lxyz来链接该动态库。如果找不到该库,可以用 -L/your_lib_path/来指定库所在路径;

     你编译的时候用: gcc -c test.c -ldl;有两个问题:(1) -c选项是编译为目标文件,而不是可执行文件;(2)你的库名字叫做libdl.so? 麼?
     建议修改成如下命令试试: gcc -o test test.c -ldl    (dl为动态库libdl.so)

GOOD LUCK! 去熟悉下GCC和LD吧


#14


8楼~~ 

库文件 ~~rtl8306.so

~~

是不太懂~~ 所以正在学习中

#15


引用 14 楼 xiaoke3344 的回复:
8楼~~

库文件 ~~rtl8306.so

~~

是不太懂~~ 所以正在学习中


最好将库文件编译为lib开头的,比如对你的情况编译为: librtl8306.so,然后就可以用 -lrtl8306 在link的时候使用该库了。

如果你一定要写成rtl8306.so这个形式,也不是不可。那么编译的时候直接用:gcc -o test test.c rtl8306.so

good luck!

#16


fuck ~~~要学的东西还很多~~

#17


3年前的帖子,今天突然看到依然受用,根据1楼的回复我把自己的makefile 整了一下,确实不错,看起来比我自己写的专业多了

#18


我先试试一楼的看看管不管用

#19