gcc -Wl,--exclude-libs,<library.a> is not working - gcc

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
$

Related

Why does the definition of makefile not take effect using -D?

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!

Shared library not found in /usr/local/lib

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.

gcc warning different when using --preprocessed

When compiling ltrace with icecc we run into a compilation problem. This is the minimal example:
main.c
#include <assert.h>
int main(int argc, char **argv) {
assert(argc != argc);
return 0;
}
test.sh:
#!/bin/bash
set -x
# one step compilation (no warning)
gcc -Wall main.c
# splitted compilation (warning)
gcc -Wall -E main.c -o main.i
gcc -Wall --preprocessed main.i
output:
++ gcc -Wall main.c
++ gcc -Wall -E main.c -o main.i
++ gcc -Wall --preprocessed main.i
main.c: In function ‘main’:
main.c:4:10: warning: self-comparison always evaluates to false [-Wtautological-compare]
assert(argc != argc);
^~
As you can see the result is different when compiling in one step and when preprocessing and compiling in two steps. Is this intended behavior?
I use gcc 6.3, the issue also appears in gcc 6.2 for ARM. I also cannot ignore this, as the full example uses -Werror.

make: *** [main.o] Error 1

I am executing a simple makefile that contait 3 parts but it does not work well these are details of my files .h and .c:
main.c
#include <stdio.h>
#include <stdlib.h>
#include "hello.h"
int main (void)
{
hello();
return EXIT_SUCCESS;
}
hello.h
#ifndef hello
#define hello
void hello (void);
#endif
hello.c
#include <stdio.h>
#include <stdlib.h>
void hello (void)
{
printf("Hello World\n");
}
makefile
all: hello
hello: hello.o main.o
gcc -o hello hello.o main.o
hello.o: hello.c
gcc -o hello.o -c hello.c -W -Wall -ansi -pedantic
main.o: main.c hello.h
gcc -o main.o -c main.c -W -Wall -ansi -pedantic
clean:
rm -rf *.o
mrproper: clean
rm -rf hello
I get this error:
When you write #define hello you define hello to be an empty token. Thus the function declaration on the next string effectively becomes this:
void (void);
which is not valid C code.
What you are trying to do is probably the Include guard, its purpose is to avoid multiple inclusion of one header. The name of the guard have to differ from any other token you use. Usual naming is FILENAME_H:
#ifndef HELLO_H
#define HELLO_H
void hello(void);
#endif
In hello.h, line 2 you are defining 'hello' as an empty token. Remove that line.

How compiling simple example C using llvm

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!

Resources