Hello all,
Remember I am a noobie.
I have a c program that is a simple "mqtt_example.c". It works fine in my pc and I am trying to make it into a package to install in OpenWrt.
I have already followed completely the helloworld tutorial: https://openwrt.org/docs/guide-developer/helloworld/chapter1 and know how to create a package and install it in openwrt - I was able to create a helloworld package and install it in an OpenWrt running in virtualbox.
My "mqtt_example.c" program uses the paho libraries (see it bellow).
I managed to create a package for paho using this: https://github.com/ngohaibac/openwrt-extra-packages/blob/master/paho.mqtt.c/Makefile
MY PROBLEM is that when I try to make a package with my "mqtt_example.c" program that uses the paho libs it cannot find these libs and issues an error!
How can I add this lib to my mqqt_example.c makefile?
Thank you for your help.
B
+++ This is the error:
~/Documents/myStuff/energiasolar.pt/dev/openwrt$ **make -j1 V=s package/mqtt_exemplo/compile**
WARNING: Makefile 'package/utils/busybox/Makefile' has a dependency on 'libpam', which does not exist
WARNING: Makefile 'package/utils/busybox/Makefile' has a build dependency on 'libpam', which does not exist
WARNING: Makefile 'package/network/utils/curl/Makefile' has a dependency on 'libgnutls', which does not exist
WARNING: Makefile 'package/network/utils/curl/Makefile' has a dependency on 'libopenldap', which does not exist
WARNING: Makefile 'package/network/utils/curl/Makefile' has a dependency on 'libidn2', which does not exist
WARNING: Makefile 'package/network/utils/curl/Makefile' has a dependency on 'libssh2', which does not exist
WARNING: Makefile 'package/boot/kexec-tools/Makefile' has a dependency on 'liblzma', which does not exist
WARNING: Makefile 'package/network/services/lldpd/Makefile' has a dependency on 'libnetsnmp', which does not exist
WARNING: Makefile 'package/feeds/espt_packages/mqtt_exemplo/Makefile' has a dependency on 'libpaho-mqtt3c', which does not exist
make[1]: Entering directory '/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt'
make[2]: Entering directory '/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/package/libs/toolchain'
echo "libc" >> /home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/staging_dir/target-x86_64_musl/pkginfo/toolchain.default.install
echo "libgcc" >> /home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/staging_dir/target-x86_64_musl/pkginfo/toolchain.default.install
echo "libpthread" >> /home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/staging_dir/target-x86_64_musl/pkginfo/toolchain.default.install
echo "librt" >> /home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/staging_dir/target-x86_64_musl/pkginfo/toolchain.default.install
make[2]: Leaving directory '/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/package/libs/toolchain'
time: package/libs/toolchain/compile#0.11#0.04#0.17
make[2]: Entering directory '/home/joao/Documents/myStuff/energiasolar.pt/dev/espt_packages/examples/mqtt_exemplo'
rm -f /home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/build_dir/target-x86_64_musl/mqtt_exemplo-1.0/.built
touch /home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/build_dir/target-x86_64_musl/mqtt_exemplo-1.0/.built_check
make -C /home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/build_dir/target-x86_64_musl/mqtt_exemplo-1.0 CC="x86_64-openwrt-linux-musl-gcc" CFLAGS="-Os -pipe -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro" LDFLAGS="-L/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/staging_dir/target-x86_64_musl/usr/lib -L/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/staging_dir/target-x86_64_musl/lib -L/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/staging_dir/toolchain-x86_64_gcc-7.3.0_musl/usr/lib -L/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/staging_dir/toolchain-x86_64_gcc-7.3.0_musl/lib -znow -zrelro"
make[3]: Entering directory '/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/build_dir/target-x86_64_musl/mqtt_exemplo-1.0'
x86_64-openwrt-linux-musl-gcc -L/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/staging_dir/target-x86_64_musl/usr/lib -L/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/staging_dir/target-x86_64_musl/lib -L/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/staging_dir/toolchain-x86_64_gcc-7.3.0_musl/usr/lib -L/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/staging_dir/toolchain-x86_64_gcc-7.3.0_musl/lib -znow -zrelro mqtt_exemplo.o -o mqtt_exemplo
mqtt_exemplo.o: In function `publish':
**mqtt_exemplo.c:(.text+0x53): undefined reference to `MQTTClient_publishMessage'**
**mqtt_exemplo.c:(.text+0x65): undefined reference to `MQTTClient_waitForCompletion'**
**mqtt_exemplo.o: In function `on_message':**
**mqtt_exemplo.c:(.text+0xac): undefined reference to `MQTTClient_freeMessage'**
**mqtt_exemplo.c:(.text+0xb5): undefined reference to `MQTTClient_free'**
**mqtt_exemplo.o: In function `main':**
**mqtt_exemplo.c:(.text.startup+0x2f): undefined reference to `MQTTClient_create'**
**mqtt_exemplo.c:(.text.startup+0x48): undefined reference to `MQTTClient_setCallbacks'**
**mqtt_exemplo.c:(.text.startup+0x58): undefined reference to `MQTTClient_connect'**
**mqtt_exemplo.c:(.text.startup+0x88): undefined reference to `MQTTClient_subscribe'**
**collect2: error: ld returned 1 exit status**
**make[3]: *** [<builtin>: mqtt_exemplo] Error 1**
make[3]: Leaving directory '/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/build_dir/target-x86_64_musl/mqtt_exemplo-1.0'
make[2]: *** [Makefile:54: /home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/build_dir/target-x86_64_musl/mqtt_exemplo-1.0/.built] Error 2
make[2]: Leaving directory '/home/joao/Documents/myStuff/energiasolar.pt/dev/espt_packages/examples/mqtt_exemplo'
time: package/feeds/espt_packages/mqtt_exemplo/compile#0.09#0.02#0.11
make[1]: *** [package/Makefile:109: package/feeds/espt_packages/mqtt_exemplo/compile] Error 2
make[1]: Leaving directory '/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt'
make: *** [/home/joao/Documents/myStuff/energiasolar.pt/dev/openwrt/include/toplevel.mk:218: package/mqtt_exemplo/compile] Error 2
+++ This is my makefile:
include $(TOPDIR)/rules.mk
#. Name, version and release number
#. The name and version of your package are used to define the variable to point to the build directory of your package: $(PKG_BUILD_DIR)
PKG_NAME:=mqtt_exemplo
PKG_VERSION:=1.0
PKG_RELEASE:=1
#. Source settings (i.e. where to find the source codes)
#. This is a custom variable, used below
SOURCE_DIR:=/home/joao/Documents/myStuff/energiasolar.pt/dev/mqtt_exemplo
include $(INCLUDE_DIR)/package.mk
#. Package definition; instructs on how and where our package will appear in the overall configuration menu ('make menuconfig')
define Package/mqtt_exemplo
SECTION:=examples
CATEGORY:=Examples
DEPENDS:=libpaho-mqtt3c
TITLE:=exemplo de MQTT client
endef
#. Package description; a more verbose description on what our package does
define Package/mqtt_exemplo/description
A simple "mqtt client" -application.
endef
#. Package preparation instructions; create the build directory and copy the source code.
#. The last command is necessary to ensure our preparation instructions remain compatible with the patching system.
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
cp $(SOURCE_DIR)/* $(PKG_BUILD_DIR)
$(Build/Patch)
endef
#. Package build instructions; invoke the GNU make tool to build our package
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) \
CC="$(TARGET_CC)" \
CFLAGS="$(TARGET_CFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS)"
endef
#. Package install instructions; create a directory inside the package to hold our executable, and then copy the executable we built previously into the folder
define Package/mqtt_exemplo/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mqtt_exemplo $(1)/usr/bin
endef
#. This command is always the last, it uses the definitions and variables we give above in order to get the job done
$(eval $(call BuildPackage,mqtt_exemplo))
-- This is my program "mqtt_example.c"
/*
*. Includes
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <MQTTClient.h>
/*
*. Defines
*/
/* Caso desejar utilizar outro broker MQTT, substitua o endereco abaixo */
#define MQTT_ADDRESS "broker.mqttdashboard.com"
/* Substitua este por um ID unico em sua aplicacao */
#define CLIENTID "MQTTCClientID"
/* Substitua aqui os topicos de publish e subscribe por topicos exclusivos de sua aplicacao */
#define MQTT_PUBLISH_TOPIC "MQTTCClientPubTopic"
#define MQTT_SUBSCRIBE_TOPIC "MQTTCClientSubTopic"
/*
*. Variaveis globais
*/
MQTTClient client;
/*
*. Prototipos de funcao
*/
void publish(MQTTClient client, char* topic, char* payload);
int on_message(void *context, char *topicName, int topicLen, MQTTClient_message *message);
/*
*. Implementacoes
*/
/* Funcao: publicacao de mensagens MQTT
*. Parametros: cleinte MQTT, topico MQTT and payload
*. Retorno: nenhum
*/
void publish(MQTTClient client, char* topic, char* payload) {
MQTTClient_message pubmsg = MQTTClient_message_initializer;
pubmsg.payload = payload;
pubmsg.payloadlen = strlen(pubmsg.payload);
pubmsg.qos = 2;
pubmsg.retained = 0;
MQTTClient_deliveryToken token;
MQTTClient_publishMessage(client, topic, &pubmsg, &token);
MQTTClient_waitForCompletion(client, token, 1000L);
}
/* Funcao: callback de mensagens MQTT recebidas e echo para o broker
*. Parametros: contexto, ponteiro para nome do topico da mensagem recebida, tamanho do nome do topico e mensagem recebida
*. Retorno : 1: sucesso (fixo / nao ha checagem de erro neste exemplo)
*/
int on_message(void *context, char *topicName, int topicLen, MQTTClient_message *message) {
char* payload = message->payload;
/* Mostra a mensagem recebida */
printf("Mensagem recebida! \n\rTopico: %s Mensagem: %s\n", topicName, payload);
/* Faz echo da mensagem recebida */
publish(client, MQTT_PUBLISH_TOPIC, payload);
MQTTClient_freeMessage(&message);
MQTTClient_free(topicName);
return 1;
}
int main(int argc, char *argv[])
{
int rc;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
/* Inicializacao do MQTT (conexao & subscribe) */
MQTTClient_create(&client, MQTT_ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
MQTTClient_setCallbacks(client, NULL, NULL, on_message, NULL);
rc = MQTTClient_connect(client, &conn_opts);
if (rc != MQTTCLIENT_SUCCESS)
{
printf("\n\rFalha na conexao ao broker MQTT. Erro: %d\n", rc);
exit(-1);
}
MQTTClient_subscribe(client, MQTT_SUBSCRIBE_TOPIC, 0);
while(1)
{
/*
*. o exemplo opera por "interrupcao" no callback de recepcao de
*. mensagens MQTT. Portanto, neste laco principal eh preciso fazer
*. nada.
*/
}
}
-- This is the makefile for the program "mqtt_example.c" that works in my pc
#. Global target; when 'make' is run without arguments, this is what it should do
all: mqtt_exemplo
#. These variables hold the name of the compilation tool, the compilation flags and the link flags
#. We make use of these variables in the package manifest
CC = gcc
CFLAGS = -lpaho-mqtt3c -Wall
LDFLAGS =
LDLIBS =
#. This variable identifies all header files in the directory; we use it to create a dependency chain between the object files and the source files
#. This approach will re-build your application whenever any header file changes. In a more complex application, such behavior is often undesirable
DEPS = $(wildcard *.h)
#. This variable holds all source files to consider for the build; we use a wildcard to pick all files
SRC = $(wildcard *.c)
#. This variable holds all object file names, constructed from the source file names using pattern substitution
OBJ = $(patsubst %.c, %.o, $(SRC))
#. This rule builds individual object files, and depends on the corresponding C source files and the header files
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
#. To build 'helloworld', we depend on the object files, and link them all into a single executable using the compilation tool
#. We use automatic variables to specify the final executable name 'helloworld', using '$@' and the '$^' will hold the names of all the
#. dependencies of this rule
helloworld: $(OBJ)
$(CC) -o $@ $^ $(LDFLAGS)
#. To clean build artifacts, we specify a 'clean' rule, and use PHONY to indicate that this rule never matches with a potential file in the directory
.PHONY: clean
clean:
rm -f mqtt_exemplo *.o