踩坑!openharmony L1级动态库编译使用 原创 精华
春节不停更,此文正在参加「星光计划-春节更帖活动」@[toc]( openharmony动态库编译使用
背景
linux系统存在大量使用静态库和动态库的情况,由于开发的需要,需要提供动态库进行二次开发和自动化测试,因此着手进行了鸿蒙相关动态使用的学习与研究。本次测试主要使用动态库,如果有感兴趣的可以尝试在此基础上编译静态库。
问题
动态的编译生成可以通过c或者c++ 语言编写编译而成。一般的linux 操作系统可以完成C 调用C++ 编译动态库,或者反正,C++ 调用C编译而成的动态库。由于开发的需要,基于C和C++ 混编时出现编译失败情况,具体详情体通过以下流程讲述。
环境
本次编译动态库为君正x2000环境,开发板:君正x2000
动态库编译
目录如下:
lts@ubuntu:~/test$ du -a
4 ./include/helloworld.h
8 ./include
4 ./BUILD.gn
4 ./src/helloworld.cpp
8 ./src
24 .
lts@ubuntu:~/test$ ls -arthl
total 20K
drwxrwxr-x 4 lts lts 4.0K Feb 10 18:31 ..
-rwxrwxr-x 1 lts lts 399 Feb 10 18:32 BUILD.gn
drwxrwxr-x 2 lts lts 4.0K Feb 10 19:44 src
drwxrwxr-x 2 lts lts 4.0K Feb 10 19:44 include
drwxrwxr-x 4 lts lts 4.0K Feb 10 22:17 .
lts@ubuntu:~/test$
helloworld.cpp 文件类容:
lts@ubuntu:~/test$ cat helloworld.cpp
#include "helloworld.h"
#include <stdio.h>
void helloworldtest(void)
{
printf("[demo] hello world 1111\n");
}
lts@ubuntu:~/test$
helloworld.h 头文件内容
lts@ubuntu:~/test$ cat include/helloworld.h
#ifndef HELLO_WORLD_H
#define HELLO_WORLD_H
#ifdef __cplusplus
extern "C" {
#endif
void helloworldtest(void);
#ifdef __cplusplus
}
#endif
#endif
lts@ubuntu:~/test$
BUILD.gn 文件内容
lts@ubuntu:~/test$ cat BUILD.gn
import("//build/lite/config/component/lite_component.gni")
shared_library("helloworld_client") {
print("ddddddddddddddddddddddddddddddddddddddddddddddddddddd")
sources = [
"./src/helloworld.cpp"
]
include_dirs = [
"./include",
]
deps = []
ldflags = [ "-lstdc++" ]
cflags = [
"-fPIC",
"-Wall",
"-Wno-format",
]
cflags_cc = cflags
}
lts@ubuntu:~/test$
注意:BUILD.gn文件中我们可以通过 print 函数来检验是否编译当前代码。
通过嵌入到对应的项目中,通过编译可以获得到我们所需的so文件。当前版使用C调用C++ 编译而成的动态库,当然使用C调用C++库时需要使用转换,否则出现编译出现下面问题。本次编译出现下面问题,主要是缺少#ifdef __cplusplus 对头文件内容进行转换,
lts@ubuntu:~/test/lib/test2$ ./complie.sh
/usr/bin/ld: /tmp/cc9ITJH6.o: in function `main':
test.c:(.text+0x14): undefined reference to `helloworldtest'
collect2: error: ld returned 1 exit status
lts@ubuntu:~/test/lib/test2$
可执行文件调用动态库
目录结构如下:
lts@ubuntu:~/test2$ ls
BUILD.gn src
lts@ubuntu:~/test2$
源码文件内容如下:
lts@ubuntu:~/test/lib/test2$ cat src/test.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "helloworld.h"
int main(int argc,char** argv[])
{
helloworldtest();
return 0;
}
lts@ubuntu:~/test/lib/test2$
BUILD.gn 文件内容:
lts@ubuntu:~/x2000/talkweb/sysinfo/test2$ cat BUILD.gn
import("//build/lite/config/component/lite_component.gni")
executable("helloworld_test") {
print("ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc")
sources = [
"./src/test.c"
]
include_dirs = [
".",
"./../test/include",
]
deps = [
"//abc/test:helloworld_client"
]
ldflags = [ "-lstdc++" ]
cflags = [
"-fPIC",
"-Wall",
"-Wno-format",
]
cflags_cc = cflags
}
lts@ubuntu:~/x2000/talkweb/sysinfo/test2$
注意:由于当前编译是调用动态库,需要在 deps 处指定编译依赖库,即前面编译好的动态库。否则出现编译失败情况
[OHOS ERROR] FAILED: bin/helloworld_test unstripped/bin/helloworld_test
[OHOS ERROR] ccache /home/lts/x2000/device/ingenic/x2000/prebuilt/gcc/linux-x86/mips/mips-gcc720-glibc229/bin/mips-linux-gnu-gcc -lstdc++ -Wl,-rpath-link=/home/lts/x2000/out/x2000/halley5_spi_nand_flash/libs/lib,-rpath-link=/home/lts/x2000/out/x2000/halley5_spi_nand_flash,-rpath-link=/home/lts/x2000/out/x2000/halley5_spi_nand_flash/buildroot-intermediate/target/usr/lib -latomic -lpthread -ldl -lrt -mips32r2 -mfp64 -fpic -D_GNU_SOURCE -march=mips32r2 -L. -Wl,-z,now -Wl,-z,relro -Wl,-z,noexecstack -pie -Wl,--start-group obj/talkweb/sysinfo/test2/src/helloworld_test.test.o -Wl,--end-group -o ./unstripped/bin/helloworld_test && ccache /home/lts/x2000/device/ingenic/x2000/prebuilt/gcc/linux-x86/mips/mips-gcc720-glibc229/bin/mips-linux-gnu-strip --strip-unneeded "./unstripped/bin/helloworld_test" -o "./bin/helloworld_test"
[OHOS ERROR] obj/talkweb/sysinfo/test2/src/helloworld_test.test.o: In function `main':
[OHOS ERROR] test.c:(.text.startup+0x24): undefined reference to `helloworldtest'
[OHOS ERROR] test.c:(.text.startup+0x2c): undefined reference to `helloworldtest'
[OHOS ERROR] collect2: error: ld returned 1 exit status
[OHOS ERROR] you can check build log in /home/lts/x2000/out/x2000/halley5_spi_nand_flash/build.log
[OHOS ERROR] command: "/home/lts/x2000/prebuilts/build-tools/linux-x86/bin/ninja -w dupbuild=warn -C /home/lts/x2000/out/x2000/halley5_spi_nand_flash" failed
[OHOS ERROR] return code: 1
[OHOS ERROR] execution path: /home/lts/x2000
lts@ubuntu:~/x2000$
运行
编译完成之后我们可以获得对应可执行文件helloworld_test 和动态库 libhelloworld_client.so
将可执行文件和动态库上传到开发板中。动态库放入到/usr/lib 目录下,
运行可执行文件:
/data/talkweb # ./helloworld_test
[demo] hello world 1111
/data/talkweb #
问题总结
第一、c掉C++ 时需要使用#ifdef __cplusplus 当然这里的c++ 没有使用类,
第二、使用deps来指定对应的依赖。
感谢排坑
666