Similar questions got asked a lot, but I still don't quite get what's wrong with how I compiled and installed my shared library.
As far as compiling goes I do
> gcc -c -fPIC libt.c
> gcc -shared -Wl,-soname,libt.so.0 -o libt.so.0.1 libt.o
In order to install the library I run
> cp libt.so.0.1 /usr/local/lib/
> cp libt.h /usr/local/include/
> ln -s /usr/local/lib/libt.so.0.1 /usr/local/lib/libt.so.0 # ldconfig would setup this symlink itself ...
> ln -s /usr/local/lib/libt.so.0 /usr/local/lib/libt.so # ... but not this one, so I do it myself
> sudo ldconfig
/usr/local/lib is included in /etc/ld.so.conf.d/libc.conf, and ldconfig -p | grep libt yields
libt.so.0 (libc6,x86-64) => /usr/local/lib/libt.so.0
libt.so (libc6,x86-64) => /usr/local/lib/libt.so
So, as far as I can tell, everything looks okay until this point. However, compiling a program that's supposed to use my library fails:
> gcc -o prog main.c -llibt
/usr/bin/ld: cannot find -llibt
libt.h
#ifndef libt_h__
#define libt_h__
extern int add(int, int);
#endif
libt.c
int
add(int a, int b)
{
return a + b;
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "libt.h"
void
print_usage()
{
printf("usage: ./prog <number a> <number b>\n");
}
int
main(int argc, char *argv[])
{
int a = 0, b = 0, c = 0;
if (argc != 3) {
print_usage();
return 1;
}
a = atoi(argv[1]);
b = atoi(argv[2]);
c = add(a, b);
printf("%d\n", c);
return 0;
}
Figured it out. While library names have to be prefixed with "lib", that prefix must not be specified when linking. That is, gcc -o prog main.c -llibt is wrong while gcc -o prog main.c -lt works as expected.
Related
I wrote a simple c++ code. I wanted to choose to execute one of the codes through the -D option of makefile, but it didn't execute? For example, code1 and code2.
1.main.cpp
#include "./common.h"
#include "./ns_api.h"
int TestFunc3(void)
{
}
int test = 10;
int main(int argv, char **argc)
{
extern int b;
int a = b;
printf("This is a test!\n");
#ifdef TEST_ADD
printf("test_add!\n"); //code1
#endif
#if TEST_SUB
printf("test_sub!\n"); //code2
#endif
return 0;
}
int b;
2.makefile
root#cat makefile
GPP = g++
CFLAGS += -O3
objects = *.o
src = *.cpp
test:$(objects)
$(GPP) $(CFLAGS) -o test $(objects)
$(objects):$(src)
$(GPP) -c $(src)
.PHONY:clean
clean:
rm test *.o
3.compile
root#make CFLAGS=-DTEST_ADD CFLAGS+=-DTEST_SUB=1
g++ -c *.cpp
g++ -DTEST_ADD -DTEST_SUB=1 -o test *.o
4.result:
root#./test
This is a test!
I am trying to make my first C++ app with embedded Dart VM. I have a problem with minimal setup of compiler on my MacOS 10.14.6. My build is successful, but when I start the app, it crashed with:
$ clang++ -I ${HOME}/opt/dart-sdk --define-macro DART_SHARED_LIB=1 -L ./libs/debug -ldart_jit -lm -lz -O2 -undefined dynamic_lookup -o reproduce *.cpp
$ ./reproduce
dyld: Symbol not found: __ZN4dart13FLAG_profilerE
Although symbol __ZN4dart13FLAG_profilerE presents inside binary
$ nm reproduce | grep __ZN4dart13FLAG_profilerE
U __ZN4dart13FLAG_profilerE
How to compile/link this properly?
My reproduce program is:
#include <iostream>
#include <include/dart_api.h>
int main(int argc, const char * argv[]) {
char* setVMFlagsError = Dart_SetVMFlags(argc, argv);
if (setVMFlagsError != nullptr) {
std::cerr << "Error while set Dart VM flags: " << setVMFlagsError << "\n";
::free(setVMFlagsError);
return 1;
} else {
Dart_InitializeParams params = {};
std::cout << "Hello, World!\n";
return 0;
}
}
Dart SDK was built following by official documentation
(dart-sdk-pyenv) ~/tmp/dart-sdk/sdk $ ./tools/build.py --mode all --arch x64 create_sdk
(dart-sdk-pyenv) ~/tmp/dart-sdk/sdk $ cp -a ~/tmp/dart-sdk/sdk/xcodebuild/DebugX64/dart-sdk ~/opt/
Where is my mistake? How is good compiling?
llvm-gcc p.c -S -emit-llvm
lli p.s
lli: p.s:1:2: error: expected top-level entity
.file "p.c"
^
simple code
cat p.c
#include <stdio.h>
int main()
{
printf("Hello World!\n");
}
Those flags will produce a file name p.ll not p.s. Therefore:
[2:24pm][wlynch#watermelon /tmp] llvm-gcc p.c -S -emit-llvm
[2:25pm][wlynch#watermelon /tmp] ~/Homebrew/opt/llvm/bin/lli p.ll
Hello World!
Im using gcc on Linux and creating a shared library for static libraries. I dont want symbols from some static libraries to be exported.
gcc version is 4.8.0.
Im trying this option at gcc command and it's not working:
-Wl,--exclude-libs,libabc.a .
If I use this option, it's removing all the symbols which not what I want.:
-Wl,--exclude-libs,ALL
Can somebody help in how to use --exclude-option and not to export symbols from specific static library, please?
Thanks
Chandra
Please ignore my comment to question, it is incorrect.
Minimal example:
test1.c:
int testvar1;
int test1(void) {
return 1;
}
test2.c:
extern int testvar1;
int test1(void);
int test2(void) {
testvar1 = -1;
return test1() + 2;
}
test.c:
#include <stdio.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
void *lib = dlopen("./libtest2.so", RTLD_NOW);
int (*f)(void) = dlsym(lib, "test2");
printf("%d\n", f());
return 0;
}
Build:
$ gcc -fPIC -c test1.c
$ ar cru libtest1.a test1.o
$ gcc -fPIC -c test2.c
$ gcc -shared -o libtest2.so test2.o -L. -ltest1 -Wl,--exclude-libs,libtest1.a
$ gcc test.c -ldl
$ ./a.out
3
$ readelf --syms -D libtest2.so | grep test1
$
This is my try:
CMD file:
#SET PATH=%PATH%;D:\mingw\bin
type test10.cpp | g++ -xc++ -o test10.exe
code (irrelevant here): int main() {}
error I get:
g++: fatal error: no input files
compilation terminated.
I thought that the -x option is for signalizing stdin input, gcc itself said me that.
The -x option specifies the input language, but it doesn't tell g++ to read from stdin. To do that, you can pass a single dash as a file name.
type test10.cpp | g++ -o test10.exe -x c++ -
you can use here doc in the interactive shell.
for example:
gcc -x c - <<eof
#include <stdio.h>
void foo()
{
int a = 10;
static int sa = 10;
a += 5;
sa += 5;
printf("a = %d, sa = %d\n", a, sa);
}
int main()
{
int i;
for (i = 0; i < 10; ++i)
foo();
}
eof
reference