I have file main.c, I want to create main.so.
main.c depends on libCmodel.so file.
main.c looks like
#include <stdio.h>
#include "Cmodel.h" // Must include before Amodel and Bmodel
#include "Amodel.h"
#include "Bmodel.h"
int main(){
..
return 0;
}
It can be observed that, libCmodel.so file depends on libAmodel.so.4 and libBmodelso.11.
All the "*.so" files are present in the same directory as main.c
I used the following command to generate object file
gcc -x c++ -fPIC main.c -o main.o -c -I.
I see that main.o is generated.
But, I am not sure if I have used the correct command. Is the above command correct?
Then, I tried the following commads to generate main.so ,
g++ -shared -o main.so main.o -L. -lCmodel
g++ -shared -o main.so main.o -L. -lCmodel -lAmodel -lBmodel
g++ -shared -o main.so main.o -L. -lCmodel -lAmodel.4 -lBmodel.11
g++ -shared -o main.so main.o -L. -lCmodel -lAmodel.so.4 -lBmodel.so.11
Which one of the above commands is correct?
Please help
The file containing your main function should not be a shared library. It is the entry point for an application, so it should be linked as an executable.
gcc -x c++ -I. -L. -o main main.c -lCmodel
Related
I'm still learning how to set up a Makefile and I'm kind of lost here. I'm using windows and currently trying to fire up my Makefile for small C++ SDL project.
I have 3 .cpp files:
main.cpp
window.cpp
rect.cpp
As well as 2 extra header files:
Window.h
rect.h
So having trouble setting up everything on a Makefile
This is what i currently have:
CXXFLAGS = -Ideps/include -std=c++0x
LXXFLAGS = -Ldeps/lib -lmingw32 -lSDL2main -lSDL2
cup: main.o
g++ main.o -o cup $(LXXFLAGS)
main.o: main.cpp
g++ main.cpp -c $(CXXFLAGS)
window.o: window.cpp
g++ window.cpp -c
rect.o: rect.cpp
g++ rect.cpp -c
But I'm getting a bunch of undefined reference errors for my constructors on my command prompt.
Help please!
From the Makefile contents I read that cup binary is only created from main.o and it does not link window.o nor rect.o, which is where probably those missing references are defined. At the very least I would update the primary rule to say:
cup: main.o window.o rect.o
g++ $(LXXFLAGS) -o cup $^
Thus said, you could make even more use from implicit rules that are built into make, and, if following the standard naming for linking flags, the Makefile could be reduced even further to just a linking line (as compilation rules are implicit), e.g.:
$ cat Makefile
CXXFLAGS = -Ideps/include -std=c++0x
LDFLAGS = -Ldeps/lib
LDLIBS = -lmingw32 -lSDL2main -lSDL2
cup: main.o window.o rect.o
$(LINK.cc) $^ $(LDLIBS) -o $#
Output:
$ make
g++ -Ideps/include -std=c++0x -c -o main.o main.cpp
g++ -Ideps/include -std=c++0x -c -o window.o window.cpp
g++ -Ideps/include -std=c++0x -c -o rect.o rect.cpp
g++ -Ideps/include -std=c++0x -Ldeps/lib main.o window.o rect.o -lmingw32 -lSDL2main -lSDL2 -o cup
So this is my first time making a make file so its really basic. I have 2 cpp files (functions.cpp and main.cpp) and 2 header files (structDeclaration.h and Prototypes.h). It needs to be able to compile my program but if only one file changes then it shouldn't recompile the entire thing.
heres my error:
g++ -c gradebook main.o Functions.o -I.
g++: error: gradebook: No such file or directory
make: *** [gradebook] Error 1
and heres my makefile:
CC = g++
gradebook: main.o Functions.o
g++ -c gradebook main.o Functions.o -I.
main.o: main.cpp Prototypes.h structDeclaration.h Prototypes.h
g++ -c main.cpp
Functions.o: Functions.cpp structDeclaration.h
g++ -c Functions.cpp
the commands have to be valid commands. I think you mean
g++ -o gradebook main.o Functions.o
If in doubt just try typing the command you are asking make to run for you, there is no magic involved here
The project has three files, main.c, file1.c and file2.c
gcc -o main.o -c main.c
gcc -o file1.o -c file1.c
gcc -o file2.o -c file2.c
Method 1, works well
g++ -o main.exe main.o file1.o file2.o
Method 2, failed
ar rv lib.a file1.o file2.o
g++ -o main.exe lib.a main.o
main.c:(.text+0xa): undefined reference to `ini_load'
Anything wrong in the commands? Thx
The position in the command line matters.
When you list a library on the command line, it's used to satisfy unresolved references in existence at that time. From the gcc man-page:
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.
If you change it to:
g++ -o main.exe main.o lib.a
then it should work fine, as all the unresolved references in mian.o will be searched for in the objects within lib.a.
I tried to make a Makefile using files main.cpp, factorial.cpp, hello.cpp and function.h
On typing 'make' on Linux command window, it shows:
g++ -c -o hello main.o factorial.o hello.o
g++: main.o: linker input file unused because linking not done
g++: factorial.o: linker input file unused because linking not done
g++: hello.o: linker input file unused because linking not done
I am making the Makefile for first time. Please give suggestions what can be the problem?
The Makefile contains following code->
hello: main.o factorial.o hello.o
g++ -c -o hello main.o factorial.o hello.o
main.o: main.cpp
g++ -c -o main.o main.cpp
factorial.o: factorial.cpp
g++ -c -o factorial.o factorial.cpp
hello.o: hello.cpp
g++ -c -o hello.o hello.cpp
The individual file contents if you want to see are:
1) main.cpp
#include<iostream>
#include"functions.h"
using namespace std;
int main()
{
print_hello();
cout << endl;
cout << "The factorial of 5 is " << factorial(5) << endl;
return 0;
}
2) hello.cpp
#include<iostream>
#include "functions.h"
using namespace std;
void print_hello()
{
cout << "Hello World!";
}
3) factorial.cpp
#include "functions.h"
int factorial(int n)
{
if(n!=1)
{
return(n * factorial(n-1));
}
else return 1;
}
4) function.h
void print_hello();
int factorial(int n);
The -c parameter to g++ tells it not to link:
-c Compile or assemble the source files, but do not link. The linking stage simply is not done. The ultimate output is in the form of an object file for each source file.
You definitely don't want the -c here:
hello: main.o factorial.o hello.o
g++ -c -o hello main.o factorial.o hello.o
You could also use rules and patterns to make it more generic:
SRC_DIR = ./src
OBJ_DIR = ./bin/obj
BIN_DIR = ./build/bin
# List all the sources
SRCS = A.cpp B.cpp
# Define the rule to make object file from cpp
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp
g++ -o $# $(INCLUDES) $(CPPFLAGS) -c $^
TARGET_BIN = $(BIN_DIR)/test
all : make_dirs $(TARGET_BIN)
$(TARGET_BIN) : $(SRCS:%.cpp=$(OBJ_DIR)/%.o)
g++ $(LDFLAGS) -o $# $^ $(LDLIBS)
make_dirs :
mkdir -p $(OBJ_DIR)
mkdir -p $(BIN_DIR)
With this approach you have several benefits:
Easy to use: you specify source files once, and you don't care about processing of each object file: the job is done by a single rule.
More maintainable: every time you need to change the compiler or linker options you do it in the single rule, not for each translation unit.
You have an error in that line:
g++ -c -o hello main.o factorial.o hello.o
man gcc says: ... the -c option says not to run the linker.
This option is used to produce objects files only. When it passed, gcc will not start linker to produce executable file or shared library.
As clear from all above answers, because of using -c in g++ -c -o hello main.o factorial.o hello.o, it is preventing from linking. After creating the object files from corresponding .cpp or .h etc files, these need to be linked. Without linking, as each file is a part of a complete program that can perform some task, nothing useful can be done as these file are dependent. So, we have to link these dependent parts to run our complete program.
One basic video tutorial for easy learning of making a Makefile in the two methods viz dependencies and pattern rules is here.
It takes example of method of dependencies and then introduce pattern rules as a better approach for making a long Makefile.
To know the difference between compilation and linking, this link can be useful.
HI,
I have an error: undefined reference to EVP_CIPHER_CTX_init'. I have the encryption code in the header.cpp. In header.h i've initialized the method that i use for encryption. i've created an ar lib.a from header.cpp and header.h. i've added the -lcrypto but still when i run the test.cpp code where i've added in the header the header.h and i compile g++ test.cpp -o test -lib.a i have this error. where am i wrong?
the compilation code:
g++ -c -static -L -lb header.cpp -lcrypto -o lib.o
ar rcs lib.a lib.o
g++ test.cpp -o tst libr.a
in the header.h i did include all the libraries necesarry for the openssl/evp.h and so on. In test.cpp i've included header.h file.