| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| static int slbt_exec_compile_remove_file( |
| const struct slbt_driver_ctx * dctx, |
| struct slbt_exec_ctx * ectx, |
| const char * target) |
| { |
| (void)ectx; |
| |
| |
| if (!(unlink(target)) || (errno == ENOENT)) |
| return 0; |
| |
| return SLBT_SYSTEM_ERROR(dctx); |
| } |
| |
| static int slbt_exec_compile_finalize_argument_vector( |
| const struct slbt_driver_ctx * dctx, |
| struct slbt_exec_ctx * ectx) |
| { |
| char * sargv[1024]; |
| char ** sargvbuf; |
| char ** base; |
| char ** parg; |
| char ** aarg; |
| char ** aargv; |
| char ** cap; |
| char ** src; |
| char ** dst; |
| char * ccwrap; |
| |
| |
| base = ectx->argv; |
| parg = ectx->argv; |
| |
| for (; *parg; ) |
| parg++; |
| |
| |
| if (parg - base < 1024) { |
| aargv = sargv; |
| aarg = aargv; |
| sargvbuf = 0; |
| |
| } else if (!(sargvbuf = calloc(parg-base+1,sizeof(char *)))) { |
| return SLBT_SYSTEM_ERROR(dctx); |
| |
| } else { |
| aargv = sargvbuf; |
| aarg = aargv; |
| } |
| |
| |
| parg = &base[1]; |
| |
| |
| |
| for (; *parg; ) { |
| if (ectx->lout[0] == parg) { |
| ectx->lout[0] = &aarg[0]; |
| ectx->lout[1] = &aarg[1]; |
| } |
| |
| if (ectx->mout[0] == parg) { |
| ectx->mout[0] = &aarg[0]; |
| ectx->mout[1] = &aarg[1]; |
| } |
| |
| |
| if (!strncmp(*parg,"-USLIBTOOL_PLACEHOLDER_",23)) { |
| parg++; |
| } else { |
| *aarg++ = *parg++; |
| } |
| } |
| |
| |
| if ((ccwrap = (char *)dctx->cctx->ccwrap)) { |
| base[1] = base[0]; |
| base[0] = ccwrap; |
| base++; |
| } |
| |
| |
| src = aargv; |
| cap = aarg; |
| dst = &base[1]; |
| |
| for (; src<cap; ) |
| *dst++ = *src++; |
| |
| |
| *dst = 0; |
| |
| |
| if (ectx->lout[0]) { |
| ectx->lout[0] = &base[1] + (ectx->lout[0] - aargv); |
| ectx->lout[1] = ectx->lout[0] + 1; |
| } |
| |
| if (ectx->mout[0]) { |
| ectx->mout[0] = &base[1] + (ectx->mout[0] - aargv); |
| ectx->mout[1] = ectx->mout[0] + 1; |
| } |
| |
| |
| if (sargvbuf) |
| free(sargvbuf); |
| |
| return 0; |
| } |
| |
| int slbt_exec_compile( |
| const struct slbt_driver_ctx * dctx, |
| struct slbt_exec_ctx * ectx) |
| { |
| int ret; |
| char * fpic; |
| char * ccwrap; |
| struct slbt_exec_ctx * actx = 0; |
| const struct slbt_common_ctx * cctx = dctx->cctx; |
| |
| |
| if (cctx->drvflags & SLBT_DRIVER_DRY_RUN) |
| return 0; |
| |
| |
| if (ectx) |
| slbt_reset_placeholders(ectx); |
| else if ((ret = slbt_get_exec_ctx(dctx,&ectx))) |
| return ret; |
| else |
| actx = ectx; |
| |
| |
| if (slbt_exec_compile_remove_file(dctx,ectx,ectx->ltobjname)) |
| return SLBT_NESTED_ERROR(dctx); |
| |
| |
| if (cctx->drvflags & SLBT_DRIVER_SHARED) |
| if (slbt_mkdir(dctx,ectx->ldirname)) { |
| slbt_free_exec_ctx(actx); |
| return SLBT_SYSTEM_ERROR(dctx); |
| } |
| |
| |
| ccwrap = (char *)cctx->ccwrap; |
| ectx->program = ccwrap ? ccwrap : ectx->compiler; |
| ectx->argv = ectx->cargv; |
| |
| |
| switch (cctx->tag) { |
| case SLBT_TAG_CC: |
| case SLBT_TAG_CXX: |
| case SLBT_TAG_F77: |
| fpic = cctx->settings.picswitch |
| ? cctx->settings.picswitch |
| : *ectx->fpic; |
| break; |
| |
| default: |
| fpic = *ectx->fpic; |
| } |
| |
| |
| if (cctx->drvflags & SLBT_DRIVER_SHARED) { |
| if (!(cctx->drvflags & SLBT_DRIVER_ANTI_PIC)) { |
| *ectx->dpic = "-DPIC"; |
| *ectx->fpic = fpic; |
| } |
| |
| *ectx->lout[0] = "-o"; |
| *ectx->lout[1] = ectx->lobjname; |
| |
| if (slbt_exec_compile_finalize_argument_vector(dctx,ectx)) |
| return SLBT_NESTED_ERROR(dctx); |
| |
| if (!(cctx->drvflags & SLBT_DRIVER_SILENT)) { |
| if (slbt_output_compile(dctx,ectx)) { |
| slbt_free_exec_ctx(actx); |
| return SLBT_NESTED_ERROR(dctx); |
| } |
| } |
| |
| if (((ret = slbt_spawn(ectx,true)) < 0) || ectx->exitcode) { |
| slbt_free_exec_ctx(actx); |
| return SLBT_SYSTEM_ERROR(dctx); |
| } |
| |
| if (cctx->drvflags & SLBT_DRIVER_STATIC) |
| slbt_reset_argvector(ectx); |
| } |
| |
| |
| if (cctx->drvflags & SLBT_DRIVER_STATIC) { |
| slbt_reset_placeholders(ectx); |
| |
| if (cctx->drvflags & SLBT_DRIVER_PRO_PIC) { |
| *ectx->dpic = "-DPIC"; |
| *ectx->fpic = fpic; |
| } |
| |
| *ectx->lout[0] = "-o"; |
| *ectx->lout[1] = ectx->aobjname; |
| |
| if (slbt_exec_compile_finalize_argument_vector(dctx,ectx)) |
| return SLBT_NESTED_ERROR(dctx); |
| |
| if (!(cctx->drvflags & SLBT_DRIVER_SILENT)) { |
| if (slbt_output_compile(dctx,ectx)) { |
| slbt_free_exec_ctx(actx); |
| return SLBT_NESTED_ERROR(dctx); |
| } |
| } |
| |
| if (((ret = slbt_spawn(ectx,true)) < 0) || ectx->exitcode) { |
| slbt_free_exec_ctx(actx); |
| return SLBT_SYSTEM_ERROR(dctx); |
| } |
| } |
| |
| ret = slbt_create_object_wrapper(dctx,ectx); |
| slbt_free_exec_ctx(actx); |
| |
| return ret ? SLBT_NESTED_ERROR(dctx) : 0; |
| } |