文章目录
- 一、背景
- 二、探索
- 1、BUILD.gn
- 2、usbmgr.gni
- 3、ohos.gni
- 4、cxx.gni
- 5、BUILDCONFIG.gn
- 三、总结
一、背景
- 发现
usb_manager
仓下,usb_service.cpp
文件里面,有些地方使用了make_shared
方法来创建堆内存。并在后面通过判断指针是否为空,来判断内存是否申请成功,如下:
handler_ = std::make_shared<UsbServerEventHandler>(eventRunner_, pms);
if (handler_ == nullptr) {
USB_HILOGE(MODULE_USB_SERVICE, "Init failed due to create handler error");
return false;
}
- 按照我们这篇文章说的 【c/c++】打印uint8_t类型—nothrow—no-exceptions,c++是默认使用异常机制的,所以应该使用
try catch
来判断make_shared
是否成功。 - 但是当我改造成try catch之后,发现报错了:
error: cannot use 'try' with exceptions disabled
try {
^
1 error generated.
- 这个错误似曾相识啊,不就是上一篇文章里面提到的同时使用了
try catch
和no-exceptions
导致的嘛。所以至此我们明白了,编译usb_service.cpp
文件的时候,肯定是禁用了异常机制。ok,下面我们就看一下到底是在哪里加入了no-exceptions
。
二、探索
1、BUILD.gn
- 通常来说
no-exception
这种应该在BUILD.gn
的config
里面设置,我们来看下usb_service.cpp
文件编译的地方:
import("//base/usb/usb_manager/usbmgr.gni")
...
ohos_shared_library("usbservice") {
sources = [
...
"native/src/usb_service.cpp",
...
]
configs = [
"${utils_path}:utils_config",
":usbsrv_private_config",
]
public_configs = [ ":usbsrv_public_config" ]
...
}
- 查看其
config
和public_config
里面都没有no-exception
的配置。
2、usbmgr.gni
- 我们继续向上层找呗,看下
usbmgr.gni
里面,发现也就是几个变量的声明,并无其他:
import("//build/ohos.gni")
usb_manager_path = "//base/usb/usb_manager"
usb_manager_part_name = "usb_manager"
utils_path = "${usb_manager_path}/utils"
3、ohos.gni
- 那就继续向上找,看下
ohos.gni
呗,全都是import
,晕。。。,一个个翻一下,看看里面都做了些啥。
...
import("//build/templates/cxx/cxx.gni")
...
import("//build/templates/common/ohos_templates.gni")
import("//build/templates/cxx/prebuilt.gni")
4、cxx.gni
template("ohos_executable") {
...
template("ohos_shared_library") {
···
template("ohos_static_library") {
...
template("ohos_source_set") {
- 好亲切啊,这里面不就是我们经常用到的一些玩意吗,并且我们的
usb_service.cpp
,就是通过ohos_shared_library
来编译的。好那我们就详细看下这是咋实现的。
template("ohos_shared_library") {
...
if (defined(invoker.use_exceptions) && invoker.use_exceptions) {
configs += [ "//build/config/compiler:exceptions" ]
configs -= [ "//build/config/compiler:no_exceptions" ]
}
...
- 其他的我不关注,我就是要找
no_exceptions
是在哪里被加进去的,configs -= [ "//build/config/compiler:no_exceptions" ]
这一句和我们有关系,但是他是去掉no_exceptions
。 - 并且通过上下文,我们大致能看懂,就是说如果你在用
ohos_shared_library
的时候,config
里面设置了use_exceptions
,那么这里就会把exceptions
加进去,而把no_exceptions
去掉。这样你的代码就能使用异常机制了。 - 那我们直接搜一下
no_exceptions
看看它在哪里用了。
- 发现用它的地方还真不多,除了
cxx.gni
只有BUILDCONFIG.gn
用了。
5、BUILDCONFIG.gn
default_compiler_configs = [
...
"//build/config/compiler:no_exceptions",
...
]
default_shared_library_configs = default_compiler_configs + [
- shared library的默认配置是在,全局默认配置基础上进行了修改而来。
set_defaults("shared_library") {
configs = default_shared_library_configs
}
- 然后通过
set_defaults
方法将默认配置,设置给shared_library
类型的目标。set_defaults
是gn原生的方法。 - ok,至此探索完毕。
三、总结
- 最终我们的结论是ohos_shared_library默认关闭了异常机制no-exceptions。
- 它是通过设置全局的默认编译配置
default_compiler_configs
,然后各种目标类型根据需要,在全局配置基础上,加上各目标类型自己的配置,生成目标类型所需配置,如default_shared_library_configs
。 - 最后在通过
set_defaults
方法将配置设置到对应目标类型中去。