@@ -6,6 +6,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <rte_common.h>
#include <rte_cycles.h>
@@ -17,6 +18,10 @@
#define CMD_MAX_TOKENS 256
#endif
+#ifndef MAX_LINE_SIZE
+#define MAX_LINE_SIZE 2048
+#endif
+
#define MSG_OUT_OF_MEMORY "Not enough memory.\n"
#define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
#define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
@@ -227,6 +232,139 @@ cmd_softnic_pipeline_codegen(struct pmd_internals *softnic __rte_unused,
}
}
+/**
+ * pipeline libbuild <code_file> <lib_file>
+ */
+static void
+cmd_softnic_pipeline_libbuild(struct pmd_internals *softnic __rte_unused,
+ char **tokens,
+ uint32_t n_tokens,
+ char *out,
+ size_t out_size)
+{
+ char *code_file, *lib_file, *obj_file = NULL, *log_file = NULL;
+ char *install_dir, *cwd = NULL, *buffer = NULL;
+ size_t length;
+ int status = 0;
+
+ if (n_tokens != 4) {
+ snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+ goto free;
+ }
+
+ install_dir = getenv("RTE_INSTALL_DIR");
+ if (!install_dir) {
+ cwd = malloc(MAX_LINE_SIZE);
+ if (!cwd) {
+ snprintf(out, out_size, MSG_OUT_OF_MEMORY);
+ goto free;
+ }
+
+ install_dir = getcwd(cwd, MAX_LINE_SIZE);
+ if (!install_dir) {
+ snprintf(out, out_size, "Error: Path too long.\n");
+ goto free;
+ }
+ }
+
+ snprintf(out, out_size, "Using DPDK source code from \"%s\".\n", install_dir);
+ out_size -= strlen(out);
+ out += strlen(out);
+
+ code_file = tokens[2];
+ length = strnlen(code_file, MAX_LINE_SIZE);
+ if (length < 3 ||
+ code_file[length - 2] != '.' ||
+ code_file[length - 1] != 'c') {
+ snprintf(out, out_size, MSG_ARG_INVALID, "code_file");
+ goto free;
+ }
+
+ lib_file = tokens[3];
+ length = strnlen(lib_file, MAX_LINE_SIZE);
+ if (length < 4 ||
+ lib_file[length - 3] != '.' ||
+ lib_file[length - 2] != 's' ||
+ lib_file[length - 1] != 'o') {
+ snprintf(out, out_size, MSG_ARG_INVALID, "lib_file");
+ goto free;
+ }
+
+ obj_file = malloc(length);
+ log_file = malloc(length + 2);
+ if (!obj_file || !log_file) {
+ snprintf(out, out_size, MSG_OUT_OF_MEMORY);
+ goto free;
+ }
+
+ memcpy(obj_file, lib_file, length - 2);
+ obj_file[length - 2] = 'o';
+ obj_file[length - 1] = 0;
+
+ memcpy(log_file, lib_file, length - 2);
+ log_file[length - 2] = 'l';
+ log_file[length - 1] = 'o';
+ log_file[length] = 'g';
+ log_file[length + 1] = 0;
+
+ buffer = malloc(MAX_LINE_SIZE);
+ if (!buffer) {
+ snprintf(out, out_size, MSG_OUT_OF_MEMORY);
+ return;
+ }
+
+ snprintf(buffer,
+ MAX_LINE_SIZE,
+ "gcc -c -O3 -fpic -Wno-deprecated-declarations -o %s %s "
+ "-I %s/lib/pipeline "
+ "-I %s/lib/eal/include "
+ "-I %s/lib/eal/x86/include "
+ "-I %s/lib/eal/include/generic "
+ "-I %s/lib/meter "
+ "-I %s/lib/port "
+ "-I %s/lib/table "
+ "-I %s/lib/pipeline "
+ "-I %s/config "
+ "-I %s/build "
+ "-I %s/lib/eal/linux/include "
+ ">%s 2>&1 "
+ "&& "
+ "gcc -shared %s -o %s "
+ ">>%s 2>&1",
+ obj_file,
+ code_file,
+ install_dir,
+ install_dir,
+ install_dir,
+ install_dir,
+ install_dir,
+ install_dir,
+ install_dir,
+ install_dir,
+ install_dir,
+ install_dir,
+ install_dir,
+ log_file,
+ obj_file,
+ lib_file,
+ log_file);
+
+ status = system(buffer);
+ if (status) {
+ snprintf(out,
+ out_size,
+ "Library build failed, see file \"%s\" for details.\n",
+ log_file);
+ goto free;
+ }
+
+free:
+ free(cwd);
+ free(obj_file);
+ free(log_file);
+ free(buffer);
+}
+
/**
* thread <thread_id> pipeline <pipeline_name> enable [ period <timer_period_ms> ]
*/
@@ -361,6 +499,11 @@ softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
cmd_softnic_pipeline_codegen(softnic, tokens, n_tokens, out, out_size);
return;
}
+
+ if (n_tokens >= 3 && !strcmp(tokens[1], "libbuild")) {
+ cmd_softnic_pipeline_libbuild(softnic, tokens, n_tokens, out, out_size);
+ return;
+ }
}
if (strcmp(tokens[0], "thread") == 0) {