Exemplo n.º 1
0
static void platform_linux(compile_t* c, reach_type_t* t)
{
  FIND_METHOD("linux");
  start_function(c, m, c->ibool, &t->use_type, 1);

  LLVMValueRef result =
    LLVMConstInt(c->ibool, target_is_linux(c->opt->triple), false);
  LLVMBuildRet(c->builder, result);
  codegen_finishfun(c);

  BOX_FUNCTION();
}
Exemplo n.º 2
0
static bool link_exe(compile_t* c, ast_t* program,
  const char* file_o)
{
  errors_t* errors = c->opt->check.errors;

  const char* ponyrt = c->opt->runtimebc ? "" :
#if defined(PLATFORM_IS_WINDOWS)
    "ponyrt.lib";
#elif defined(PLATFORM_IS_LINUX)
    c->opt->pic ? "-lponyrt-pic" : "-lponyrt";
#else
    "-lponyrt";
#endif

#if defined(PLATFORM_IS_MACOSX)
  char* arch = strchr(c->opt->triple, '-');

  if(arch == NULL)
  {
    errorf(errors, NULL, "couldn't determine architecture from %s",
      c->opt->triple);
    return false;
  }

  const char* file_exe =
    suffix_filename(c, c->opt->output, "", c->filename, "");

  if(c->opt->verbosity >= VERBOSITY_MINIMAL)
    fprintf(stderr, "Linking %s\n", file_exe);

  program_lib_build_args(program, c->opt, "-L", NULL, "", "", "-l", "");
  const char* lib_args = program_lib_args(program);

  size_t arch_len = arch - c->opt->triple;
  size_t ld_len = 128 + arch_len + strlen(file_exe) + strlen(file_o) +
    strlen(lib_args);
  char* ld_cmd = (char*)ponyint_pool_alloc_size(ld_len);
  const char* linker = c->opt->linker != NULL ? c->opt->linker
                                              : "ld";

  snprintf(ld_cmd, ld_len,
    "%s -execute -no_pie -dead_strip -arch %.*s "
    "-macosx_version_min 10.8 -o %s %s %s %s -lSystem",
           linker, (int)arch_len, c->opt->triple, file_exe, file_o,
           lib_args, ponyrt
    );

  if(c->opt->verbosity >= VERBOSITY_TOOL_INFO)
    fprintf(stderr, "%s\n", ld_cmd);

  if(system(ld_cmd) != 0)
  {
    errorf(errors, NULL, "unable to link: %s", ld_cmd);
    ponyint_pool_free_size(ld_len, ld_cmd);
    return false;
  }

  ponyint_pool_free_size(ld_len, ld_cmd);

  if(!c->opt->strip_debug)
  {
    size_t dsym_len = 16 + strlen(file_exe);
    char* dsym_cmd = (char*)ponyint_pool_alloc_size(dsym_len);

    snprintf(dsym_cmd, dsym_len, "rm -rf %s.dSYM", file_exe);
    system(dsym_cmd);

    snprintf(dsym_cmd, dsym_len, "dsymutil %s", file_exe);

    if(system(dsym_cmd) != 0)
      errorf(errors, NULL, "unable to create dsym");

    ponyint_pool_free_size(dsym_len, dsym_cmd);
  }

#elif defined(PLATFORM_IS_LINUX) || defined(PLATFORM_IS_FREEBSD)
  const char* file_exe =
    suffix_filename(c, c->opt->output, "", c->filename, "");

  if(c->opt->verbosity >= VERBOSITY_MINIMAL)
    fprintf(stderr, "Linking %s\n", file_exe);

  program_lib_build_args(program, c->opt, "-L", "-Wl,-rpath,",
    "-Wl,--start-group ", "-Wl,--end-group ", "-l", "");
  const char* lib_args = program_lib_args(program);

  const char* arch = c->opt->link_arch != NULL ? c->opt->link_arch : PONY_ARCH;
  bool fallback_linker = false;
  const char* linker = c->opt->linker != NULL ? c->opt->linker :
    env_cc_or_pony_compiler(&fallback_linker);

  if((c->opt->verbosity >= VERBOSITY_MINIMAL) && fallback_linker)
  {
    fprintf(stderr,
      "Warning: environment variable $CC undefined, using %s as the linker\n",
      PONY_COMPILER);
  }
  const char* mcx16_arg = target_is_ilp32(c->opt->triple) ? "" : "-mcx16";
  const char* fuseld = target_is_linux(c->opt->triple) ? "-fuse-ld=gold " : "";
  const char* ldl = target_is_linux(c->opt->triple) ? "-ldl  " : "";

  size_t ld_len = 512 + strlen(file_exe) + strlen(file_o) + strlen(lib_args)
                  + strlen(arch) + strlen(mcx16_arg) + strlen(fuseld)
                  + strlen(ldl);

  char* ld_cmd = (char*)ponyint_pool_alloc_size(ld_len);

  snprintf(ld_cmd, ld_len, "%s -o %s -O3 -march=%s "
    "%s "
#ifdef PONY_USE_LTO
    "-flto -fuse-linker-plugin "
#endif
    "%s %s %s %s -lpthread %s "
    "-lm",
    linker, file_exe, arch, mcx16_arg, fuseld, file_o, lib_args, ponyrt, ldl
    );

  if(c->opt->verbosity >= VERBOSITY_TOOL_INFO)
    fprintf(stderr, "%s\n", ld_cmd);

  if(system(ld_cmd) != 0)
  {
    errorf(errors, NULL, "unable to link: %s", ld_cmd);
    ponyint_pool_free_size(ld_len, ld_cmd);
    return false;
  }

  ponyint_pool_free_size(ld_len, ld_cmd);
#elif defined(PLATFORM_IS_WINDOWS)
  vcvars_t vcvars;

  if(!vcvars_get(&vcvars, errors))
  {
    errorf(errors, NULL, "unable to link: no vcvars");
    return false;
  }

  const char* file_exe = suffix_filename(c, c->opt->output, "", c->filename,
    ".exe");
  if(c->opt->verbosity >= VERBOSITY_MINIMAL)
    fprintf(stderr, "Linking %s\n", file_exe);

  program_lib_build_args(program, c->opt,
    "/LIBPATH:", NULL, "", "", "", ".lib");
  const char* lib_args = program_lib_args(program);

  char ucrt_lib[MAX_PATH + 12];
  if (strlen(vcvars.ucrt) > 0)
    snprintf(ucrt_lib, MAX_PATH + 12, "/LIBPATH:\"%s\"", vcvars.ucrt);
  else
    ucrt_lib[0] = '\0';

  size_t ld_len = 256 + strlen(file_exe) + strlen(file_o) +
    strlen(vcvars.kernel32) + strlen(vcvars.msvcrt) + strlen(lib_args);
  char* ld_cmd = (char*)ponyint_pool_alloc_size(ld_len);

  while (true)
  {
    int num_written = snprintf(ld_cmd, ld_len,
      "cmd /C \"\"%s\" /DEBUG /NOLOGO /MACHINE:X64 "
      "/OUT:%s "
      "%s %s "
      "/LIBPATH:\"%s\" "
      "/LIBPATH:\"%s\" "
      "%s %s %s \"",
      vcvars.link, file_exe, file_o, ucrt_lib, vcvars.kernel32, 
      vcvars.msvcrt, lib_args, vcvars.default_libs, ponyrt
    );

    if (num_written < ld_len)
      break;

    ponyint_pool_free_size(ld_len, ld_cmd);
    ld_len += 256;
    ld_cmd = (char*)ponyint_pool_alloc_size(ld_len);
  }

  if(c->opt->verbosity >= VERBOSITY_TOOL_INFO)
    fprintf(stderr, "%s\n", ld_cmd);

  if (system(ld_cmd) == -1)
  {
    errorf(errors, NULL, "unable to link: %s", ld_cmd);
    ponyint_pool_free_size(ld_len, ld_cmd);
    return false;
  }

  ponyint_pool_free_size(ld_len, ld_cmd);
#endif

  return true;
}
Exemplo n.º 3
0
// Report whether the named platform attribute is true
bool os_is_target(const char* attribute, bool release, bool* out_is_target, pass_opt_t* options)
{
  pony_assert(attribute != NULL);
  pony_assert(out_is_target != NULL);
  pony_assert(options != NULL);

  if(!strcmp(attribute, OS_BSD_NAME))
  {
    *out_is_target = target_is_bsd(options->triple);
    return true;
  }

  if(!strcmp(attribute, OS_FREEBSD_NAME))
  {
    *out_is_target = target_is_freebsd(options->triple);
    return true;
  }

  if(!strcmp(attribute, OS_DRAGONFLY_NAME))
  {
    *out_is_target = target_is_dragonfly(options->triple);
    return true;
  }

  if(!strcmp(attribute, OS_LINUX_NAME))
  {
    *out_is_target = target_is_linux(options->triple);
    return true;
  }

  if(!strcmp(attribute, OS_MACOSX_NAME))
  {
    *out_is_target = target_is_macosx(options->triple);
    return true;
  }

  if(!strcmp(attribute, OS_WINDOWS_NAME))
  {
    *out_is_target = target_is_windows(options->triple);
    return true;
  }

  if(!strcmp(attribute, OS_POSIX_NAME))
  {
    *out_is_target = target_is_posix(options->triple);
    return true;
  }

  if(!strcmp(attribute, OS_X86_NAME))
  {
    *out_is_target = target_is_x86(options->triple);
    return true;
  }

  if(!strcmp(attribute, OS_ARM_NAME))
  {
    *out_is_target = target_is_arm(options->triple);
    return true;
  }

  if(!strcmp(attribute, OS_LP64_NAME))
  {
    *out_is_target = target_is_lp64(options->triple);
    return true;
  }

  if(!strcmp(attribute, OS_LLP64_NAME))
  {
    *out_is_target = target_is_llp64(options->triple);
    return true;
  }

  if(!strcmp(attribute, OS_ILP32_NAME))
  {
    *out_is_target = target_is_ilp32(options->triple);
    return true;
  }

  if(!strcmp(attribute, OS_NATIVE128_NAME))
  {
    *out_is_target = target_is_native128(options->triple);
    return true;
  }

  if(!strcmp(attribute, OS_DEBUG_NAME))
  {
    *out_is_target = !release;
    return true;
  }

  return false;
}