summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/slibtool/slibtool.h3
-rw-r--r--src/internal/slibtool_driver_impl.h2
-rw-r--r--src/logic/slbt_exec_ar.c52
-rw-r--r--src/skin/slbt_skin_ar.c16
4 files changed, 72 insertions, 1 deletions
diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h
index b081e57..0cbcad5 100644
--- a/include/slibtool/slibtool.h
+++ b/include/slibtool/slibtool.h
@@ -76,6 +76,7 @@ extern "C" {
#define SLBT_DRIVER_MODE_AR SLBT_DRIVER_XFLAG(0x010000)
#define SLBT_DRIVER_MODE_AR_CHECK SLBT_DRIVER_XFLAG(0x020000)
+#define SLBT_DRIVER_MODE_AR_MERGE SLBT_DRIVER_XFLAG(0x040000)
/* unit action flags */
#define SLBT_ACTION_MAP_READWRITE 0x0001
@@ -127,6 +128,8 @@ enum slbt_custom_error {
SLBT_ERR_AR_INVALID_ARMAP_STRING_TABLE,
SLBT_ERR_AR_INVALID_ARMAP_MEMBER_OFFSET,
SLBT_ERR_AR_INVALID_ARMAP_NAME_OFFSET,
+ SLBT_ERR_AR_OUTPUT_NOT_SPECIFIED,
+ SLBT_ERR_AR_OUTPUT_NOT_APPLICABLE,
};
/* execution modes */
diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h
index 631a1b6..17cb290 100644
--- a/src/internal/slibtool_driver_impl.h
+++ b/src/internal/slibtool_driver_impl.h
@@ -92,6 +92,8 @@ enum app_tags {
TAG_AR_PRETTY,
TAG_AR_POSIX,
TAG_AR_YAML,
+ TAG_AR_MERGE,
+ TAG_AR_OUTPUT,
TAG_AR_VERBOSE,
};
diff --git a/src/logic/slbt_exec_ar.c b/src/logic/slbt_exec_ar.c
index e3613fd..eab86ea 100644
--- a/src/logic/slbt_exec_ar.c
+++ b/src/logic/slbt_exec_ar.c
@@ -11,7 +11,8 @@
#include "slibtool_errinfo_impl.h"
#include "argv/argv.h"
-#define SLBT_DRIVER_MODE_AR_ACTIONS (SLBT_DRIVER_MODE_AR_CHECK)
+#define SLBT_DRIVER_MODE_AR_ACTIONS (SLBT_DRIVER_MODE_AR_CHECK \
+ | SLBT_DRIVER_MODE_AR_MERGE)
#define SLBT_DRIVER_MODE_AR_OUTPUTS (SLBT_OUTPUT_ARCHIVE_MEMBERS \
| SLBT_OUTPUT_ARCHIVE_HEADERS \
@@ -77,6 +78,7 @@ static int slbt_exec_ar_perform_archive_actions(
struct slbt_archive_ctx ** arctxv)
{
struct slbt_archive_ctx ** arctxp;
+ struct slbt_archive_ctx * arctx;
for (arctxp=arctxv; *arctxp; arctxp++) {
if (dctx->cctx->fmtflags & SLBT_DRIVER_MODE_AR_OUTPUTS)
@@ -88,6 +90,15 @@ static int slbt_exec_ar_perform_archive_actions(
return SLBT_NESTED_ERROR(dctx);
}
+ if (dctx->cctx->drvflags & SLBT_DRIVER_MODE_AR_MERGE) {
+ if (slbt_merge_archives(arctxv,&arctx) < 0)
+ return SLBT_NESTED_ERROR(dctx);
+
+ /* (defer mode to umask) */
+ if (slbt_store_archive(arctx,dctx->cctx->output,0666) < 0)
+ return SLBT_NESTED_ERROR(dctx);
+ }
+
return 0;
}
@@ -183,6 +194,14 @@ int slbt_exec_ar(
ictx->cctx.drvflags |= SLBT_DRIVER_MODE_AR_CHECK;
break;
+ case TAG_AR_MERGE:
+ ictx->cctx.drvflags |= SLBT_DRIVER_MODE_AR_MERGE;
+ break;
+
+ case TAG_AR_OUTPUT:
+ ictx->cctx.output = entry->arg;
+ break;
+
case TAG_AR_PRINT:
if (!entry->arg)
ictx->cctx.fmtflags |= SLBT_OUTPUT_ARCHIVE_MEMBERS;
@@ -260,6 +279,37 @@ int slbt_exec_ar(
SLBT_ERR_AR_NO_ACTION_SPECIFIED));
}
+ /* -Wmerge without -Woutput? */
+ if ((cctx->drvflags & SLBT_DRIVER_MODE_AR_MERGE) && !cctx->output) {
+ if (cctx->drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
+ slbt_dprintf(fderr,
+ "%s: archive merging: output must be specified.\n",
+ dctx->program);
+
+ return slbt_exec_ar_fail(
+ actx,meta,
+ SLBT_CUSTOM_ERROR(
+ dctx,
+ SLBT_ERR_AR_OUTPUT_NOT_SPECIFIED));
+ }
+
+
+ /* -Woutput without -Wmerge? */
+ if (cctx->output && !(cctx->drvflags & SLBT_DRIVER_MODE_AR_MERGE)) {
+ if (cctx->drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
+ slbt_dprintf(fderr,
+ "%s: output may only be specified "
+ "when merging one or more archives.\n",
+ dctx->program);
+
+ return slbt_exec_ar_fail(
+ actx,meta,
+ SLBT_CUSTOM_ERROR(
+ dctx,
+ SLBT_ERR_AR_OUTPUT_NOT_APPLICABLE));
+ }
+
+
/* at least one unit must be specified */
if (!nunits) {
if (cctx->drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
diff --git a/src/skin/slbt_skin_ar.c b/src/skin/slbt_skin_ar.c
index 5108554..d424abe 100644
--- a/src/skin/slbt_skin_ar.c
+++ b/src/skin/slbt_skin_ar.c
@@ -14,6 +14,22 @@ const struct argv_option slbt_ar_options[] = {
"verify that each %s is a valid archive; "
"supported variants are BSD, SysV, and PE/COFF"},
+ {"Wmerge", 0,TAG_AR_MERGE,ARGV_OPTARG_NONE,
+ ARGV_OPTION_HYBRID_ONLY,
+ "[ARCHIVE-FILE]",0,
+ "merge one or more archive files; "
+ "the name of the new archive, which may be the same "
+ "as one of the input archives, shall be specified "
+ "via the -Woutput switch; order of archive members "
+ "shall be retained, and symbol maps shall be "
+ "merged as well as normalized."},
+
+ {"Woutput", 0,TAG_AR_OUTPUT,ARGV_OPTARG_REQUIRED,
+ ARGV_OPTION_HYBRID_ONLY|ARGV_OPTION_HYBRID_SPACE,
+ 0,0,
+ "specify the name of the archive to be created "
+ "(or replaced) as a result of a -Wmerge operation."},
+
{"Wprint", 0,TAG_AR_PRINT,ARGV_OPTARG_OPTIONAL,
ARGV_OPTION_HYBRID_EQUAL|ARGV_OPTION_HYBRID_COMMA,
"members",0,