XianyuTech / flutter-boot

A native-flutter-hybrid develop tool helps you add and develop flutter with your existing app
621 stars 68 forks source link

[!] Unable to find a target named `Runner`, did find `FlutterBootTest`. #13

Closed linhanda closed 4 years ago

linhanda commented 4 years ago

按照flutter-boot init之后,link对应的iOS工程,之后在pod install的时候报错

Analyzing dependencies [!] Unable to find a target named Runner, did find FlutterBootTest. (node:22199) UnhandledPromiseRejectionWarning: Error: Command failed: pod install

Jenus commented 4 years ago

存在问题的地方在文件duplicate_target.rb 中, 判断nativeTarget是否依赖subproject的地方, 目前还不得而知为何需要这么判断

具体位置在: if FILE == $0 puts(ARGV[0]) proj = Xcodeproj::Project.open(ARGV[0]) src_target = get_src_target(proj) puts(src_target.name) dependencies_array = get_dependent_targets(proj, src_target.uuid) if !dependencies_array.empty? //这个地方的判断, 创建Runner target(可以不需要增加这个条件?) create_runner_target(proj, src_target, dependencies_array) end puts(src_target.uuid)

Jenus commented 4 years ago

@linhanda

如果手动将自己的iOS工程配置flutter环境, 即混搭环境, 可以参考: flutter官方文档: https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps 我按照官方的文档, 可以构建成功; 如果有何问题, 可以贴出问题继续讨论

Jenus commented 4 years ago

@voicewitness 我个人研究代码发现配置iOS环境主要问题有: 1 就是你发现的这个duplicate_target.rb 最后的依赖判断问题; 2 第二个问题是ios_shell构建目录, 只是第一阶段flutter-boot init执行好后, 可以从flutter视角跑脚手架默认构建的Runner workspace(flutter module目录下的ios_shell目录symlink iOS目录); 但一旦选择了iOS native工程之后, 由于会link 原生的project到flutter module目录下iOS目录, 导致这个ios_shell(可以看到symlink清除掉了)目录目前被弃用. 3 那么一旦link成功, 在native project下面的Podfile文件会在Runner target会增加一行, eval(File.read(File.join(File.dirname(FILE), 'fbpodhelper.rb')), binding) 但目前这个文件来说, 只能读取flutter module的路径信息, 以及 读取 flutter_application_path = File.join(fbFlutterPath, '.ios', 'Flutter') eval(File.read(File.join(flutter_application_path, 'podhelper.rb')), binding) podhelper.rb这个文件只是一些函数定义, 并没有主动调用类似install_all_flutter_pods的调用

以上问题, 导致native的对flutter module作为framework的环境无法建立.以上如果步骤有错误,希望作者提供文档,或者指正, 谢谢.

yinma848 commented 4 years ago

@voicewitness 我个人研究代码发现配置iOS环境主要有: 1 就是你发现的这个duplicate_target.rb 最后的依赖判断问题; 2 第二个问题是ios_shell构建目录, 只是第一阶段flutter-boot init执行好后, 可以从flutter视角跑脚手架默认构建的Runner workspace(flutter module目录下的ios_shell目录symlink iOS目录); 但一旦选择了iOS native工程之后, 由于会link 原生的project到flutter module目录下iOS目录, 导致这个ios_shell(可以看到symlink清除掉了)目录目前被弃用. 3 那么一旦link成功, 在native project下面的Podfile文件会在Runner target会增加一行, eval(File.read(File.join(File.dirname(FILE), 'fbpodhelper.rb')), binding) 但目前这个文件来说, 只能读取flutter module的路径信息, 以及 读取 flutter_application_path = File.join(fbFlutterPath, '.ios', 'Flutter') eval(File.read(File.join(flutter_application_path, 'podhelper.rb')), binding) podhelper.rb这个文件只是一些函数定义, 并没有主动调用类似install_all_flutter_pods的调用

以上问题, 导致native的对flutter module作为framework的环境无法建立.以上如果步骤有错误,希望作者提供文档,或者指正, 谢谢.

其实问题大致如你所说。在别的issue中也有差不多的讨论,这里不重复了。 关于ios和.ios这两个路径各自的用途,这里涉及到flutter_tools的实现细节。这里贴一段flutter_tools的源码:

void _regenerateFromTemplateIfNeeded() {
  if (!isModule)
    return;
  final bool pubspecChanged = isOlderThanReference(entity: _ephemeralDirectory, referenceFile: parent.pubspecFile);
  final bool toolingChanged = Cache.instance.isOlderThanToolsStamp(_ephemeralDirectory);
  if (!pubspecChanged && !toolingChanged)
    return;
  _deleteIfExistsSync(_ephemeralDirectory);
  _overwriteFromTemplate(fs.path.join('module', 'ios', 'library'), _ephemeralDirectory);
  // Add ephemeral host app, if a editable host app does not already exist.
  if (!_editableDirectory.existsSync()) {
    _overwriteFromTemplate(fs.path.join('module', 'ios', 'host_app_ephemeral'), _ephemeralDirectory);
    if (hasPlugins(parent)) {
      _overwriteFromTemplate(fs.path.join('module', 'ios', 'host_app_ephemeral_cocoapods'), _ephemeralDirectory);
    }
  }
 }

这里.ios路径的变量名为_ephemeralDirectory,而ios路径的变量名为` _editableDirectory。根据变量名及代码上下文的分析可知,.ios其实是一个临时目录,事实上,在运行flutter run时,条件满足时会覆盖该路径。 从这个getter中可以看到,flutter优先使用的是_editableDirectory

/// This parent folder of `Runner.xcodeproj`.
Directory get hostAppRoot {
  if (!isModule || _editableDirectory.existsSync())
    return _editableDirectory;
  return _ephemeralDirectory;
}

其实这就是我们为什么会在ios目录下(而不是.ios)做软链接到客户工程的主要原因