How to create a shared library (.so) file in Mac os X using terminal - macos

How to create a shared library (.so) file in Mac os X using terminal
Thanks in Advance.

This might be very late, but incase someone stumbles upon this I know how to make an so files for c++/c code. Assuming that you are in the directory with your .cpp/.c and .h files, in the terminal you must type:
g++ -c file1.cpp file2.cpp (add as many cpp/c files you want in the so file)
g++ *.o -dynamiclib -o lib_name.so
Then if you are using a cpp file that will run it:
g++ -c test.cpp -o test.o (compiling the program to see if the shared library works)
g++ -o test test.o -L. -l_name (create an executable to run)
./test (run the test)
For C code so files, it's the same but replace g++ with gcc.

Related

How to link different object file with LLVM library?

I am following the LLVM tutorial : Kaleidoscope: Code generation to LLVM IR, which will use LLVM libraries like LLVMContext, Module and so on. Different from the tutorial, I am trying to write the lexer, parser and code generator in different source file and link them into one executable file.
Here is my compile command on the Ubuntu 20.04:
clang++ -g -O3 -I /home/therlf/LLVM/include -I ./ -I /home/therlf/LLVM_Temp/llvm/include `llvm-config --cxxflags --ldflags --system-libs --libs all` ast/CallExprAST.o ast/NumberExprAST.o ast/PrototypeAST.o ast/FunctionAST.o ast/BinaryExprAST.o ast/VariableExprAST.o lexer/lexer.o logger/logger.o parser/parser.o main.cpp -o main
But I only get lots of "undefined error".
Here are some of them:
/usr/bin/ld: /tmp/main-2b71c8.o:(.data+0x0): undefined reference to `llvm::DisableABIBreakingChecks
/home/therlf/MyProject/tmp/ast/CallExprAST.cpp:6: undefined reference to `llvm::Module::getFunction(llvm::StringRef) const'
/home/therlf/LLVM/include/llvm/IR/InstrTypes.h:1112: undefined reference to `llvm::Instruction::Instruction(llvm::Type*, unsigned int, llvm::Use*, unsigned int, llvm::Instruction*)'
/usr/bin/ld: /home/therlf/LLVM/include/llvm/IR/InstrTypes.h:977: undefined reference to `llvm::VectorType::get(llvm::Type*, llvm::ElementCount)'
At first I thought it's including path's error. But when I compiled and ran the source file in the tutorial successfully, which is just a whole source file with everything packed into file, I knew the including path is nothing wrong.
I have searched for this question, and some blogs say that you should link them with lld and use the -fuse-ld=lld in the compile command. But I don't have lld, and the clang++ doesn't know the argument -fuse-ld, which will report an error. The blog says that you should have lld as long as you have installed LLVM. In fact here are what I got: LLVM tools
And I know the llvm-link is used to link IR file, not the object file compiled from cpp source file.
Here is my LLVM version:
10.0.0svn
And here is my Makefile:
SOURCES = $(shell find ast kaleidoscope lexer logger parser -name '*.cpp')
HEADERS = $(shell find ast kaleidoscope lexer logger parser -name '*.h')
OBJ = ${SOURCES:.cpp=.o}
CC = clang++
# -stdlib=libc++ -std=c++11
CFLAGS = -g -O3 -I /home/therlf/LLVM/include -I ./ -I /home/therlf/LLVM_Temp/llvm/include
LLVMFLAGS = `llvm-config --cxxflags --ldflags --system-libs --libs all`
.PHONY: main
main: main.cpp ${OBJ}
${CC} ${CFLAGS} ${LLVMFLAGS} ${OBJ} $< -o $#
clean:
rm -r ${OBJ}
%.o: %.cpp ${HEADERS}
${CC} ${CFLAGS} ${LLVMFLAGS} -c $< -o $#
In fact, I follow the project structure from the repository : ghaiklor/llvm-kaleidoscope and the Makefile is nearly identical.
Sincerely thank you for your answers!
I have sloved this problem by exchanging my linker ld with linker lld.
You should install lld first by this command in ubuntu if you can't find it in the LLVM/tools directory like I did.
sudo apt-get update
sudo apt-get -y install lld
And then you can add -fuse-ld=lld to your compile command
or you can
cd /usr/bin
ln -s /path/to/ld.lld /usr/bin/ld
This should work if everything goes well.
But I still can't figure out the reason behand this situation :-(

How does cygwin terminal work? (Makefile issue)

Here's my makefile:
assemblera: main.o parsingA.o parsingC.o symbolTable.o
gcc -o assemblera main.o parsingA.o parsingC.o symbolTable.o
main.o: main.c parsingA.h parsingC.h symbolTable.h
gcc -c main.c
parsingA.o: parsingA.c parsingA.h
gcc -c parsingA.c
parsingC.o: parsingC.c parsingC.h
gcc -c parsingC.c
symbolTable.o: symbolTable.c symbolTable.h
gcc -c symbolTable.c
clean:
rm *.o assemblera
Now for the problem: with Windows command prompt I can easily generate all the .o files and .exe file, and if I run the latter it works as intended. Now, if I use the cygwin terminal, I can give the instructions to generate the object files / the exe, but those do not appear nowhere in the folder and no error is returned. Also, if I use the make command, it returns this error:
gcc -c main.c
make: *** [Makefile:5: main.o] Error 1
(I did put tabs in front of every "gcc" and "rm"). I know next to nothing about makefiles and cygwin.

Creating .o file with make

I'm trying to learn how to write makefiles. I have started reading the manual of gnu make: https://www.gnu.org/software/make/manual/html_node/Simple-Makefile.html#Simple-Makefile
I have 3 files in the same directory:
main.cpp: which creates a rectangle and prints some information. Therefor it includes Rectangle.h
Rectangle.h: header file for rectangle class
Rectangle.cpp: implementation of rectangle class
I am having troubles with the include of Rectangle.h in main.cpp. My makefile is:
main: main.o rectangle.o
g++ -o main.exe main.o rectangle.o
main.o: main.cpp
g++ main.cpp
rectangle.o: Rectangle.cpp
g++ Rectangle.cpp
clean:
rm main.exe main.o rectangle.o
I know something is missing to create main.o but I can't find out what it is. I tried adding various variations of Rectangle.h/.o/.cpp and finding something on the internet but I was unable to find something.
Help will be much appreciated :)
PS: The code is fine, I can compile it with the command:
g++ -o main.exe main.cpp Rectangle.cpp
man g++
When you invoke GCC, it normally does preprocessing, compilation, assembly and linking. The "overall options" allow you to stop this process at an intermediate stage. For example, the -c option says not to run the linker. Then the output consists of object files output by the assembler.

gcc -pg creates a.out instead of gmon.out

How can I make my gcc -pg create a gmon.out file instead of an a.out? I'm trying to profile my CPU using gprof, but when I compile my .c file I get an a.out, which is not what I need.
The profile is generated when you run the compiled program, not upon compilation.
$ gcc -pg yourfile.c #compile with -pg
$ ./a.out #execute it
Now, you can see the gmon.out file.

is it possible to create an object file from other object files in gcc?

I was trying to do something like this in a makefile:
program.exe: ui.o main.o
gcc ......etc
ui.o: window1.o window2.o
gcc -c window1.o window2.o -o ui.o #this doesn't want to work
window1.o: window1.c window1.h window1_events.c window1_controls.c ...
gcc -c window1.c window1_events.c window1_controls.c... -o window1.o
window2.o: ...
gcc ...
main.o: ...
gcc ...
but when I compile like this, it gives the error "input file unused because linking not done," and then I get a bunch of unresolved externs, etc--problems which are resolved by changing
program.exe: ui.o main.o
gcc ...
to
program.exe: window1.o window2.o main.o
gcc ...
so is it possible to just link object files together, to avoid having mile-long lines in a makefile and break down the build process a little more?
Yes: to merge several object files into one, use ld -r or ld -Ur:
From "man ld" on Linux:
-r
--relocatable
Generate relocatable output---i.e., generate an output file that can
in turn serve as input to ld. This is often called partial linking.
As a side effect, in environments that support standard Unix magic
numbers, this option also sets the output file’s magic number to
"OMAGIC".
If this option is not specified, an absolute file is produced.
When linking C++ programs, this option will not resolve references to
constructors; to do that, use -Ur.
You could also do this with gcc:
gcc -Wl,-r foo.o bar.o -o foobar.o -nostdlib
Merging object files like this has some advantages over using an archive library: if merged files change very infrequently (compared to say main.c), your final executable links will be faster.
OTOH, with archived library, the linker will only use what it needs, so your executable may end up being smaller if e.g. window2.c ends up not being necessary.
I bunch of object files is a library. You can create a library with the ar
utility. The following example creates a library called mylib.a containing the files foo.o and bar.o
ar rvs mylib.a foo.o bar.o
You can then link with it by using it on the compiler command line:
gcc -o myexe main.c mylib.a
To create a library:
ar rvs somelib.a file1.o file2.o file3.o
To link it:
gcc -o program.exe file4.o somelib.a

Resources