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.
Related
how to can i achieve linking 2 .o file without CRT.
Compiling .c files:
gcc -ffreestanding -c file.c -o file.o
Linking:
gcc file1.o file2.o -o f.o
Flags -nostartfiles and -nostdlib don't help me.
I just compile 2 .c file and i want to link their in 1 object file
ld -r -o f.o file1.o file2.o
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
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.
I am trying to use GLEW in a program I'm creating, but my compiler will not compile it, instead it throws a ton of errors at this line gcc -g -c glew.c -o glew.o. This is my Makefile:
MY_LIBS =
glewex: glew.o main.o glew.h
g++ main.o glew.o glew.h -o glewex $(MY_LIBS)
glew.o: glew.c
gcc -g -c glew.c -o glew.o
main.o: main.cpp
g++ -g -c main.cpp -o main.o
It simply outputs hundreds of errors that look like this:
__glewActiveTexture redeclared without dllimport attribute: previous import ignored [ -Wattributes ]
Try this:
gcc -g -DGLEW_STATIC -c glew.c -o glew.o
That should prevent DLL import/export decorations from getting added to the declarations.
You don't want to add the library source files to the compiler input of your project. You should add the library to the list of linker inputs; either statically (libglew.a) or dynamic (-lglew).
I.e. either
gcc -o … -lglew
or
gcc -o … libglew.a
When linking GLEW statically you must add -DGLEW_STATIC to the compiler options generating the compilation units (.o files)
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.