主题 : 应用程序库文件编译和使用问题 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 1870
精华: 0
发帖: 8
金钱: 60 两
威望: 17 点
综合积分: 16 分
注册时间: 2008-10-07
最后登录: 2012-09-20
楼主  发表于: 2011-11-22 22:31

 应用程序库文件编译和使用问题

求帮助!
现在我想写个linux下的应用程序,想将其中公用的一个目录编译成库文件后与主程序连接。
但是一直会提示未定义错误。
我尝试参考书写一个简单的程序,如附件,解压后可直接使用sh make.sh或make编译。

主程序中只要有调用f2()函数程序就会出现f2未定义错误。
而只调用f1()函数则不会出现这种错误,两个函数是非常相似的。
下面是我的整个操作过程,望高手帮忙解决。谢谢!

my@ubuntu:~/test$ cd lib
my@ubuntu:~/test/lib$ ls
f1.c  f1.o  f2.c  f2.o  libexample.a  Makefile
my@ubuntu:~/test/lib$ cat f1.c
#include <stdio.h>

void f1(void)
{
    printf("f1()\n");
}
my@ubuntu:~/test/lib$ cat f2.c
#include <stdio.h>

void f1(void)
{
    printf("f1()\n");
}
my@ubuntu:~/test/lib$ cd ..
my@ubuntu:~/test$ ls
inc  lib  main.c  main.o  Makefile  make.sh
my@ubuntu:~/test$ cat main.c
void f2(void);

int main()
{
    //f1();
    f2();
    return 0;
}
my@ubuntu:~/test$ cd inc
my@ubuntu:~/test/inc$ ls
fx.h
my@ubuntu:~/test/inc$ cat fx.h
#ifndef __FX_H__
#define __FX_H__

extern void f1(void);
extern void f2(void);

#endif
my@ubuntu:~/test/inc$ cd ..
my@ubuntu:~/test$ ls
inc  lib  main.c  main.o  Makefile  make.sh
my@ubuntu:~/test$ cat make.sh
cd lib/
gcc -c *.c
ar cr libexample.a f2.o f1.o
cd ..
gcc -o main main.c lib/libexample.a -I inc/
my@ubuntu:~/test$ sh make.sh
/tmp/ccjicsHw.o: In function 'main':
main.c:(.text+0x7): undefined reference to 'f2'
collect2: ld returned 1 exit status
my@ubuntu:~/test$
描述:代码源文件
附件: test.tar.gz (2 K) 下载次数:2
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2011-11-22 22:58
你整个源代码里面就没有定义f2()这个函数,当然link不到它啊。f2.c里应该改成
复制代码
  1. void f2(void)
  2. {
  3.     printf("f2()\n");
  4. }

吧.
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
2楼  发表于: 2011-11-22 23:13
另外,链接库的写法通常是用gcc的-L和-l参数,而不是直接将库文件作为链接的对象文件放在gcc的命令行上。

diff --git a/make.sh b/make.sh
index b815b74..553686b 100644
--- a/make.sh
+++ b/make.sh
@@ -2,4 +2,4 @@ cd lib/
gcc -c *.c
ar cr libexample.a f2.o f1.o
cd ..
-gcc -o main main.c lib/libexample.a -I inc/
+gcc -o main main.c -L lib -lexample -I inc/

关于库的使用和编译,建议你参考Advanced Linux Programming的2.3节(http://www.advancedlinuxprogramming.com/alp-folder/alp-ch02-writing-good-gnu-linux-software.pdf)
[ 此帖被kasim在2011-11-22 23:24重新编辑 ]
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 1870
精华: 0
发帖: 8
金钱: 60 两
威望: 17 点
综合积分: 16 分
注册时间: 2008-10-07
最后登录: 2012-09-20
3楼  发表于: 2011-11-23 22:35

 回 2楼(kasim) 的帖子

非常感谢,那个f2未定义确实是我的粗心
之前是在公司电脑也写个类似的测试项目,回家又写了个,以为这个错误是同样原因引起的。
其实,我是想测试makefile的错误。
在公司的库文件的makefile中有错误的地方:
%.o:%c
    $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
被我写成了
$(OBJS):$(SOURCES)
       $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

再次谢谢!