踩坑!openharmony L1级动态库编译使用 原创 精华

挖墙脚的农民工
发布于 2022-2-11 14:48
浏览
6收藏

春节不停更,此文正在参加「星光计划-春节更帖活动」@[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来指定对应的依赖。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-2-11 16:17:47修改
8
收藏 6
回复
举报
2条回复
按时间正序
/
按时间倒序
mb609898e2cfb86
mb609898e2cfb86

感谢排坑

1
回复
2022-2-11 16:18:32
民之码农
民之码农

666

回复
2022-2-15 08:17:27
回复
    相关推荐