warmcat / libwebsockets

canonical libwebsockets.org networking library
https://libwebsockets.org
Other
4.77k stars 1.49k forks source link

wanted to add my own API's to library #2526

Closed madhanreddy433 closed 2 years ago

madhanreddy433 commented 2 years ago

Hi All, I am new to CMAKE, I want to add new folder to libwebsocket and it includes some .c files without main(). I want to merge these APIs also to the libwebsocket library. Could anyone please help me to change the CMakeLists.txt files to do this?

Madhan

lws-team commented 2 years ago

What kind of functionality is it? A new protocol? or core apis, misc helpers, network related? They should all go in different places.

madhanreddy433 commented 2 years ago

it is like a client code, we are using LWS to connect NATS-client to NATS-Server. we wrote this code by invoking LWS library and built it and running it as a process. . ├── CMakeLists.txt ├── ws_client.h └── WS_NATS_client.c ------ contains core lws APIs and our own APIs to establish a connection

we wrote our own CMakeLists.txt to built a binary of WS_NATS_client.

Now the requirement is we need to change the main() inside WS_NATS_client.c to ws_main() and then add this file to LWS library. so that we can invoke this entire new library in another process to use the APIs.

madhanreddy433 commented 2 years ago

. ├── cmake ├── include │   └── libwebsockets │   └── abstract │   ├── protocols │   └── transports ├── lib │   ├── abstract │   │   ├── protocols │   │   │   └── smtp │   │   └── transports │   ├── core │   ├── core-net │   │   └── client │   ├── cose │   ├── drivers │   │   ├── button │   │   ├── devices │   │   │   └── display │   │   ├── display │   │   ├── i2c │   │   │   └── bitbang │   │   ├── led │   │   ├── netdev │   │   ├── pwm │   │   ├── settings │   │   └── spi │   │   └── bitbang │   ├── event-libs │   │   ├── glib │   │   ├── libev │   │   ├── libevent │   │   ├── libuv │   │   ├── poll │   │   ├── sdevent │   │   └── uloop │   ├── jose │   │   ├── jwe │   │   │   └── enc │   │   ├── jwk │   │   └── jws │   ├── misc │   │   ├── cache-ttl │   │   ├── fts │   │   ├── lwsac │   │   └── threadpool │   ├── plat │   │   ├── freertos │   │   │   └── esp32 │   │   │   └── drivers │   │   │   └── netdev │   │   ├── optee │   │   ├── unix │   │   │   └── android │   │   └── windows │   ├── roles │   │   ├── cgi │   │   ├── dbus │   │   ├── h1 │   │   ├── h2 │   │   ├── http │   │   │   ├── client │   │   │   ├── compression │   │   │   │   ├── brotli │   │   │   │   └── deflate │   │   │   └── server │   │   ├── listen │   │   ├── mqtt │   │   │   └── client │   │   ├── netlink │   │   ├── pipe │   │   ├── raw-file │   │   ├── raw-proxy │   │   ├── raw-skt │   │   └── ws │   │   └── ext │   ├── secure-streams │   │   ├── cpp │   │   ├── plugins │   │   │   └── ssp-h1url │   │   ├── protocols │   │   └── system │   │   ├── auth-api.amazon.com │   │   ├── auth-sigv4 │   │   ├── captive-portal-detect │   │   └── fetch-policy │   ├── system │   │   ├── async-dns │   │   ├── dhcpclient │   │   ├── fault-injection │   │   ├── metrics │   │   ├── ntpclient │   │   └── smd │   └── tls │   ├── mbedtls │   │   └── wrapper │   │   ├── include │   │   │   ├── internal │   │   │   ├── openssl │   │   │   └── platform │   │   ├── library │   │   └── platform │   └── openssl └── ws-client

lws-team commented 2 years ago

There is no "ws_main()" in lws... I assume that is also in some other code of your own.

What you're talking about isn't very maintainable, it might be better to make your apis in their own library, which links to lws to resolve what it needs.

If you are sure you want to do it by hacking your stuff into lws itself, you can just add a dir in ./lib like ./lib/myapis.

There are two approaches to bringing it into the build, one is keep your CMakeLists.txt and in ./lib/CMakeLists.txt, just do add_subdirectory(myapis). This will make the lws build refer to your CMakeLists.txt to do the actual build. The other, probably better way for this is don't bring your CMakeLists.txt in, and don't try to tell the lws one to use it. Instead, just hack in your source file as part of the core lib build, by adding myapis/WS_NATS_client.c here

https://libwebsockets.org/git/libwebsockets/tree/lib/core/CMakeLists.txt#n28

it's not very beautiful but it should build it in.

By default, in lws all exports are private, you have to mark up apis as explicitly public to export them. Copy this kind of declaration to export the new api symbols you care about and make them available to the consumer app.

https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-misc.h#n70-71

madhanreddy433 commented 2 years ago

I have added myapis at ./lib/core/myapis and modified core/CMakeLists.txt like below to add my files to lib

if (LWS_RUCKUS_ICX) list(APPEND SOURCES core/ws-client/WS_NATS_client.c) endif()

I have added this option LWS_RUCKUS_ICX in main CMakeLists.txt and default it to ON. Now my file is building, I am seeing the corresponding .o files.

[mr1154@l42-icx-linux-23 messaging]$ find . -name "WS_NATS_client.c.o" ./WS-cross-compiled-arm/WS/build/lib/CMakeFiles/websockets.dir/core/ws-client/WS_NATS_client.c.o ./WS-cross-compiled-arm/WS/build/lib/CMakeFiles/websockets_shared.dir/core/ws-client/WS_NATS_client.c.o [mr1154@l42-icx-linux-23 messaging]$

now to test it I have created a simple main() program and invoked my api by extern

include

extern int ws_main(int argc, char argv); int main(int argc, char argv) { ws_main(argc, argv); return 0; }

compiled by passing library with -l option, getting below error [mr1154@l42-icx-linux-23 lib]$ ./compile_ws_client.sh /tmp/ccV8WR6j.o: In function main': ws-client.c:(.text+0x1c): undefined reference tows_main' collect2: error: ld returned 1 exit status

how do I invoke my api's to my program, extern is not working, do I need to include any .h file ?

lws-team commented 2 years ago

... okay... but where is ws_main() defined? It is in WS_NATS_client.c ?

If so, you must export it as I described above

By default, in lws all exports are private, you have to mark up apis as explicitly public to export them. Copy this kind of declaration to export the new api symbols you care about and make them available to the consumer app.

https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-misc.h#n70-71

madhanreddy433 commented 2 years ago

Thank you so much it is working fine now but I have defined many APIs in myaps, do I need to export all same way? or is it possible to declare all those apis in one .h file include it in my program?

instead of adding my directory inside ./lib/core/ and modifying its core/CMakeLists.txt, if I want to add my directory in ./lib or outside ./lib like I have shown you the hierarchy in above and then I will call add_subdirectory(myapis), in this case how do I write my own CMakeLists.txt?

could you please give me any reference or pointers to write my own CMakeLists.txt?

lws-team commented 2 years ago

You must export the ones you want to be visible from the app that wants to use the hacked lws library. You can just copy paste your existing header and mark up all the functions you want to export with LWS_VISIBLE LWS_EXTERN.

You can make your own ./include/libwebsockets/lws-myapis.h and put everything in there rather than abusing lws-misc.h, you must add a #include for it from ./include/libwebsockets.h somewhere. Doing it like that, the application only needs to #include <libwebsockets.h> (assuming it is your hacked version it is looking at) and it will also have all of myapi declarations available too.

With cmake, directory structure inside the project matters less than the calling hierarchy of add_subdirectory(), so it doesn't make much difference where you put it. However you will want to bring it in from ./lib/CMakeLists.txt, Source cwd there is ./lib, so if you make ./myapis/CMakeLists.txt, you will want add_subdirectory(../myapis) in ./lib/CMakeLists.txt.

Your CMakeLists.txt is not like a standalone one, it's a small spur of the larger lws build. Lws already figured out the compiler build options, the build targets and everything else. Your CMakeLists.txt just needs to look like

list(APPEND SOURCES
        ../myapis/mysource1.c
        ../myapis/mysource2.c)

SOURCES will be iterated through eventually from ./lib cwd. So paths should be relative to that

lws-team commented 2 years ago

... also in your CMakeLists.txt, make sure to put

exports_to_parent_scope()

at the end. This makes anything lws uses that you modifed visible at the parent add_subdirectory() level. Otherwise your changes will be lost at your child level.

madhanreddy433 commented 2 years ago

below is my directory structure [mr1154@l42-icx-linux-23 WS]$ ls cmake CMakeLists.txt include lib Makefile.projbuild myapis CMakeLists-implied-options.txt component.mk Kconfig LICENSE websocket.sh

I have added myapis directory outside lib, did below changes in CMakeLists.txt files

./CMakeLists.txt if (LWS_RUCKUS_ICX) add_subdirectory(myapis) endif()

./lib/CMakeLists.txt -- no change

./myapis/CMakeLists.txt if(LWS_RUCKUS_ICX) list(APPEND SOURCES myapis/WS_NATS_client.c) exports_to_parent_scope() else()

it is compiling but my files are not including in it, I didn't see corresponding .o's for my files

instead of including my directory from ./CMakeLists.txt I did it from ./lib/CMakeLists.txt like below if (LWS_RUCKUS_ICX) add_subdirectory(../myapis) endif()

I am getting below error CMake Error at lib/CMakeLists.txt:37 (add_subdirectory): add_subdirectory not given a binary directory but the given source directory "/users/home/mr1154/git.clones/nats-debug/ap_scg_common/services/messaging/WS-cross-compiled-arm/WS/ws-client" is not a subdirectory of "/users/home/mr1154/git.clones/nats-debug/ap_scg_common/services/messaging/WS-cross-compiled-arm/WS/lib". When specifying an out-of-tree source a binary directory must be explicitly specified.

am I doing anything wrong? I wanted to keep my directory "myapis" outside ./lib

lws-team commented 2 years ago

Looks like add_subdirectory(../myapis myapis) might be enough.