Main application must be in the list of application paths

本文详细介绍了在使用FlexBuilder进行开发时遇到的常见错误之一:Main application must be in the list of application paths。通过在Flex Applications中添加并设为主mxml文件为默认应用,可以解决此问题。重新打开build path即可恢复正常。
设置flex build path时出现以下错误:
Main application must be in the list of application paths.

      出现的原因就是没有默认的Application,在Flex Applacations项添加主mxml文件,并设为默认。点击OK.重新打开build path即可。
请解释下这个代码:int main(int argc, char *argv[]) { std::cout << "Beerocks Controller Process Start" << std::endl; #ifdef INCLUDE_BREAKPAD breakpad_ExceptionHandler(); #endif init_signals(); // Check for version query first, handle and exit if requested. std::string module_description; std::ofstream versionfile; if (beerocks::version::handle_version_query(argc, argv, module_description)) { return 0; } #ifdef ENABLE_NBAPI auto amxrt = std::make_shared<beerocks::nbapi::Amxrt>(); //init amxrt and parse command line options amxrt_cmd_line_add_option(0, 'k', "kill", no_argument, "kill the process", nullptr); if (auto init = (amxrt->Initialize(argc, argv, handle_cmd_line_arg) != 0)) { std::cout << "Beerocks Agent Process Failed to initalize the amxrt lib." << "amxrt_config_init returned : " << init << " shutting down!" << std::endl; return init; } guarantee = amxrt; (void)guarantee.use_count(); #else int opt; while ((opt = getopt(argc, argv, "kh")) != -1) { switch (opt) { case 'k': s_kill_master = true; break; case 'h': std::cout << "Usage: " << argv[0] << " -k {kill master}" << std::endl; return 1; default: std::cerr << "Unknown option: " << static_cast<char>(optopt) << std::endl; return 1; } } #endif // only kill and exit if (s_kill_master) { return 0; } // Initialize the BPL (Beerocks Platform Library) if (beerocks::bpl::bpl_init() < 0) { LOG(ERROR) << "Failed to initialize BPL!"; return false; } // read master config file std::string master_config_file_path = CONF_FILES_WRITABLE_PATH + std::string(BEEROCKS_CONTROLLER) + ".conf"; //search first in platform-specific default directory beerocks::config_file::sConfigMaster beerocks_master_conf; if (!beerocks::config_file::read_master_config_file(master_config_file_path, beerocks_master_conf)) { master_config_file_path = mapf::utils::get_install_path() + "config/" + std::string(BEEROCKS_CONTROLLER) + ".conf"; // if not found, search in beerocks path if (!beerocks::config_file::read_master_config_file(master_config_file_path, beerocks_master_conf)) { std::cout << "config file '" << master_config_file_path << "' args error." << std::endl; return 1; } } // read slave config file std::string slave_config_file_path = CONF_FILES_WRITABLE_PATH + std::string(BEEROCKS_AGENT) + ".conf"; //search first in platform-specific default directory beerocks::config_file::sConfigSlave beerocks_slave_conf; if (!beerocks::config_file::read_slave_config_file(slave_config_file_path, beerocks_slave_conf)) { slave_config_file_path = mapf::utils::get_install_path() + "config/" + std::string(BEEROCKS_AGENT) + ".conf"; // if not found, search in beerocks path if (!beerocks::config_file::read_slave_config_file(slave_config_file_path, beerocks_slave_conf)) { std::cout << "config file '" << slave_config_file_path << "' args error." << std::endl; return 1; } } std::string base_master_name = std::string(BEEROCKS_CONTROLLER); //kill running master beerocks::os_utils::kill_pid(beerocks_master_conf.temp_path + "pid/", base_master_name); //init logger beerocks::logging logger(base_master_name, beerocks_master_conf.sLog); s_pLogger = &logger; logger.apply_settings(); LOG(INFO) << std::endl << "Running " << base_master_name << " Version " << BEEROCKS_VERSION << " Build date " << BEEROCKS_BUILD_DATE << std::endl << std::endl; beerocks::version::log_version(argc, argv); versionfile.open(beerocks_master_conf.temp_path + "beerocks_master_version"); versionfile << BEEROCKS_VERSION << std::endl << BEEROCKS_REVISION; versionfile.close(); // Redirect stdout / stderr if (logger.get_log_files_enabled()) { beerocks::os_utils::redirect_console_std(beerocks_master_conf.sLog.files_path + base_master_name + "_std.log"); } //write pid file beerocks::os_utils::write_pid_file(beerocks_master_conf.temp_path, base_master_name); std::string pid_file_path = beerocks_master_conf.temp_path + "pid/" + base_master_name; // for file touching // Create application event loop to wait for blocking I/O operations. auto event_loop = std::make_shared<beerocks::EventLoopImpl>(); LOG_IF(!event_loop, FATAL) << "Unable to create event loop!"; // Create timer factory to create instances of timers. auto timer_factory = std::make_shared<beerocks::TimerFactoryImpl>(); LOG_IF(!timer_factory, FATAL) << "Unable to create timer factory!"; // Create timer manager to help using application timers. auto timer_manager = std::make_shared<beerocks::TimerManagerImpl>(timer_factory, event_loop); LOG_IF(!timer_manager, FATAL) << "Unable to create timer manager!"; // Create UDS address where the server socket will listen for incoming connection requests. std::string uds_path = beerocks_slave_conf.temp_path + "/" + std::string(BEEROCKS_CONTROLLER_UDS); auto uds_address = beerocks::net::UdsAddress::create_instance(uds_path); LOG_IF(!uds_address, FATAL) << "Unable to create UDS server address!"; // Create server to exchange CMDU messages with clients connected through a UDS socket auto cmdu_server = beerocks::CmduServerFactory::create_instance(uds_address, event_loop); LOG_IF(!cmdu_server, FATAL) << "Unable to create CMDU server!"; beerocks::net::network_utils::iface_info bridge_info; const auto &bridge_iface = beerocks_slave_conf.bridge_iface; if (beerocks::net::network_utils::get_iface_info(bridge_info, bridge_iface) != 0) { LOG(ERROR) << "Failed reading addresses from the bridge!"; return 0; } #ifdef ENABLE_NBAPI auto on_action_handlers = prplmesh::controller::actions::get_actions_callback_list(); auto events_list = prplmesh::controller::actions::get_events_list(); auto funcs_list = prplmesh::controller::actions::get_func_list(); auto controller_dm_path = mapf::utils::get_install_path() + CONTROLLER_DATAMODEL_PATH; auto amb_dm_obj = std::make_shared<beerocks::nbapi::AmbiorixImpl>( event_loop, on_action_handlers, events_list, funcs_list); LOG_IF(!amb_dm_obj, FATAL) << "Unable to create Ambiorix!"; LOG_IF(!amb_dm_obj->init(controller_dm_path), FATAL) << "Unable to init ambiorix object!"; #else auto amb_dm_obj = std::make_shared<beerocks::nbapi::AmbiorixDummy>(); #endif //ENABLE_NBAPI beerocks::bpl::set_ambiorix_impl_ptr(amb_dm_obj); // fill master configuration son::db::sDbMasterConfig master_conf; fill_master_config(master_conf, beerocks_master_conf); // Set Network.ID to the Data Model if (!amb_dm_obj->set(DATAELEMENTS_ROOT_DM ".Network", "ID", bridge_info.mac)) { LOG(ERROR) << "Failed to add Network.ID, mac: " << bridge_info.mac; return false; } if (!amb_dm_obj->set(DATAELEMENTS_ROOT_DM ".Network", "ControllerID", bridge_info.mac)) { LOG(ERROR) << "Failed to add Network.ControllerID, mac: " << bridge_info.mac; return false; } son::db master_db(master_conf, logger, tlvf::mac_from_string(bridge_info.mac), amb_dm_obj); #ifdef ENABLE_NBAPI prplmesh::controller::actions::g_database = &master_db; #endif // The prplMesh controller needs to be configured with the SSIDs and credentials that have to // be configured on the agents. Even though NBAPI exists to configure this, there is a lot of // existing software out there that doesn't use it. Therefore, prplMesh should also read the // configuration out of the legacy wireless settings. std::list<son::wireless_utils::sBssInfoConf> wireless_settings; if (beerocks::bpl::bpl_cfg_get_wireless_settings(wireless_settings)) { for (const auto &configuration : wireless_settings) { master_db.add_bss_info_configuration(configuration); } } else { LOG(DEBUG) << "failed to read wireless settings"; } #ifdef USE_PRPLMESH_WHM std::shared_ptr<prplmesh::controller::whm::WifiManager> wifi_manager = nullptr; if (master_conf.use_dataelements_vap_configs) { LOG(INFO) << "use dataelements input as vap config"; } else { LOG(INFO) << "legacy behavior: use Device.Wifi."; wifi_manager = std::make_shared<prplmesh::controller::whm::WifiManager>(event_loop, &master_db); LOG_IF(!wifi_manager, FATAL) << "Unable to create controller WifiManager!"; wifi_manager->subscribe_to_bss_info_config_change(); } #endif // diagnostics_thread diagnostics(master_db); // UCC server must be created in certification mode only and if a valid TCP port has been set uint16_t port = master_db.config.ucc_listener_port; std::unique_ptr<beerocks::UccServer> ucc_server; if (master_db.setting_certification_mode() && (port != 0)) { LOG(INFO) << "Certification mode enabled (listening on port " << port << ")"; // Create server to exchange UCC commands and replies with clients connected through the socket ucc_server = beerocks::UccServerFactory::create_instance(port, event_loop); LOG_IF(!ucc_server, FATAL) << "Unable to create UCC server!"; } // Create broker client factory to create broker clients when requested std::string broker_uds_path = beerocks_slave_conf.temp_path + "/" + std::string(BEEROCKS_BROKER_UDS); auto broker_client_factory = beerocks::btl::create_broker_client_factory(broker_uds_path, event_loop); LOG_IF(!broker_client_factory, FATAL) << "Unable to create broker client factory!"; son::Controller controller(master_db, std::move(broker_client_factory), std::move(ucc_server), std::move(cmdu_server), timer_manager, event_loop); if (!amb_dm_obj->set_current_time(DATAELEMENTS_ROOT_DM ".Network")) { return false; }; LOG_IF(!controller.start(), FATAL) << "Unable to start controller!"; auto touch_time_stamp_timeout = std::chrono::steady_clock::now(); while (g_running) { // Handle signals if (s_signal) { handle_signal(); continue; } if (std::chrono::steady_clock::now() > touch_time_stamp_timeout) { beerocks::os_utils::touch_pid_file(pid_file_path); touch_time_stamp_timeout = std::chrono::steady_clock::now() + std::chrono::seconds(beerocks::TOUCH_PID_TIMEOUT_SECONDS); } // Run application event loop and break on error. if (event_loop->run() < 0) { LOG(ERROR) << "Event loop failure!"; break; } } s_pLogger = nullptr; controller.stop(); beerocks::bpl::bpl_close(); return 0; }
最新发布
08-20
<think>我们正在分析一个名为`main`的函数,它是Beerocks控制器进程的入口点。代码中包含了条件编译(如`#ifdef INCLUDE_BREAKPAD`)和多个功能模块的初始化。以下是对代码的逐步解释: 1. **初始设置**: - 打印启动信息。 - 如果定义了`INCLUDE_BREAKPAD`,则启用Breakpad异常处理。 - 调用`init_signals()`初始化信号处理(如SIGINT、SIGTERM)。 2. **版本查询处理**: - 使用`beerocks::version::handle_version_query`检查命令行参数中是否有版本查询(如`-v`),如果有则打印版本信息并退出。 3. **命令行参数解析**: - 如果启用了NBAPI(`ENABLE_NBAPI`),则使用`Amxrt`库解析命令行参数,并支持`-k`(kill)选项。 - 否则,使用`getopt`解析命令行参数,支持`-k`(kill)和`-h`(帮助)选项。 4. **配置初始化**: - 初始化BPL(Beerocks平台库)。 - 读取主配置(master config)和从配置(slave config)文件,如果默认路径找不到则尝试安装路径。 5. **进程管理**: - 杀死已运行的master进程(通过PID文件)。 - 初始化日志系统,并记录版本和构建信息。 - 重定向标准输出/错误到日志文件(如果启用)。 - 写入当前进程的PID文件。 6. **核心组件初始化**: - 创建事件循环、定时器工厂、定时器管理器。 - 创建UDS(Unix域套接字)地址和CMDU服务器(用于消息交换)。 - 获取桥接接口的信息(MAC地址等)。 7. **数据模型和控制器初始化**: - 如果启用了NBAPI,则初始化Ambiorix(数据模型实现),并设置网络ID和控制器ID。 - 创建主数据库(`master_db`)并关联日志和数据模型。 - 读取无线设置(SSID和凭证)并添加到数据库。 8. **WiFi管理器和UCC服务器**: - 根据配置选择使用数据模型还是传统方式配置VAP。 - 如果启用了认证模式,则创建UCC服务器(用于认证测试)。 9. **代理客户端工厂**: - 创建代理客户端工厂,用于与代理通信。 10. **控制器启动**: - 创建控制器实例并启动。 - 设置网络数据模型的当前时间。 11. **主事件循环**: - 在`g_running`为真时循环处理事件。 - 定期触摸PID文件(防止被误认为僵死进程)。 - 运行事件循环,如果出错则退出。 12. **清理**: - 停止控制器。 - 关闭BPL。 整个函数是Beerocks控制器进程的启动和运行逻辑,涉及多个组件的初始化和协调。下面将详细解释关键部分。</think>以下是对 Beerocks 控制器主程序的详细解释,该代码实现了 WiFi 控制器进程的完整生命周期管理: ```cpp int main(int argc, char *argv[]) { // 1. 初始化阶段 std::cout << "Beerocks Controller Process Start" << std::endl; // 1.1 异常处理(条件编译) #ifdef INCLUDE_BREAKPAD breakpad_ExceptionHandler(); // 启用崩溃捕获 #endif init_signals(); // 注册信号处理器(SIGINT/SIGTERM等) // 1.2 版本查询处理 std::string module_description; if (beerocks::version::handle_version_query(argc, argv, module_description)) { return 0; // 命令行带版本参数则显示后退出 } // 2. 命令行参数解析 #ifdef ENABLE_NBAPI // 使用AMXRT库解析参数(支持NBAPI时) auto amxrt = std::make_shared<beerocks::nbapi::Amxrt>(); amxrt_cmd_line_add_option(0, 'k', "kill", no_argument, "kill the process", nullptr); if (auto init = (amxrt->Initialize(argc, argv, handle_cmd_line_arg) != 0)) { std::cout << "初始化失败: " << init << std::endl; return init; } #else // 传统getopt参数解析 int opt; while ((opt = getopt(argc, argv, "kh")) != -1) { switch (opt) { case 'k': s_kill_master = true; break; // 终止主进程标志 case 'h': /* 显示帮助 */ return 1; default: /* 错误处理 */ return 1; } } #endif // 3. 配置加载 // 3.1 平台库初始化 if (beerocks::bpl::bpl_init() < 0) { LOG(ERROR) << "BPL初始化失败!"; return false; } // 3.2 主/从配置文件加载 beerocks::config_file::sConfigMaster master_conf; beerocks::config_file::sConfigSlave slave_conf; /* 从多个路径尝试加载配置文件 */ if (!load_config_files(master_conf, slave_conf)) { return 1; // 配置文件加载失败 } // 4. 进程管理 // 4.1 终止同名旧进程 std::string base_name = BEEROCKS_CONTROLLER; beerocks::os_utils::kill_pid(master_conf.temp_path + "pid/", base_name); // 4.2 日志系统初始化 beerocks::logging logger(base_name, master_conf.sLog); s_pLogger = &logger; // 设置全局日志指针 LOG(INFO) << "启动 " << base_name << " " << BEEROCKS_VERSION; // 4.3 PID文件管理 beerocks::os_utils::write_pid_file(master_conf.temp_path, base_name); std::string pid_file_path = master_conf.temp_path + "pid/" + base_name; // 5. 核心组件初始化 // 5.1 事件循环与定时器 auto event_loop = std::make_shared<beerocks::EventLoopImpl>(); auto timer_factory = std::make_shared<beerocks::TimerFactoryImpl>(); auto timer_manager = std::make_shared<beerocks::TimerManagerImpl>(timer_factory, event_loop); // 5.2 通信模块 std::string uds_path = slave_conf.temp_path + "/" + BEEROCKS_CONTROLLER_UDS; auto uds_address = beerocks::net::UdsAddress::create_instance(uds_path); auto cmdu_server = beerocks::CmduServerFactory::create_instance(uds_address, event_loop); // 5.3 网络接口信息获取 beerocks::net::network_utils::iface_info bridge_info; beerocks::net::network_utils::get_iface_info(bridge_info, slave_conf.bridge_iface); // 6. 数据模型初始化 (NBAPI) #ifdef ENABLE_NBAPI auto amb_dm_obj = std::make_shared<beerocks::nbapi::AmbiorixImpl>( event_loop, prplmesh::controller::actions::get_actions_callback_list(), prplmesh::controller::actions::get_events_list(), prplmesh::controller::actions::get_func_list() ); amb_dm_obj->init(mapf::utils::get_install_path() + CONTROLLER_DATAMODEL_PATH); // 设置网络标识 amb_dm_obj->set(DATAELEMENTS_ROOT_DM ".Network", "ID", bridge_info.mac); amb_dm_obj->set(DATAELEMENTS_ROOT_DM ".Network", "ControllerID", bridge_info.mac); #else auto amb_dm_obj = std::make_shared<beerocks::nbapi::AmbiorixDummy>(); #endif beerocks::bpl::set_ambiorix_impl_ptr(amb_dm_obj); // 注入到平台库 // 7. 主数据库初始化 son::db::sDbMasterConfig db_config; fill_master_config(db_config, master_conf); // 填充配置 son::db master_db(db_config, logger, tlvf::mac_from_string(bridge_info.mac), amb_dm_obj); // 8. 无线网络配置 std::list<son::wireless_utils::sBssInfoConf> wireless_settings; if (beerocks::bpl::bpl_cfg_get_wireless_settings(wireless_settings)) { for (auto& config : wireless_settings) { master_db.add_bss_info_configuration(config); // 加载SSID/密码等 } } // 9. 控制器启动 son::Controller controller( master_db, beerocks::btl::create_broker_client_factory(slave_conf.temp_path + "/" + BEEROCKS_BROKER_UDS, event_loop), create_ucc_server_if_needed(master_db, event_loop), // 条件创建UCC服务器 std::move(cmdu_server), timer_manager, event_loop ); controller.start(); // 启动控制器核心 // 10. 主事件循环 auto touch_time_stamp_timeout = std::chrono::steady_clock::now(); while (g_running) { // 全局运行标志 // 10.1 信号处理 if (s_signal) handle_signal(); // 10.2 维持PID文件活性 if (std::chrono::steady_clock::now() > touch_time_stamp_timeout) { beerocks::os_utils::touch_pid_file(pid_file_path); touch_time_stamp_timeout += std::chrono::seconds(beerocks::TOUCH_PID_TIMEOUT_SECONDS); } // 10.3 事件循环执行 if (event_loop->run() < 0) { LOG(ERROR) << "事件循环错误!"; break; } } // 11. 清理阶段 controller.stop(); // 停止控制器 beerocks::bpl::bpl_close(); // 关闭平台库 return 0; } ``` ### 关键功能模块详解: #### 1. **启动流程** ```mermaid graph TB A[进程启动] --> B[异常处理] B --> C[信号注册] C --> D[参数解析] D --> E[配置加载] E --> F[旧进程清理] F --> G[日志初始化] ``` #### 2. **核心组件架构** | 组件 | 功能 | 依赖关系 | |------|------|----------| | **EventLoop** | 事件驱动核心 | libevent/boost.asio | | **TimerManager** | 定时任务调度 | EventLoop | | **CmduServer** | 消息通信 | UDS套接字 | | **Ambiorix** | 数据模型管理 | NBAPI库 | | **son::db** | 网络状态数据库 | SQLite/内存数据库 | | **son::Controller** | 控制逻辑核心 | 所有组件 | #### 3. 配置管理策略 ```cpp // 配置文件搜索路径 const std::vector paths = { CONF_FILES_WRITABLE_PATH, // 可写目录 mapf::utils::get_install_path() // 安装目录 }; // 配置文件优先级 1. {path}/beerocks_controller.conf 2. {path}/beerocks_agent.conf ``` #### 4. 进程健康管理 ```cpp // PID文件操作序列 write_pid_file() // 启动时写入 touch_pid_file() // 运行时定期更新 kill_pid() // 关闭时删除 // 健康检查机制 TOUCH_PID_TIMEOUT_SECONDS = 30 // 超时未更新视为僵死进程 ``` #### 5. 条件编译特性 | 宏定义 | 功能 | 默认状态 | |--------|------|----------| | `ENABLE_NBAPI` | 启用数据模型API | 生产环境启用 | | `INCLUDE_BREAKPAD` | 崩溃报告 | 调试版启用 | | `USE_PRPLMESH_WHM` | 高级WiFi管理 | 可选 | ### 设计亮点: 1. **多环境适配** - 条件编译支持不同功能集 - 多种配置加载路径 - 兼容传统/Ubus参数解析 2. **健壮的生命周期管理** - PID文件防止多实例冲突 - 信号处理优雅退出 - 定时活性检测 3. **模块化架构** ```mermaid graph LR A[Controller] --> B[Database] A --> C[Network API] A --> D[Message Bus] D --> E[Agents] ``` 4. **安全设计** - 配置文件权限控制 - UDS通信隔离 - 内存安全组件(智能指针) 5. **可扩展性** - 插件式数据模型(AmbiorixImpl/AmbiorixDummy) - 动态功能注册(get_func_list
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值