/*******************************************************************/ /* slibtool: a strong libtool implementation, written in C */ /* Copyright (C) 2016--2024 SysDeer Technologies, LLC */ /* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ /*******************************************************************/ #include #include #include #include #include "slibtool_driver_impl.h" #include "slibtool_dprintf_impl.h" #include "slibtool_errinfo_impl.h" static const char enable[] = "yes"; static const char disable[] = "no"; static const char lconf_begin[] = "# ### BEGIN LIBTOOL CONFIG\n"; static const char lconf_end [] = "# ### END LIBTOOL CONFIG\n"; static const char lconf_guard[] = "# ### ##################\n"; static int slbt_output_config_lconf( const struct slbt_driver_ctx * dctx, const struct slbt_map_info * lconf) { const char * ch; const char * cfg_begin; const char * cfg_end; const char * map_cap; size_t cmp_len; size_t end_len; size_t min_len; size_t nbytes; ssize_t written; int fdout; cmp_len = strlen(lconf_begin); end_len = strlen(lconf_end); min_len = cmp_len + end_len; if (lconf->size < min_len) return SLBT_CUSTOM_ERROR( dctx, SLBT_ERR_FLOW_ERROR); map_cap = lconf->addr; map_cap += lconf->size; map_cap -= strlen(lconf_end); map_cap -= strlen(lconf_begin); cfg_begin = cfg_end = 0; for (ch=lconf->addr; !cfg_begin && (ch < map_cap); ch++) if (!strncmp(ch,lconf_begin,cmp_len)) cfg_begin = ch; if (!cfg_begin) return SLBT_CUSTOM_ERROR( dctx, SLBT_ERR_FLOW_ERROR); for (++ch; !cfg_end && (ch < map_cap); ch++) if (!strncmp(ch,lconf_end,end_len)) cfg_end = ch; if (!cfg_end) return SLBT_CUSTOM_ERROR( dctx, SLBT_ERR_FLOW_ERROR); fdout = slbt_driver_fdout(dctx); nbytes = cfg_end - cfg_begin - cmp_len; for (ch=&cfg_begin[cmp_len]; nbytes; ) { written = write(fdout,ch,nbytes); while ((written < 0) && (errno == EINTR)) written = write(fdout,ch,nbytes); if (written < 0) return SLBT_SYSTEM_ERROR(dctx,0); nbytes -= written; ch += written; } return 0; } static int slbt_output_config_mkvars(const struct slbt_driver_ctx * dctx) { int fdout; const char * shared_option; const char * static_option; const struct slbt_source_version * verinfo; const struct slbt_common_ctx * cctx; /* init */ fdout = slbt_driver_fdout(dctx); shared_option = (dctx->cctx->drvflags & SLBT_DRIVER_DISABLE_SHARED) ? disable : enable; static_option = (dctx->cctx->drvflags & SLBT_DRIVER_DISABLE_STATIC) ? disable : enable; cctx = dctx->cctx; /* header */ verinfo = slbt_api_source_version(); if (slbt_dprintf( fdout, "%s\n\n" "%s\n" "# %s\n" "# Generated by %s (slibtool %d.%d.%d)\n" "# [commit reference: %s]\n\n", "#!/dev/null", lconf_begin, "Backward compatible build configuration", dctx->program, verinfo->major,verinfo->minor,verinfo->revision, verinfo->commit) < 0) return SLBT_SYSTEM_ERROR(dctx,0); /* shared & static build options */ if (slbt_dprintf(fdout,"# shared libraries?\n" "build_libtool_libs=%s\n\n",shared_option) < 0) return SLBT_SYSTEM_ERROR(dctx,0); if (slbt_dprintf(fdout,"# static libraries?\n" "build_old_libs=%s\n\n",static_option) < 0) return SLBT_SYSTEM_ERROR(dctx,0); if (slbt_dprintf(fdout,"# host identification\n" "host=%s\n\n",cctx->host.host) < 0) return SLBT_SYSTEM_ERROR(dctx,0); if (slbt_dprintf(fdout,"# archiver\n" "AR=\"%s\"\n\n",cctx->host.ar) < 0) return SLBT_SYSTEM_ERROR(dctx,0); if (slbt_dprintf(fdout,"# name mangler\n" "NM=\"%s\"\n\n",cctx->host.nm) < 0) return SLBT_SYSTEM_ERROR(dctx,0); if (slbt_dprintf(fdout,"# archive librarian\n" "RANLIB=\"%s\"\n\n",cctx->host.ranlib) < 0) return SLBT_SYSTEM_ERROR(dctx,0); if (slbt_dprintf(fdout,"# assembler\n" "AS=\"%s\"\n\n",cctx->host.as) < 0) return SLBT_SYSTEM_ERROR(dctx,0); if (slbt_dprintf(fdout,"# PE targets: modern import library compiler\n" "MDSO=%s%s%s\n\n", cctx->host.mdso[0] ? "\"" : "", cctx->host.mdso[0] ? cctx->host.mdso : "", cctx->host.mdso[0] ? "\"" : "") < 0) return SLBT_SYSTEM_ERROR(dctx,0); if (slbt_dprintf(fdout,"# PE targets: coff import library compiler\n" "DLLTOOL=%s%s%s\n\n", cctx->host.dlltool[0] ? "\"" : "", cctx->host.dlltool[0] ? cctx->host.dlltool : "", cctx->host.dlltool[0] ? "\"" : "") < 0) return SLBT_SYSTEM_ERROR(dctx,0); if (slbt_dprintf(fdout,"# PE targets: resource compiler\n" "WINDRES=%s%s%s\n\n", cctx->host.windres[0] ? "\"" : "", cctx->host.windres[0] ? cctx->host.windres : "", cctx->host.windres[0] ? "\"" : "") < 0) return SLBT_SYSTEM_ERROR(dctx,0); if (slbt_dprintf(fdout,"%s%s%s\n",lconf_end,lconf_guard,lconf_guard) < 0) return SLBT_SYSTEM_ERROR(dctx,0); return 0; } int slbt_output_config(const struct slbt_driver_ctx * dctx) { struct slbt_driver_ctx_impl * ictx; const struct slbt_map_info * lconf; ictx = slbt_get_driver_ictx(dctx); lconf = &ictx->lconf; if (lconf->addr) return slbt_output_config_lconf( dctx,lconf); if (ictx->mkvarsctx || true) return slbt_output_config_mkvars(dctx); return 0; }