#line 1926 "/home/travis/build/felix-lang/felix/src/packages/toolchain.fdoc"
  include "std/felix/toolchain_interface";
  include "std/felix/toolchain_clang_config";
  include "std/felix/flx_cxx";
  
  object toolchain_clang_iphoneos (config:clang_config_t) implements toolchain_t =
  {
  
    var cxx_compile_warning_flags = list$
      "-w", // turn off all the warnings (but not hard errors)
      "-Wfatal-errors", // stop compiling on the first hard error
      "-Wno-return-type-c-linkage",
      "-Wno-invalid-offsetof"
    ;
    var c_compile_warning_flags = list$ "-w",
      "-Wfatal-errors",
      "-Wno-array-bounds"
    ;
  
    var sdk = Env::getenv "SDK";
    var arch = Env::getenv "ARCH";
    var c_compiler = "clang";
    var cxx_compiler = "clang++";
    var linker = "clang++";
  
    var ccflags_for_dynamic_link = list[string]("-dynamiclib", "-arch", arch, "-isysroot", sdk);
    // should be $(xcrun --sdk iphoneos --show-sdk-path). how to choose other SDK?
    var base_c_compile_flags =
      "-g"! "-c" ! "-arch" ! arch ! "-isysroot" ! sdk ! "-O1" ! "-fno-common"! "-fno-strict-aliasing" ! (c_compile_warning_flags+config.ccflags)
    ;
    var base_cxx_compile_flags =
      "-g"! "-c" ! "-arch" ! arch ! "-isysroot" ! sdk ! "-O1" ! "-fno-common"! "-fno-strict-aliasing" ! "-std=c++11" !  (cxx_compile_warning_flags+config.ccflags)
    ;
  
    method fun whatami () => "toolchain_clang_iphoneos (version 2)";
    method fun host_os () => "OSX";
    method fun target_os () => "iPhoneOS";
    method fun cxx_compiler_vendor () => "clang";
  
    method fun dependency_extension () => ".d";
    method fun executable_extension () => "";
    method fun static_object_extension () => "_static.o";
    method fun dynamic_object_extension () => "_dynamic.o";
    method fun static_library_extension () => ".a";
    method fun dynamic_library_extension () => ".dylib";
    method fun pathname_separator () => "/";
    method fun debug_flags () => list[string] "-g";
    method fun get_base_c_compile_flags () => base_c_compile_flags;
    method fun get_base_cxx_compile_flags () => base_cxx_compile_flags;
  
  // Boilerplate
  
    method gen c_dependency_generator (spec:(src:string)) : int * string =
    {
       var result, data =
         CxxCompiler::generic_cxx_gen_deps
         (
            CCDEP=c_compiler,
            CCFLAGS = "-MM" ! config.ccflags,
            INCLUDE_DIRS=config.header_search_dirs,
            MACROS=config.macros,
            debugln = config.debugln
         )
         (spec.src)
       ;
       return result,  data;
    }
  
    method gen cxx_dependency_generator (spec:(src:string)) : int * string =
    {
       var result, data =
         CxxCompiler::generic_cxx_gen_deps
         (
            CCDEP=cxx_compiler,
            CCFLAGS = "-MM" ! config.ccflags,
            INCLUDE_DIRS=config.header_search_dirs,
            MACROS=config.macros,
            debugln = config.debugln
         )
         (spec.src)
       ;
       return result, data;
    }
  
    method gen dependency_parser (data:string) : list[string] =>
       CxxCompiler::generic_dependency_parser data
    ;
  
    method gen c_static_object_compiler (spec:(dst:string, src:string)) : int =
    {
      var result =
        CxxCompiler::generic_cxx_compile_for_static
        (
          CCOBJ_STATIC_LIB = c_compiler,
          CCFLAGS = base_c_compile_flags,
          INCLUDE_DIRS = config.header_search_dirs,
          MACROS = config.macros,
          SPEC_OBJ_FILENAME = "-o ",
          debugln = config.debugln
        )
        (spec.src, spec.dst)
      ;
      return result;
    }
  
    method gen c_dynamic_object_compiler (spec:(dst:string, src:string)) : int =
    {
      var result =
        CxxCompiler::generic_cxx_compile_for_dynamic
        (
          CCOBJ_DLLIB = c_compiler,
          CCFLAGS = "-fPIC" ! "-fvisibility=hidden" ! base_c_compile_flags,
          INCLUDE_DIRS = config.header_search_dirs,
          MACROS = config.macros,
          SPEC_OBJ_FILENAME = "-o ",
          debugln = config.debugln
        )
        (spec.src, spec.dst)
      ;
      return result;
    }
  
  
    method gen cxx_static_object_compiler (spec:(dst:string, src:string)) : int =
    {
      var result =
        CxxCompiler::generic_cxx_compile_for_static
        (
          CCOBJ_STATIC_LIB = cxx_compiler,
          CCFLAGS = base_cxx_compile_flags,
          INCLUDE_DIRS = config.header_search_dirs,
          MACROS = config.macros,
          SPEC_OBJ_FILENAME = "-o ",
          debugln = config.debugln
        )
        (spec.src, spec.dst)
      ;
      return result;
    }
  
    method gen cxx_static_library_object_compiler (spec:(dst:string, src:string)) : int =
    {
      var result =
        CxxCompiler::generic_cxx_compile_for_static
        (
          CCOBJ_STATIC_LIB = cxx_compiler,
          CCFLAGS = base_cxx_compile_flags,
          INCLUDE_DIRS = config.header_search_dirs,
          MACROS = "FLX_STATIC_LINK"+config.macros,
          SPEC_OBJ_FILENAME = "-o ",
          debugln = config.debugln
        )
        (spec.src, spec.dst)
      ;
      return result;
    }
  
  
    method gen cxx_dynamic_object_compiler (spec:(dst:string, src:string)) : int =
    {
      var result =
        CxxCompiler::generic_cxx_compile_for_dynamic
        (
          CCOBJ_DLLIB = linker,
          CCFLAGS = "-fPIC" ! "-fvisibility=hidden" ! base_cxx_compile_flags,
          INCLUDE_DIRS = config.header_search_dirs,
          MACROS = config.macros,
          SPEC_OBJ_FILENAME = "-o ",
          debugln = config.debugln
        )
        (spec.src, spec.dst)
      ;
      return result;
    }
  
    method gen static_library_linker (spec:(dst:string, srcs:list[string])): int =
    {
      var result =
        CxxCompiler::generic_static_library
        (
          CCLINK_STATIC_LIB = "ar",
          CCFLAGS = list[string]("-rcs"),
          SPEC_LIB_FILENAME = "",
          debugln = config.debugln
        )
        (spec.srcs, spec.dst)
      ;
      return result;
    }
  
    method gen static_executable_linker  (spec:(dst:string, srcs:list[string])) : int =
    {
      var result =
        CxxCompiler::generic_link_exe_static
        (
          CCLINK_STATIC = linker,
          CCFLAGS = Empty[string],
          SPEC_EXE_FILENAME = "-o ",
          LINK_STRINGS = config.library_search_dirs + config.static_libraries,
          debugln = config.debugln
        )
        (spec.srcs, spec.dst)
      ;
      return result;
    }
  
    method gen dynamic_executable_linker  (spec:(dst:string, srcs:list[string])) : int =
    {
      var result =
        CxxCompiler::generic_link_exe_dynamic
        (
          CCLINK_STATIC = linker,
          CCFLAGS = Empty[string],
          SPEC_EXE_FILENAME = "-o ",
          LINK_STRINGS = config.library_search_dirs + config.dynamic_libraries,
          debugln = config.debugln
        )
        (spec.srcs, spec.dst)
      ;
      return result;
    }
  
  
    method gen dynamic_library_linker (spec:(dst:string,srcs:list[string])) : int =
    {
      var result =
        CxxCompiler::generic_link_lib_dynamic
        (
          CCLINK_DLLIB = linker,
          CCFLAGS = ccflags_for_dynamic_link,
          EXT_SHARED_OBJ = #dynamic_library_extension,
          SPEC_EXE_FILENAME = "-o ",
          LINK_STRINGS = config.library_search_dirs + config.dynamic_libraries,
          debugln = config.debugln
        )
        (spec.srcs, spec.dst)
      ;
      return result;
    }
  }