I try to integrate a C library into my project. The custom makefile of this project try to compile all source files, each file into one object file (*.o).
I need to link all of those *.o files into one file, for example so file, for easily to use it. Do I need this ? And if yes, how can I link all of *.o files into one library file. Which lines I will add to Makefile ?
(Notes that, this C library include many sub-directory, and a big makefile will go into all sub directories, and use Makefile in each directory to run it)
Thanks :)
see this is best document.
Lets see i have 2 .o files. ctest1.o ctest2.o
so i will make static library as follows way.
ar -cvq libctest.a ctest1.o ctest2.o
For dynamic .so file
gcc -Wall -fPIC -c *.c
gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o
mv libctest.so.1.0 /opt/lib
ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so.1
ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so
This creates the library libctest.so.1.0 and symbolic links to it.
Related
I'm working on a C project which needs an external open source library.
In particular, it needs a version I patched myself in order to add some needed features.
At the moment I'm using a Makefile which expects a statically compiled version of the patched library inside the ./lib folder (let's call it libpatched.a), and the corresponding header files in ./include/libpatched.
The following are the main parts of the aforementioned Makefile:
EXECNAME=MyExecutable
CC=gcc
SRC_DIR=src
OBJ_DIR=obj
SRC=$(wildcard $(SRC_DIR)/*.c)
OBJ=$(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
CFLAGS += -Wall -O2 -Iinclude -Iinclude/libpatched
LDFLAGS += -Llib
LDLIBS += -lpatched
.PHONY: all clean
all: $(EXECNAME)
$(EXECNAME): $(OBJ_CC)
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
clean:
$(RM) $(OBJ_DIR)/*.o
This Makefile is working correctly; however, I was looking for a more flexible solution, which does not need any statically compiled library before make is called.
What I would like to accomplish is having a Makefile which does something like:
Download a specific version of the original library (in order to never have any compatibility problem)
Apply a patch using patch and a diff file (.patch)
Compile the patched library (either statically or dynamically) for the current platform, using cmake, as required by the original library
Compile my project, using libpatched
Are these steps valid in your opinion, or is there a much better way to handle this need for a patched library?
If yes, as I'm not an expert at all in creating Makefiles, is there an easy way to reach this goal by simply leveraging on a properly written Makefile?
Which could be the best way to do so?
Thank you very much in advance.
I've done exactly this before, when building cross compiler etc with my patches for my operating system kernel. You can use the wget or curl commands in the Makefile. For example something like
# foo.tar.gz needs to be downloaded
foo.tar.gz:
wget https://download.source.from/here/foo.tar.gz -O foo.tar.gz
# the makefile requires the downloaded file.
foo_src/CMakeLists.txt: foo.tar.gz
mkdir -p foo_src
cd foo_src && tar xfz ../foo.tar.gz
# patch the library if flag not present
foo_patched.flag:
cd foo_src && patch -p1 ../foo.patch
touch foo_patched.flag
# this depends on patching
libpatched.a: foo_src/CMakeLists.txt foo_patched.flag
cd foo_src && cmake
cp foo_src/libfoo.a libpatched.a
The Makefile format is very simple - unlike CMake! - the rules just say: "to generate the file on the left, please build the prerequisites on the right side first. Then execute these commands to actually generate the file on the left hand side"
How can i build a c project using makefile that generate intermediate and output files in separate directory other than source?
Current form of my makefile is
CC = g++
LDLIBS = -lm
all: test_makefile
test_makefile: file1.o file2.o file3.o file4.o test_makefile.o
clean:
rm test_makefile *.o
I want to generate these intermediate files in /build directory.
Can anyone help me to modify this make file?
You might want to consider using Automake (https://www.gnu.org/software/automake/) for projects of significant size with separate source and build directories.
Without automake, and considering that by default compilers generate output files in CWD, you can simply create your makefile in the build directory. Here's an example that uses ../ as source directory:
all: foo
foo: ../x.cc
$(CXX) $< -o $#
I have source code in one directory and have a makefile in a different directory. I am able to compile the code using the make system's vpath mechanism. The .o files are being created in the same folder where the makefile is. But I want to move those .o files to a different directory called obj. I tried the following:
vpath %.o obj
However, they are still being created in the same folder as the makefile. Can anyone help me to solve this issue?
Here are some highlighted lines of the makefile:
PATH_TO_OBJ:- ../obj
SRC :- .c files
OBJS :- $(SRC:.c = .o)
.c.o = $(CC) $(CFLAGS) -c
exe: cc $(LFLAGS) -o $(PATH_TO_OBJ) $(SRC).
After this also, .o file is creating in same folder of Makefile. Not moving to obj
-o option defines where to save the output file, produced by a gcc compiler.
gcc main.c -c -o path/to/object/files/main.o
Make's VPATH is only for finding source files. The placement of object files is up to the thing that is building them. There's a nice description at http://mad-scientist.net/make/vpath.html (I see someone beat me to posting this in a comment).
The *BSD build systems use variants of make that can place object files (and other generated files, including C sources from lex and yacc variants) in /usr/obj automatically. If you have access to that version of make, that will likely be a good way to deal with whatever underlying problem you are trying to solve.
I'm trying to write a makefile and I compiled main.c. Then I'm trying to create main.o, but I'm confused as how to do so. I'm using a vi editor in UNIX. I tried gcc -o main.c, I get a fatal error saying that there's no input files. What went wrong?
You can use gcc's -c option to compile a source file without linking. This will leave you with a .o file:
gcc -c main.c
You can then create an executable by linking that .o file with the standard libraries, and other .o or .c files if you like:
gcc -o myprogram main.o
The primary advantage of this is when you have multiple .c files. In that case you can save time by not recompiling them all when one of them changes.
If you are using a Makefile, then you probably have too much in it. Warning: the following will overwrite your Makefile. Try:
echo 'all: main.o' > Makefile
make
or even:
> Makefile # truncate the Makefile. That is, make it empty
make main.o
or even:
rm Makefile
make main.o
Stop working so hard.
I'm trying to compile a C program (myProgram.c) that includes a custom .h file that is in a specified directory. How can I add the directory to gcc so that I can build myProgram.c anytime using just a command like gcc myProgram (with no flags and what not)
You can do this by altering the C_INCLUDE_PATH environment variable, e.g.
C_INCLUDE_PATH=~/include
export C_INCLUDE_PATH
You can add that to your .bashrc or .bash_profile or whatever to always have the environment variable set properly. Here's a reference on how you can do the same for libraries and C++.
had to use a whole set of flags to get this working on El Capitan:
export DYLD_LIBRARY_PATH=/usr/local/include
export CPPFLAGS="-I/usr/local/include/snappy-c.h"
export CFLAGS="-I/usr/local/include/snappy-c.h"
export CXXFLAGS="-I/usr/local/include/snappy-c.h"
export LDFLAGS="-L/usr/local/lib"
Makefiles would be helpful in this situation, they ease the compilation of multiple file projects.
Assuming you are using these same files and they are in the same directory
main.c
custom.c
custom.h
A sample makefile could look like
all: main.o custom.o
gcc main.o custom.o -o myExecutable
main.o: main.c
gcc -c main.c
custom.o: custom.c custom.h
gcc -c custom.c
clean:
rm -f *.o myExecutable
Or something similar, the general format is
name: dependency
command
So by running make all from the commandline you would be instructing the compiler to compile your source code into object files, and then link those object files together into an executable.
Make should be easily available on any modern system. For more information on basic makefiles and usage refer to this simple tutorial: http://mrbook.org/tutorials/make/