问题
I asked this question a while back: How to make C library installable with angle brackets as <mylib.h> on Mac. I am trying to do the same sort of thing, but don't exactly remember all the details / I'm not sure if I'm doing it right.
So I have a production example working, but it seems like things aren't organized right (even though it seems to be compiling and running properly). My question is, how can I clean this up and remove some duplication and remove anything unnecessary?
So here is my Makefile
:
C_OPTS := -shared -fpic -O2 \
-lssl -lcrypto -lboost_system \
-lboost_thread-mt -lboost_chrono-mt \
-std=c99 -lncurses
c/macos:
@cp src/bundle.h \
/usr/local/include/foo.h
@mkdir -p /usr/local/include/foo
@cp src/client.h \
/usr/local/include/foo
@cp src/cursor.h \
/usr/local/include/foo
@clang $(C_OPTS) \
-install_name libfoo.dylib \
-o build/libfoo.dylib \
src/client.c \
src/cursor.c \
src/bundle.c
@cp build/libfoo.dylib \
/usr/local/lib
@clang test/bundle.c \
-lfoo -o build/foo.o
@./build/foo.o
.PHONY: c/macos
What I do here is essentially, copy all of the header files from my local project to the global /usr/local/include/foo
, so it ends up like this:
/usr/local/include
/foo.h
/foo
/client.h
/cursor.h
Notice how I am doing this file copying before doing the clang
compilation step. I kept on getting errors of either Undefined symbols for architecture x86_64
or fatal error: 'client.h' file not found
, depending on the small adjustments made to this system to try and get it to work. So the only thing I could do to get it to work was to actually copy all the header files to /usr/local/include
. I don't feel like this is right.... Shouldn't I just be able to copy only the foo.h
to /usr/local/include/foo.h
, and somehow the other 2+ header files are just compiled into the dylib
or something? I don't know how this is supposed to work, or if it's common practice to copy the multiple (nested) header files to the global path like this.
The reason I am doing this step is so I can include it like #include <foo.h>
.
So after the file copying step, I compile the libfoo.dylib
with clang
. At one point in this process I was able to only have to pass it the "main" "top level" file src/bundle.c
. But after figuring out that copying the headers works, I had to pass all of the files to the clang
command as input. So instead of this:
@clang $(C_OPTS) \
-install_name libfoo.dylib \
-o build/libfoo.dylib \
src/bundle.c
I have to do this:
@clang $(C_OPTS) \
-install_name libfoo.dylib \
-o build/libfoo.dylib \
src/client.c \
src/cursor.c \
src/bundle.c
Is that the right way to be doing this? If not, how should it be? Is there a way to make it so I only have to pass it the top-level src/bundle.c
?
So now, src/bundle.c
looks like this:
#include "bundle.h"
#include "client.h"
#include "cursor.h"
And I had to do this seemingly hack in src/bundle.h
to get it to work:
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "foo/client.h"
#include "foo/cursor.h"
That is presumably because it is actually loading the header files from the global folder I made just before doing the clang
compilation step. But this smells, something is not right. I feel like it should be like this:
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "client.h"
#include "cursor.h"
Combine that with this, and it seems like it should work, but it doesn't....
@clang $(C_OPTS) \
-install_name libfoo.dylib \
-o build/libfoo.dylib \
src/bundle.c
Why isn't that working?
Finally, I have another file, test/bundle.c
, which I use to verify things are working. I compile it in the last step:
@clang test/bundle.c \
-lfoo -o build/foo.o
It works with this current setup. That test/bundle.c
looks like this:
#include <foo.h>
int
main() {
some_function();
return 0;
}
In one configuration I had of all these files and headers and everything, I kept on getting the warning implicit declaration of function 'some_function' is invalid in C99
, even though in foo.h
and foo.c
it was defined. I don't understand why it wasn't working before. I understand why it's working now, but again, my main concern is this #include
architecture, and the way things are being compiled and link, smells bad. Something seems wrong. How do I clean it up and make the files better organized, while getting rid of all those errors?
来源:https://stackoverflow.com/questions/59021186/how-to-properly-organize-multiple-c-and-h-files-in-different-directories-so-i