diff --git a/.dockerignore b/.dockerignore index 33849337c..4e893e699 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,4 +2,5 @@ !build/release/packaging/rpm/* !thirdparty/libxil/ !thirdparty/criterion/ -!thirdparty/libwebsockets/ \ No newline at end of file +!thirdparty/libwebsockets/ +!thirdparty/nanomsg/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 6de52bcb8..59504c262 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,3 +25,6 @@ [submodule "thirdparty/libopal"] path = thirdparty/libopal url = ../libopal.git +[submodule "thirdparty/nanomsg"] + path = thirdparty/nanomsg + url = https://github.com/nanomsg/nanomsg.git diff --git a/Dockerfile.dev b/Dockerfile.dev index deb5c3571..1e542147a 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -56,7 +56,8 @@ RUN dnf -y install \ iproute \ python-pip \ valgrind \ - gdb + gdb \ + xmlto rubygem-asciidoctor # 32bit versions of some standard libraries for RT-LAB code RUN dnf -y install \ @@ -80,6 +81,10 @@ RUN mkdir -p /tmp/criterion/build && cd /tmp/criterion/build && cmake -DCMAKE_IN COPY thirdparty/libwebsockets /tmp/libwebsockets RUN mkdir -p /tmp/libwebsockets/build && cd /tmp/libwebsockets/build && cmake -DLWS_IPV6=1 -DLWS_WITH_STATIC=0 -DLWS_WITHOUT_TESTAPPS=1 -DLWS_WITH_HTTP2=1 -DLIB_SUFFIX=64 .. && make install +# Build & Install nanomsg +COPY thirdparty/nanomsg /tmp/nanomsg +RUN mkdir -p /tmp/nanomsg/build && cd /tmp/nanomsg/build && cmake .. && make install + # Cleanup intermediate files from builds RUN rm -rf /tmp/* diff --git a/etc/example.conf b/etc/example.conf index a0e638f65..86cba27e7 100644 --- a/etc/example.conf +++ b/etc/example.conf @@ -145,9 +145,23 @@ nodes = { ] }, websocket_node = { - type = "websocket" + type = "websocket", destinations = [ "http://example.com/node-name1", "https://example.com/another-node" ] + }, + nanomsg_node = { + type = "nanomsg", + + publish = [ + "tcp://*:12000", # TCP socket + "ipc:///tmp/test.ipc", # Interprocess communication + "inproc://test" # Inprocess communication + ], + subscribe = [ + "tcp://127.0.0.1:12000", + "ipc:///tmp/test.ipc", + "inproc://test" + ] } }; diff --git a/include/villas/list.h b/include/villas/list.h index 6615c665f..18c2d99bd 100644 --- a/include/villas/list.h +++ b/include/villas/list.h @@ -97,4 +97,7 @@ int list_count(struct list *l, cmp_cb_t cmp, void *ctx); int list_contains(struct list *l, void *p); /** Sort the list using the quicksort algorithm of libc */ -void list_sort(struct list *l, cmp_cb_t cmp); \ No newline at end of file +void list_sort(struct list *l, cmp_cb_t cmp); + +/** Set single element in list */ +int list_set(struct list *l, int index, void *value); \ No newline at end of file diff --git a/include/villas/msg.h b/include/villas/msg.h index 27c8e8bb6..194ffe1b3 100644 --- a/include/villas/msg.h +++ b/include/villas/msg.h @@ -25,6 +25,10 @@ /* Forward declarations. */ struct msg; +struct sample; + +/** The maximum length of a packet which contains stuct msg. */ +#define MSG_MAX_PACKET_LEN 1500 /** Swaps the byte-order of the message. * @@ -48,4 +52,17 @@ void msg_hton(struct msg *m); * @retval 0 The message header is valid. * @retval <0 The message header is invalid. */ -int msg_verify(struct msg *m); \ No newline at end of file +int msg_verify(struct msg *m); + +/** Copy fields from \p msg into \p smp. */ +int msg_to_sample(struct msg *msg, struct sample *smp); + +/** Copy fields form \p smp into \p msg. */ +int msg_from_sample(struct msg *msg, struct sample *smp); + + +/** Copy / read struct msg's from buffer \p buf to / fram samples \p smps. */ +ssize_t msg_buffer_from_samples(struct sample *smps[], unsigned cnt, char *buf, size_t len); + +/** Read struct sample's from buffer \p buf into samples \p smps. */ +int msg_buffer_to_samples(struct sample *smps[], unsigned cnt, char *buf, size_t len); diff --git a/include/villas/nodes/nanomsg.h b/include/villas/nodes/nanomsg.h new file mode 100644 index 000000000..345919185 --- /dev/null +++ b/include/villas/nodes/nanomsg.h @@ -0,0 +1,67 @@ +/** Node type: nanomsg + * + * This file implements the file type for nodes. + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +/** + * @addtogroup nanomsg nanomsg node type + * @ingroup node + * @{ + */ + +#pragma once + +#include "node.h" +#include "list.h" + +struct nanomsg { + struct { + int socket; + struct list endpoints; + } publisher; + + struct { + int socket; + struct list endpoints; + } subscriber; +}; + +/** @see node_type::print */ +char * nanomsg_print(struct node *n); + +/** @see node_type::parse */ +int nanomsg_parse(struct node *n, config_setting_t *cfg); + +/** @see node_type::open */ +int nanomsg_start(struct node *n); + +/** @see node_type::close */ +int nanomsg_stop(struct node *n); + +/** @see node_type::read */ +int nanomsg_read(struct node *n, struct sample *smps[], unsigned cnt); + +/** @see node_type::write */ +int nanomsg_write(struct node *n, struct sample *smps[], unsigned cnt); + +/** @} */ diff --git a/lib/Makefile.villas.inc b/lib/Makefile.villas.inc index ab5aeabeb..1901cb23d 100644 --- a/lib/Makefile.villas.inc +++ b/lib/Makefile.villas.inc @@ -51,6 +51,14 @@ ifeq ($(shell $(PKGCONFIG) libnl-route-3.0; echo $$?),0) endif endif +# Enable nanomsg node type when libnanomsg is available +ifndef WITHOUT_NANOMSG +ifeq ($(shell $(PKGCONFIG) nanomsg; echo $$?),0) + LIB_SRCS += lib/nodes/nanomsg.c + LIB_PKGS += nanomsg +endif +endif + # Enable VILLASfpga support when libxil is available ifndef WITHOUT_FPGA ifeq ($(shell $(PKGCONFIG) libxil; echo $$?),0) diff --git a/lib/list.c b/lib/list.c index 9719ee773..758343411 100644 --- a/lib/list.c +++ b/lib/list.c @@ -188,4 +188,14 @@ void list_sort(struct list *l, cmp_cb_t cmp) qsort_r(l->array, l->length, sizeof(void *), cmp_sort, (void *) cmp); pthread_mutex_unlock(&l->lock); +} + +int list_set(struct list *l, int index, void *value) +{ + if (index >= l->length) + return -1; + + l->array[index] = value; + + return 0; } \ No newline at end of file diff --git a/lib/msg.c b/lib/msg.c index b857515b2..183b42669 100644 --- a/lib/msg.c +++ b/lib/msg.c @@ -21,9 +21,12 @@ *********************************************************************************/ #include +#include #include "msg.h" #include "msg_format.h" +#include "sample.h" +#include "utils.h" void msg_ntoh(struct msg *m) { @@ -67,4 +70,83 @@ int msg_verify(struct msg *m) return -3; else return 0; +} + +int msg_to_sample(struct msg *msg, struct sample *smp) +{ + int ret; + + msg_ntoh(msg); + + ret = msg_verify(msg); + if (ret) + return -1; + + smp->length = MIN(msg->length, smp->capacity); + smp->sequence = msg->sequence; + smp->ts.origin = MSG_TS(msg); + smp->ts.received.tv_sec = -1; + smp->ts.received.tv_nsec = -1; + + memcpy(smp->data, msg->data, SAMPLE_DATA_LEN(smp->length)); + + return 0; +} + +int msg_from_sample(struct msg *msg, struct sample *smp) +{ + *msg = MSG_INIT(smp->length, smp->sequence); + + msg->ts.sec = smp->ts.origin.tv_sec; + msg->ts.nsec = smp->ts.origin.tv_nsec; + + memcpy(msg->data, smp->data, MSG_DATA_LEN(smp->length)); + + msg_hton(msg); + + return 0; +} + +ssize_t msg_buffer_from_samples(struct sample *smps[], unsigned cnt, char *buf, size_t len) +{ + int ret, i = 0; + char *ptr = buf; + + struct msg *msg = (struct msg *) ptr; + struct sample *smp = smps[i]; + + while (ptr < buf + len && i < cnt) { + ret = msg_from_sample(msg, smp); + if (ret) + return ret; + + ptr += MSG_LEN(smp->length); + + msg = (struct msg *) ptr; + smp = smps[++i]; + } + + return ptr - buf; +} + +int msg_buffer_to_samples(struct sample *smps[], unsigned cnt, char *buf, size_t len) +{ + int ret, i = 0; + char *ptr = buf; + + struct msg *msg = (struct msg *) ptr; + struct sample *smp = smps[i]; + + while (ptr < buf + len && i < cnt) { + ret = msg_to_sample(msg, smp); + if (ret) + return ret; + + ptr += MSG_LEN(smp->length); + + msg = (struct msg *) ptr; + smp = smps[++i]; + } + + return i; } \ No newline at end of file diff --git a/lib/nodes/nanomsg.c b/lib/nodes/nanomsg.c new file mode 100644 index 000000000..5c15fdee9 --- /dev/null +++ b/lib/nodes/nanomsg.c @@ -0,0 +1,251 @@ +/** Node type: nanomsg + * + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +#include +#include +#include + +#include "plugin.h" +#include "nodes/nanomsg.h" +#include "utils.h" +#include "msg.h" + +int nanomsg_reverse(struct node *n) +{ + struct nanomsg *m = n->_vd; + + if (list_length(&m->publisher.endpoints) != 1 || + list_length(&m->subscriber.endpoints) != 1) + return -1; + + char *subscriber = list_first(&m->subscriber.endpoints); + char *publisher = list_first(&m->publisher.endpoints); + + list_set(&m->subscriber.endpoints, 0, publisher); + list_set(&m->publisher.endpoints, 0, subscriber); + + return 0; +} + +static int nanomsg_parse_endpoints(struct list *l, config_setting_t *cfg) +{ + const char *ep; + + switch (config_setting_type(cfg)) { + case CONFIG_TYPE_LIST: + case CONFIG_TYPE_ARRAY: + for (int j = 0; j < config_setting_length(cfg); j++) { + const char *ep = config_setting_get_string_elem(cfg, j); + + list_push(l, strdup(ep)); + } + break; + + case CONFIG_TYPE_STRING: + ep = config_setting_get_string(cfg); + + list_push(l, strdup(ep)); + + break; + + default: + return -1; + } + + return 0; +} + +int nanomsg_parse(struct node *n, config_setting_t *cfg) +{ + int ret; + struct nanomsg *m = n->_vd; + + config_setting_t *cfg_pub, *cfg_sub; + + list_init(&m->publisher.endpoints); + list_init(&m->subscriber.endpoints); + + cfg_pub = config_setting_lookup(cfg, "publish"); + if (cfg_pub) { + ret = nanomsg_parse_endpoints(&m->publisher.endpoints, cfg_pub); + if (ret < 0) + cerror(cfg_pub, "Invalid type for 'publish' setting of node %s", node_name(n)); + } + + cfg_sub = config_setting_lookup(cfg, "subscribe"); + if (cfg_sub) { + ret = nanomsg_parse_endpoints(&m->subscriber.endpoints, cfg_sub); + if (ret < 0) + cerror(cfg_pub, "Invalid type for 'subscribe' setting of node %s", node_name(n)); + } + + return 0; +} + +char * nanomsg_print(struct node *n) +{ + struct nanomsg *m = n->_vd; + + char *buf = NULL; + + strcatf(&buf, "subscribe=[ "); + + for (size_t i = 0; i < list_length(&m->subscriber.endpoints); i++) { + char *ep = list_at(&m->subscriber.endpoints, i); + + strcatf(&buf, "%s ", ep); + } + + strcatf(&buf, "], publish=[ "); + + for (size_t i = 0; i < list_length(&m->publisher.endpoints); i++) { + char *ep = list_at(&m->publisher.endpoints, i); + + strcatf(&buf, "%s ", ep); + } + + strcatf(&buf, " ]"); + + return buf; +} + +int nanomsg_start(struct node *n) +{ + int ret; + struct nanomsg *m = n->_vd; + + ret = m->subscriber.socket = nn_socket(AF_SP, NN_SUB); + if (ret < 0) + return ret; + + ret = m->publisher.socket = nn_socket(AF_SP, NN_PUB); + if (ret < 0) + return ret; + + /* Subscribe to all topics */ + ret = nn_setsockopt(ret = m->subscriber.socket, NN_SUB, NN_SUB_SUBSCRIBE, "", 0); + if (ret < 0) + return ret; + + /* Bind publisher to socket */ + for (size_t i = 0; i < list_length(&m->publisher.endpoints); i++) { + char *ep = list_at(&m->publisher.endpoints, i); + + ret = nn_bind(m->publisher.socket, ep); + if (ret < 0) { + info("Failed to connect nanomsg socket: node=%s, endpoint=%s, error=%s", node_name(n), ep, nn_strerror(errno)); + return ret; + } + } + + /* Sonnect subscribers socket */ + for (size_t i = 0; i < list_length(&m->subscriber.endpoints); i++) { + char *ep = list_at(&m->subscriber.endpoints, i); + + ret = nn_connect(m->subscriber.socket, ep); + if (ret < 0) { + info("Failed to connect nanomsg socket: node=%s, endpoint=%s, error=%s", node_name(n), ep, nn_strerror(errno)); + return ret; + } + } + + return 0; +} + +int nanomsg_stop(struct node *n) +{ + int ret; + struct nanomsg *m = n->_vd; + + ret = nn_shutdown(m->subscriber.socket, 0); + if (ret < 0) + return ret; + + ret = nn_shutdown(m->publisher.socket, 0); + if (ret < 0) + return ret; + + return 0; +} + +int nanomsg_deinit() +{ + nn_term(); + + return 0; +} + +int nanomsg_read(struct node *n, struct sample *smps[], unsigned cnt) +{ + int ret; + struct nanomsg *m = n->_vd; + + char data[MSG_MAX_PACKET_LEN]; + + /* Receive payload */ + ret = nn_recv(m->subscriber.socket, data, sizeof(data), 0); + if (ret < 0) + return ret; + + return msg_buffer_to_samples(smps, cnt, data, ret); +} + +int nanomsg_write(struct node *n, struct sample *smps[], unsigned cnt) +{ + int ret; + struct nanomsg *m = n->_vd; + + ssize_t sent; + + char data[MSG_MAX_PACKET_LEN]; + + sent = msg_buffer_from_samples(smps, cnt, data, sizeof(data)); + if (sent < 0) + return -1; + + ret = nn_send(m->publisher.socket, data, sent, 0); + if (ret < 0) + return ret; + + return cnt; +} + +static struct plugin p = { + .name = "nanomsg", + .description = "scalability protocols library", + .type = PLUGIN_TYPE_NODE, + .node = { + .vectorize = 0, + .size = sizeof(struct nanomsg), + .reverse = nanomsg_reverse, + .parse = nanomsg_parse, + .print = nanomsg_print, + .start = nanomsg_start, + .stop = nanomsg_stop, + .deinit = nanomsg_deinit, + .read = nanomsg_read, + .write = nanomsg_write, + .instances = LIST_INIT() + } +}; + +REGISTER_PLUGIN(&p) \ No newline at end of file diff --git a/lib/nodes/socket.c b/lib/nodes/socket.c index 7b630218e..828375999 100644 --- a/lib/nodes/socket.c +++ b/lib/nodes/socket.c @@ -348,37 +348,16 @@ static int socket_read_villas(struct node *n, struct sample *smps[], unsigned cn error("Remote node %s closed the connection", node_name(n)); else if (bytes < 0) serror("Failed receive packet from node %s", node_name(n)); - - int received = 0; - char *ptr = data; - - struct msg *msg = (struct msg *) ptr; - struct sample *smp = smps[received]; - - while (ptr < data + bytes - sizeof(struct msg) && received < cnt) { - msg_ntoh(msg); - - ret = msg_verify(msg); - if (ret) { - warn("Received invalid packet for node %s", node_name(n)); - return -1; - } - - smp->length = msg->length; - smp->sequence = msg->sequence; - smp->ts.origin = MSG_TS(msg); - smp->ts.received.tv_sec = -1; - smp->ts.received.tv_nsec = -1; - - memcpy(smp->data, msg->data, SAMPLE_DATA_LEN(msg->length)); - - ptr += MSG_LEN(msg->length); - - msg = (struct msg *) ptr; - smp = smps[++received]; + else if (bytes < MSG_LEN(1) || bytes % 4 != 0) { + warn("Received invalid packet for node %s", node_name(n)); + return 0; } - - return received; + + ret = msg_buffer_to_samples(smps, cnt, data, bytes); + if (ret < 0) + warn("Received invalid packet from node: %s", node_name(n)); + + return ret; } static int socket_write_none(struct node *n, struct sample *smps[], unsigned cnt) @@ -423,32 +402,15 @@ static int socket_write_villas(struct node *n, struct sample *smps[], unsigned c { struct socket *s = n->_vd; - ssize_t bytes = 0; + char data[MSG_MAX_PACKET_LEN]; + ssize_t bytes = 0, sent; - for (int i = 0; i < cnt; i++) - bytes += MSG_LEN(smps[i]->length); - - char data[bytes], *ptr = data; - - struct msg *msg = (struct msg *) ptr; - - for (int i = 0; i < cnt; i++) { - *msg = MSG_INIT(smps[i]->length, smps[i]->sequence); - - msg->ts.sec = smps[i]->ts.origin.tv_sec; - msg->ts.nsec = smps[i]->ts.origin.tv_nsec; - - memcpy(msg->data, smps[i]->data, MSG_DATA_LEN(smps[i]->length)); - - msg_hton(msg); - - ptr += MSG_LEN(msg->length); - - msg = (struct msg *) ptr; - } + sent = msg_buffer_from_samples(smps, cnt, data, sizeof(data)); + if (sent < 0) + return -1; /* Send message */ - bytes = sendto(s->sd, data, bytes, 0, (struct sockaddr *) &s->remote, sizeof(s->remote)); + bytes = sendto(s->sd, data, sent, 0, (struct sockaddr *) &s->remote, sizeof(s->remote)); if (bytes < 0) serror("Failed send to node %s", node_name(n)); diff --git a/packaging/rpm/Makefile.inc b/packaging/rpm/Makefile.inc index 8c032da78..72479fa81 100644 --- a/packaging/rpm/Makefile.inc +++ b/packaging/rpm/Makefile.inc @@ -38,6 +38,14 @@ rpm-libxil: $(BUILDDIR)/thirdparty/libxil/ | $(RPMDIR)/SOURCES/ cp $(BUILDDIR)/thirdparty/libxil/libxil-*.tar.gz $(RPMDIR)/SOURCES/ rpmbuild -ba --define="_topdir $$(pwd)/$(RPMDIR)" $(SRCDIR)/thirdparty/libxil/libxil.spec +rpm-nanomsg: $(BUILDDIR)/thirdparty/nanomsg/ | $(RPMDIR)/SOURCES/ + cmake -DCMAKE_INSTALL_PREFIX:PATH=$(PREFIX) \ + -H$(SRCDIR)/thirdparty/nanomsg \ + -B$(BUILDDIR)/thirdparty/nanomsg $(CMAKE_OPTS) + make -C$(BUILDDIR)/thirdparty/nanomsg package_source + cp $(BUILDDIR)/thirdparty/nanomsg/nanomsg-*.tar.gz $(RPMDIR)/SOURCES/ + rpmbuild -ba --define="_topdir $$(pwd)/$(RPMDIR)" $(SRCDIR)/packaging/rpm/nanomsg.spec + rpm-libwebsockets: | $(RPMDIR)/RPMS/x86_64/ $(BUILDDIR)/thirdparty/libwebsockets/ cmake -DCMAKE_INSTALL_PREFIX:PATH=$(PREFIX) \ -H$(SRCDIR)/thirdparty/libwebsockets \ diff --git a/packaging/rpm/nanomsg.spec b/packaging/rpm/nanomsg.spec new file mode 100644 index 000000000..6297756a4 --- /dev/null +++ b/packaging/rpm/nanomsg.spec @@ -0,0 +1,157 @@ +# Don't create static libraries (unless we want to) +%bcond_with static + + +Name: nanomsg +Version: 1.0.0 +Release: 40.master.20170523gitg5cc0074%{?dist} +Summary: A fast, scalable, and easy to use socket library + +Group: System Environment/Libraries +License: MIT +URL: http://nanomsg.org/ +Source0: nanomsg-%{version}-40-g5cc0074.tar.gz + +BuildRequires: rubygem-asciidoctor xmlto cmake +BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) + + +%description +nanomsg is a socket library that provides several common communication +patterns. It aims to make the networking layer fast, scalable, and easy +to use. Implemented in C, it works on a wide range of operating systems +with no further dependencies. + +The communication patterns, also called "scalability protocols", are +basic blocks for building distributed systems. By combining them you can +create a vast array of distributed applications. + + +%if %{with static} +%package static +Summary: Libraries for static linking of applications which will use nanomsg +Group: Development/Libraries +Requires: %{name}-devel%{?_isa} = %{version}-%{release} + +%description static +nanomsg is a socket library that provides several common communication +patterns. The nanomsg-static package includes static libraries needed to +link and develop applications using this library. + +Most users will not need to install this package. +%endif + + +%package devel +Summary: Development files for the nanomsg socket library +Group: Development/Libraries +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description devel +This package contains files needed to develop applications using nanomsg, +a socket library that provides several common communication patterns. + + +%package utils +Summary: Command line interface for communicating with nanomsg +Group: Applications/Internet + +%description utils +Includes nanocat, a simple utility for reading and writing to nanomsg +sockets and bindings, which can include local and remote connections. + + +%prep +%setup -q -n nanomsg-1.0.0-40-g5cc0074/ + +%build +# Enabling static library build disables the dynamic library. +# First configure and build the static library, then reconfigure and build +# the dynamic libs, tools and docs afterwards instead of patching CMake build files +%if %{with static} + %cmake -DNN_STATIC_LIB=ON -DNN_ENABLE_DOC=OFF -DNN_ENABLE_TEST=OFF -DNN_ENABLE_TOOLS=OFF . + make %{?_smp_mflags} V=1 +%endif +%cmake -DNN_STATIC_LIB=OFF -DNN_ENABLE_DOC=ON -DNN_ENABLE_TEST=ON -DNN_ENABLE_TOOLS=ON . +make %{?_smp_mflags} V=1 + + + +%install +rm -fR %{buildroot} +make install DESTDIR="%{buildroot}" + + +%check +#make test LD_LIBRARY_PATH="%{buildroot}%{_libdir}" DESTDIR="%{buildroot}" + + +%post -p /sbin/ldconfig +%postun -p /sbin/ldconfig + + +%clean +rm -fR %{buildroot} + + +%files +%defattr(-,root,root) +%doc AUTHORS COPYING README.md +%{_libdir}/*.so.* + +%if %{with static} +%files static +%defattr(-,root,root) +%{_libdir}/*.a* +%endif + + +%files devel +%defattr(-,root,root) +%{_docdir}/%{name} +%{_mandir}/man7/* +%{_mandir}/man3/* +%{_includedir}/* +%{_libdir}/*.so +%{_libdir}/pkgconfig/*.pc + + +%files utils +%defattr(-,root,root) +%{_mandir}/man1/* +%{_bindir}/* + + +%changelog +* Sat Apr 1 2017 Tarjei Knapstad - 1.0.0-1 +- Updated to 1.0.0 final release +- nanomsg moved to CMake, so this spec did too +- Changed source URL +- Moved contents of -doc package into -devel +- Removed conditional check, all tests should pass +- The nanocat symlink stuff is gone, nanocat is now a single binary with options + +* Tue Oct 27 2015 Japheth Cleaver 0.7-0.1.beta +- update to 0.7-beta release + +* Fri Nov 14 2014 Japheth Cleaver 0.5-0.1.beta +- update to 0.5-beta release + +* Sun Jul 27 2014 Japheth Cleaver 0.4-0.3.beta +- compile with correct Fedora flags +- move documentation back to base package +- spec file cleanups + +* Thu Jul 17 2014 Japheth Cleaver 0.4-0.2.beta +- drop the 'lib' prefix from package name +- remove explicit pkgconfig requires in nanomsg-devel +- move overview man pages to devel subpackage +- move html to doc subpackage + +* Thu Jul 17 2014 Japheth Cleaver 0.4-0.1.beta +- new "libnanomsg" package based on BZ#1012392, with current versioning +- devel and utils subpackages created, static lib a build conditional +- check section added as a build conditional +- ensure man pages for nanocat symlinks present +- disable RPATH in library +- License set to MIT \ No newline at end of file diff --git a/thirdparty/Makefile.inc b/thirdparty/Makefile.inc index cd4b0ed43..e1eddf17d 100644 --- a/thirdparty/Makefile.inc +++ b/thirdparty/Makefile.inc @@ -20,7 +20,7 @@ # along with this program. If not, see . ################################################################################### -DEPS_CMAKE = libxil libwebsockets criterion jansson +DEPS_CMAKE = libxil libwebsockets criterion jansson nanomsg DEPS_AUTOCONF = libnl libconfig libcurl DEPS = $(DEPS_CMAKE) $(DEPS_AUTOCONF) diff --git a/thirdparty/nanomsg b/thirdparty/nanomsg new file mode 160000 index 000000000..5cc007452 --- /dev/null +++ b/thirdparty/nanomsg @@ -0,0 +1 @@ +Subproject commit 5cc0074524684797dd5cd9067bbccbefe1513996