I'm trying to split the source of an external I'm writing to more than one .c files but I'm failing. I have two .h and two .c files, where one pair includes all the Pd specific functions, line new() and setup(). In the Makefile (pd-lib-builder), I include the following line:
``` common.sources = src/dense.c ``` This is the .c file where I want to include part of the code. The object compiles. I even get some warnings about this dense.c file, but when I try to load the object, Pd complains that it can't find certain functions that are included in this dense.c file.
Hi,
can you post a link to the repository? Then we don't need to guess :)
Christof
On 06.08.2024 13:31, Alexandros Drymonitis wrote:
I'm trying to split the source of an external I'm writing to more than one .c files but I'm failing. I have two .h and two .c files, where one pair includes all the Pd specific functions, line new() and setup(). In the Makefile (pd-lib-builder), I include the following line:
common.sources = src/dense.c
This is the .c file where I want to include part of the code. The object compiles. I even get some warnings about this dense.c file, but when I try to load the object, Pd complains that it can't find certain functions that are included in this dense.c file.
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
It's not in a repo yet, it's on my laptop only. What I'm doing is pass a 2D pointer (if I'm allowed to say this :) ) of t_float and a pointer to a data structure. The actual data live in the main file. Here's a reduced example:
In the dense.h file:
``` typedef struct _layer_dense { // some variables here } t_layer_dense;
In the dense.c file:
``` void layer_dense_forward(t_layer_dense *layer, t_float **data) { \ process data from layer data structure and the "data" pointer } ```
In the main header file:
``` #include dense.h
typedef struct _layer { t_layer_dense *layer_dense; t_float **data; } t_layer; ```
In the main .c file:
``` layer_dense_forward(&layer_dense, data); ```
Initially, the function in the dense.c file was declared as static, which is when Pd couldn't find it. I removed the static keyword, and now Pd just can't create the object, without providing any more information, even at log level 3 or 4.
On 8/6/24 14:34, Christof Ressi wrote:
Hi,
can you post a link to the repository? Then we don't need to guess :)
Christof
On 06.08.2024 13:31, Alexandros Drymonitis wrote:
I'm trying to split the source of an external I'm writing to more than one .c files but I'm failing. I have two .h and two .c files, where one pair includes all the Pd specific functions, line new() and setup(). In the Makefile (pd-lib-builder), I include the following line:
common.sources = src/dense.c
This is the .c file where I want to include part of the code. The object compiles. I even get some warnings about this dense.c file, but when I try to load the object, Pd complains that it can't find certain functions that are included in this dense.c file.
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
What warnings do you get when you compile?
On 06.08.2024 13:46, Alexandros Drymonitis wrote:
It's not in a repo yet, it's on my laptop only. What I'm doing is pass a 2D pointer (if I'm allowed to say this :) ) of t_float and a pointer to a data structure. The actual data live in the main file. Here's a reduced example:
In the dense.h file:
typedef struct _layer_dense { // some variables here } t_layer_dense; In the dense.c file:
void layer_dense_forward(t_layer_dense *layer, t_float **data) { \ process data from layer data structure and the "data" pointer }
In the main header file:
#include dense.h
typedef struct _layer { t_layer_dense *layer_dense; t_float **data; } t_layer;
In the main .c file:
layer_dense_forward(&layer_dense, data);
Initially, the function in the dense.c file was declared as static, which is when Pd couldn't find it. I removed the static keyword, and now Pd just can't create the object, without providing any more information, even at log level 3 or 4. On 8/6/24 14:34, Christof Ressi wrote: > Hi, > > can you post a link to the repository? Then we don't need to guess :) > > Christof > > On 06.08.2024 13:31, Alexandros Drymonitis wrote: >> I'm trying to split the source of an external I'm writing to more >> than one .c files but I'm failing. I have two .h and two .c files, >> where one pair includes all the Pd specific functions, line new() >> and setup(). In the Makefile (pd-lib-builder), I include the >> following line: >> >> ``` >> common.sources = src/dense.c >> ``` >> This is the .c file where I want to include part of the code. The >> object compiles. I even get some warnings about this dense.c file, >> but when I try to load the object, Pd complains that it can't find >> certain functions that are included in this dense.c file. >> >> >> >> >> _______________________________________________ >> Pd-dev mailing list >> Pd-dev@lists.iem.at >> https://lists.puredata.info/listinfo/pd-dev > > > > _______________________________________________ > Pd-dev mailing list > Pd-dev@lists.iem.at > https://lists.puredata.info/listinfo/pd-dev _______________________________________________ Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
On 8/6/24 14:34, Christof Ressi wrote:
Hi,
can you post a link to the repository? Then we don't need to guess :)
+1
Am 6. August 2024 13:46:46 MESZ schrieb Alexandros Drymonitis adrcki@gmail.com:
It's not in a repo yet, it's on my laptop only.
-1
Without seeing your full code, it's really only guesswork. Please push your full code or paste it to some pastebin or simply attach it.
A repo is highly recommended
mfg.sfg.jfd IOhannes
On 8/6/24 23:21, IOhannes m zmölnig wrote:
On 8/6/24 14:34, Christof Ressi wrote:
Hi,
can you post a link to the repository? Then we don't need to guess :)
+1
Am 6. August 2024 13:46:46 MESZ schrieb Alexandros Drymonitis adrcki@gmail.com:
It's not in a repo yet, it's on my laptop only.
-1
You're both right, sorry for not providing one from the start. Here it is: https://github.com/alexdrymonitis/neuralnet/tree/develop
For now I've included three functions in the dense.c file as a test. I want to include more, but I can't even make these three to work.
Actually, now I get a compile error, saying that there are multiple definitions of these three functions, but I really can't see where these are, since these are only defined in the dense.h and dense.c files.
On 8/7/24 08:46, Alexandros Drymonitis wrote:
On 8/6/24 23:21, IOhannes m zmölnig wrote:
On 8/6/24 14:34, Christof Ressi wrote:
Hi,
can you post a link to the repository? Then we don't need to guess :)
+1
Am 6. August 2024 13:46:46 MESZ schrieb Alexandros Drymonitis adrcki@gmail.com:
It's not in a repo yet, it's on my laptop only.
-1
You're both right, sorry for not providing one from the start. Here it is: https://github.com/alexdrymonitis/neuralnet/tree/develop
For now I've included three functions in the dense.c file as a test. I want to include more, but I can't even make these three to work.
On 8/7/24 07:50, Alexandros Drymonitis wrote:
On 8/7/24 08:46, Alexandros Drymonitis wrote:
You're both right, sorry for not providing one from the start. Here it is: https://github.com/alexdrymonitis/neuralnet/tree/develop
thanks.
Actually, now I get a compile error, saying that there are multiple definitions of these three functions, but I really can't see where these are, since these are only defined in the dense.h and dense.c files.
the root of your problem is, that the Makefile tries to link the 'dense.o' objectfile **twice** into the final neuralnet.pd_linux
``` ++++ info: linking objects in neuralnet.pd_linux for lib neuralnet cc -rdynamic -shared -fPIC -Wl,-rpath,"$ORIGIN",--enable-new-dtags -o neuralnet.pd_linux neuralnet.pd_linux.o dense.pd_linux.o dense.pd_linux.o -lc -lm ```
since the dense.o objectfile holds a single definition of "dropout_forward" (and friends), linking it twice results in a duplicate definition, thus leading to the error (the linker does not try to detect duplicate object files).
the cause for this problem is, that you added the header-file 'dense.h' to the "common.sources". while a header file is arguably a "source" file, pd-lib-builder assumes that sources are files **to be compiled**. this is a common dichotomy: https://stackoverflow.com/questions/3482948
so removing the dense.h file from your "sources" fixes the problem.
apart from that:
conceptually 'common.sources' is for source-files that are common to all objects within a library. if you want to just split the sources for a single object, you can instead use "<object>.class.sources", e.g.:
```diff iff --git a/Makefile b/Makefile index 88a8168..8edf8c5 100755 --- a/Makefile +++ b/Makefile @@ -2,9 +2,7 @@
lib.name = neuralnet
-class.sources = neuralnet.c - -common.sources = dense.h dense.c +neuralnet.class.sources = neuralnet.c dense.c
datafiles = neuralnet-help.pd README.md ```
now your "library" is a single-object lib, where there's little difference. but if you think of any additional (helper) object that might become part of your library (turning it into a multi-object lib), and such an additional object won't need dense.c, you probably should go with *.class.sources
you *really* should pay attention to the compiler warnings. there are a couple of implicit pointer casts from (t_atom*) to (t_float*). a modern compiler (e.g. gcc-14), will simply refuse to build such code. unfortunately, there are a couple of warnings that are hard (or impossible) to get rid-of, to the signal to noise ratio is quite high. it typically helps a lot when suppressing warnings about unused thingies (by adding "suppress-wunused=1" to your make invocation) there's also the "cast-function-type" warning, which you cannot practically fix for registering callbacks (e.g. in "class_new" or "class_addmethod")
some includes (rnn.h, embedded.h) are missing from the repository (or the README should mention which dependencies you need to install). (i'm rather old-school and prefer to build code that I need to review)
your Makefile marked is executable, but doesn't define a shebang. examples/map.pd is also (wrongly) marked as executable.
gmasdr IOhannes
That worked, thanks! I changed the makefile and added the missing .h files too (sorry for that...). I also took care of all the warning massages, now the object compiles without any warnings.
Thanks for the help
P.S. How to mark examples/map.pd as a non-executable?
On 8/7/24 11:35, IOhannes m zmoelnig wrote:
On 8/7/24 07:50, Alexandros Drymonitis wrote:
On 8/7/24 08:46, Alexandros Drymonitis wrote:
You're both right, sorry for not providing one from the start. Here it is: https://github.com/alexdrymonitis/neuralnet/tree/develop
thanks.
Actually, now I get a compile error, saying that there are multiple definitions of these three functions, but I really can't see where these are, since these are only defined in the dense.h and dense.c files.
the root of your problem is, that the Makefile tries to link the 'dense.o' objectfile **twice** into the final neuralnet.pd_linux
++++ info: linking objects in neuralnet.pd_linux for lib neuralnet cc -rdynamic -shared -fPIC -Wl,-rpath,"\$ORIGIN",--enable-new-dtags -o neuralnet.pd_linux neuralnet.pd_linux.o dense.pd_linux.o dense.pd_linux.o -lc -lm
since the dense.o objectfile holds a single definition of "dropout_forward" (and friends), linking it twice results in a duplicate definition, thus leading to the error (the linker does not try to detect duplicate object files).
the cause for this problem is, that you added the header-file 'dense.h' to the "common.sources". while a header file is arguably a "source" file, pd-lib-builder assumes that sources are files **to be compiled**. this is a common dichotomy: https://stackoverflow.com/questions/3482948
so removing the dense.h file from your "sources" fixes the problem.
apart from that:
conceptually 'common.sources' is for source-files that are common to all objects within a library. if you want to just split the sources for a single object, you can instead use "<object>.class.sources", e.g.:
iff --git a/Makefile b/Makefile index 88a8168..8edf8c5 100755 --- a/Makefile +++ b/Makefile @@ -2,9 +2,7 @@ lib.name = neuralnet -class.sources = neuralnet.c - -common.sources = dense.h dense.c +neuralnet.class.sources = neuralnet.c dense.c datafiles = neuralnet-help.pd README.md
now your "library" is a single-object lib, where there's little difference. but if you think of any additional (helper) object that might become part of your library (turning it into a multi-object lib), and such an additional object won't need dense.c, you probably should go with *.class.sources
you *really* should pay attention to the compiler warnings. there are a couple of implicit pointer casts from (t_atom*) to (t_float*). a modern compiler (e.g. gcc-14), will simply refuse to build such code. unfortunately, there are a couple of warnings that are hard (or impossible) to get rid-of, to the signal to noise ratio is quite high. it typically helps a lot when suppressing warnings about unused thingies (by adding "suppress-wunused=1" to your make invocation) there's also the "cast-function-type" warning, which you cannot practically fix for registering callbacks (e.g. in "class_new" or "class_addmethod")
some includes (rnn.h, embedded.h) are missing from the repository (or the README should mention which dependencies you need to install). (i'm rather old-school and prefer to build code that I need to review)
your Makefile marked is executable, but doesn't define a shebang. examples/map.pd is also (wrongly) marked as executable.
gmasdr IOhannes
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev