linux c shared library 动态链接库 开发 调用 笔记 普通工程 gnu autotools工程 报错undefined reference

普通工程

New Project-> C Project 

 mysharedlibrary

/*
 * libMysharedlibrary.h
 *
 *  Created on: 2023年8月23日
 *      Author: yeqiang
 */

#ifndef LIBMYSHAREDLIBRARY_H_
#define LIBMYSHAREDLIBRARY_H_

extern void mysharedlibraryfunc ();

#endif /* LIBMYSHAREDLIBRARY_H_ */
/*
 * mysharedlibrary.c
 *
 *  Created on: 2023年8月23日
 *      Author: yeqiang
 */

#include <stdio.h>
#include "libMysharedlibrary.h"

void mysharedlibraryfunc (){
	printf("mysharedlibrary func...\n");
}

build

13:33:10 **** Build of configuration Debug for project mysharedlibrary ****
make all 
Building file: ../mysharedlibrary.c
Invoking: GCC C Compiler
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"mysharedlibrary.d" -MT"mysharedlibrary.o" -o "mysharedlibrary.o" "../mysharedlibrary.c"
Finished building: ../mysharedlibrary.c
 
Building target: libmysharedlibrary.so
Invoking: GCC C Linker
gcc -shared -o "libmysharedlibrary.so" ./mysharedlibrary.o   
Finished building target: libmysharedlibrary.so
 

13:33:11 Build Finished. 0 errors, 0 warnings. (took 165ms)

 New Project-> C Project 

 配置include

 配置library

源码

/*
 ============================================================================
 Name        : executableproj.c
 Author      : 
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include "libMysharedlibrary.h"

int main(void) {
	puts("Hello World"); /* prints Hello World */
	mysharedlibraryfunc();
	return EXIT_SUCCESS;
}

build

13:36:50 **** Build of configuration Debug for project executableproj ****
make all 
Building file: ../src/executableproj.c
Invoking: GCC C Compiler
gcc -I/home/yeqiang/eclipse-workspace/mysharedlibrary -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/executableproj.d" -MT"src/executableproj.o" -o "src/executableproj.o" "../src/executableproj.c"
Finished building: ../src/executableproj.c
 
Building target: executableproj
Invoking: GCC C Linker
gcc -L/home/yeqiang/eclipse-workspace/mysharedlibrary/Debug -o "executableproj" ./src/executableproj.o   -lmysharedlibrary
Finished building target: executableproj
 

13:36:50 Build Finished. 0 errors, 0 warnings. (took 166ms)

 执行,报错:cannot open shared object file: No such file or directory

 原因:未配置libmysharedlibrary.so目录到/etc/ld.so.conf

零时定义环境变量LD_LIBRARY_PATH,成功。

 Gnu AutoTools工程

Makefile.am

bin_PROGRAMS=a.out
a_out_SOURCES=test.c

# Linker options for a.out
a_out_LDFLAGS = -L/home/yeqiang/eclipse-workspace/mysharedlibrary/Debug -lmysharedlibrary

# Compiler options for a.out
a_out_CPPFLAGS = -I/home/yeqiang/eclipse-workspace/mysharedlibrary

build 报错 undefined reference to `mysharedlibraryfunc'

13:43:16 **** Build of configuration Build (GNU) for project test ****
make all 
Making all in src
make[1]: 进入目录“/home/yeqiang/eclipse-workspace/test/src”
gcc -DPACKAGE_NAME=\"test\" -DPACKAGE_TARNAME=\"test\" -DPACKAGE_VERSION=\"1.0\" -DPACKAGE_STRING=\"test\ 1.0\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"test\" -DVERSION=\"1.0\" -I.  -I/home/yeqiang/eclipse-workspace/mysharedlibrary   -g -O2 -MT a_out-test.o -MD -MP -MF .deps/a_out-test.Tpo -c -o a_out-test.o `test -f 'test.c' || echo './'`test.c
mv -f .deps/a_out-test.Tpo .deps/a_out-test.Po
gcc  -g -O2 -L/home/yeqiang/eclipse-workspace/mysharedlibrary/Debug -lmysharedlibrary  -o a.out a_out-test.o  
/usr/bin/ld: a_out-test.o: in function `main':
/home/yeqiang/eclipse-workspace/test/src/test.c:17: undefined reference to `mysharedlibraryfunc'
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:353:a.out] 错误 1
make[1]: 离开目录“/home/yeqiang/eclipse-workspace/test/src”
make: *** [Makefile:348:all-recursive] 错误 1
"make all" terminated with exit code 2. Build might be incomplete.

13:43:16 Build Failed. 4 errors, 0 warnings. (took 166ms)

经测试,最基本的动态库链接过程

gcc -I/home/yeqiang/eclipse-workspace/mysharedlibrary  -c -o "executableproj.o" "executableproj.c"
gcc -L/home/yeqiang/eclipse-workspace/mysharedlibrary/Debug -o "executableproj" executableproj.o   -lmysharedlibrary

可成功执行

 经反复测试,发现,手动执行成功操作过程如下

gcc -I/home/yeqiang/eclipse-workspace/mysharedlibrary  -c -o a_out-test.o test.c
gcc -L/home/yeqiang/eclipse-workspace/mysharedlibrary/Debug -o a.out a_out-test.o -lmysharedlibrary

失败过程如下

gcc -I/home/yeqiang/eclipse-workspace/mysharedlibrary  -c -o a_out-test.o test.c
gcc -L/home/yeqiang/eclipse-workspace/mysharedlibrary/Debug -lmysharedlibrary  -o a.out a_out-test.o

即:Gnu Autotools Project链接动态库造成undefined reference to `mysharedlibraryfunc'的根本原因在于-l参数(-lmysharedlibrary)应该排在gcc指令追后,不能在a_out-test.o参数之前!

Makefile.in是自动生成的,每次编译会重新覆盖,无法在此处修改参数位置,gcc bug? 

进一步分析,发现clang 16就没有这个问题,gcc的bug?

 最终解决,采用clang编译

修改src/Makefile.am,定义CC变量,指向clang

bin_PROGRAMS=a.out
a_out_SOURCES=test.c

CC=/usr/local/bin/clang
# Linker options for a.out
AM_LDFLAGS = -L/home/yeqiang/eclipse-workspace/mysharedlibrary/Debug -lmysharedlibrary

# Compiler options for a.out
AM_CPPFLAGS = -I/home/yeqiang/eclipse-workspace/mysharedlibrary

编译

14:53:40 **** Build of configuration Build (GNU) for project test ****
make all 
Making all in src
make[1]: 进入目录“/home/yeqiang/eclipse-workspace/test/src”
/usr/local/bin/clang -DPACKAGE_NAME=\"test\" -DPACKAGE_TARNAME=\"test\" -DPACKAGE_VERSION=\"1.0\" -DPACKAGE_STRING=\"test\ 1.0\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"test\" -DVERSION=\"1.0\" -I.  -I/home/yeqiang/eclipse-workspace/mysharedlibrary   -g -O2 -MT test.o -MD -MP -MF .deps/test.Tpo -c -o test.o test.c
mv -f .deps/test.Tpo .deps/test.Po
/usr/local/bin/clang  -g -O2 -L/home/yeqiang/eclipse-workspace/mysharedlibrary/Debug -lmysharedlibrary  -o a.out test.o  
make[1]: 离开目录“/home/yeqiang/eclipse-workspace/test/src”
make[1]: 进入目录“/home/yeqiang/eclipse-workspace/test”
make[1]: 对“all-am”无需做任何事。
make[1]: 离开目录“/home/yeqiang/eclipse-workspace/test”

14:53:40 Build Finished. 0 errors, 0 warnings. (took 265ms)

运行

猜你喜欢

转载自blog.csdn.net/hknaruto/article/details/132447606