g++ and boost linker error on Ubuntu oneiric - boost

I am getting the following errors after an upgrade. I cannot figure what is wrong with it. It should work as far as I can see.
$ make 2>&1 | head
g++ -o prog -ansi -O2 -Wall -I/usr/include/boost -L/usr/lib -lboost_program_options -lboost_thread -lstdc++ ./YYY.o ./main.o ./myClass.o
./YYY.o: In function `void boost::call_once<void (*)()>(boost::once_flag&, void (*)())':
YYY.cc:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[void boost::call_once<void (*)()>(boost::once_flag&, void (*)())]+0x14): undefined reference to `boost::detail::get_once_per_thread_epoch()'
YYY.cc:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[void boost::call_once<void (*)()>(boost::once_flag&, void (*)())]+0x2c): undefined reference to `boost::detail::once_epoch_mutex'
YYY.cc:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[void boost::call_once<void (*)()>(boost::once_flag&, void (*)())]+0x62): undefined reference to `boost::detail::once_epoch_mutex'
YYY.cc:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[void boost::call_once<void (*)()>(boost::once_flag&, void (*)())]+0x67): undefined reference to `boost::detail::once_epoch_cv'
YYY.cc:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[void boost::call_once<void (*)()>(boost::once_flag&, void (*)())]+0x95): undefined reference to `boost::detail::once_epoch_mutex'
YYY.cc:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[void boost::call_once<void (*)()>(boost::once_flag&, void (*)())]+0xa9): undefined reference to `boost::detail::once_epoch_mutex'
YYY.cc:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[void boost::call_once<void (*)()>(boost::once_flag&, void (*)())]+0xbd): undefined reference to `boost::detail::once_global_epoch'
YYY.cc:(.text._ZN5boost9call_onceIPFvvEEEvRNS_9once_flagET_[void boost::call_once<void (*)()>(boost::once_flag&, void (*)())]+0xc2): undefined reference to `boost::detail::once_epoch_cv'
$ ls -l /usr/lib/*boost_threa*
0 lrwxrwxrwx 1 root root 17 Jun 3 22:30 /usr/lib/libboost_thread-mt.a -> libboost_thread.a
0 lrwxrwxrwx 1 root root 25 Jun 3 22:30 /usr/lib/libboost_thread-mt.so -> libboost_thread.so.1.46.1
208K -rw-r--r-- 1 root root 208K Jun 3 22:30 /usr/lib/libboost_thread.a
0 lrwxrwxrwx 1 root root 25 Jun 3 22:30 /usr/lib/libboost_thread.so -> libboost_thread.so.1.46.1
88K -rw-r--r-- 1 root root 87K Oct 21 2010 /usr/lib/libboost_thread.so.1.42.0
100K -rw-r--r-- 1 root root 99K Jun 3 22:30 /usr/lib/libboost_thread.so.1.46.1
$ ls -ld /usr/include/boost/*thread*
4.0K drwxr-xr-x 5 root root 4.0K Oct 13 21:59 /usr/include/boost/thread/
4.0K -rw-r--r-- 1 root root 839 Jun 3 22:18 /usr/include/boost/thread.hpp

The solution involved changing the order of linkage, as per the man page. The thing is that it used to work fine with an older version of g++...
$ make
g++ -I/usr/include/boost -MM ./YYY.cc ./main.cc ./myClass.cc > buildfiles.d
g++ -ansi -O2 -Wall -I/usr/include/boost -c -o main.o main.cc
g++ -ansi -O2 -Wall -I/usr/include/boost -c -o myClass.o myClass.cc
g++ -o prog -ansi -O2 -Wall -I/usr/include/boost ./YYY.o ./main.o ./myClass.o -lstdc++ -L/usr/lib -lboost_program_options -lboost_thread

Related

Not able to compile with gcc using -m32

amar#pc:/local/mnt/workspace/amarn$ gcc -m32 a.c
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc.a when searching for -lgcc
/usr/bin/ld: cannot find -lgcc
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc_s.so when searching for -lgcc_s
/usr/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
amar#pc:/local/mnt/workspace/amarn$ cat a.c
#include <stdio.h>
int
main ()
{
long z;
printf("Long int size is %d bytes long!\n", sizeof(z));
;
return 0;
}
amarn#hyd-tbsbld01:/local/mnt/workspace/amarn$ uname -a
Linux mypc 4.4.0-78-generic #99-Ubuntu SMP Thu Apr 27 15:29:09 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
I made following change for gcc.
gcc was mapped to gcc-5.
I mapped gcc to gcc-4.8.
amar#mypc:/usr/bin$ ll | grep gcc
-rwxr-xr-x 1 root root 428 May 7 2006 c89-gcc
-rwxr-xr-x 1 root root 454 Apr 11 2011 c99-gcc
lrwxrwxrwx 1 root root 7 Jun 1 11:54 gcc -> gcc-4.8
-rwxr-xr-x 1 root root 776344 Jan 26 2016 gcc-4.8
-rwxr-xr-x 1 root root 915736 Nov 3 2016 gcc-5
lrwxrwxrwx 1 root root 10 Jun 1 11:55 gcc-ar -> gcc-ar-4.8
-rwxr-xr-x 1 root root 27032 Jan 26 2016 gcc-ar-4.8
-rwxr-xr-x 1 root root 31136 Nov 3 2016 gcc-ar-5
lrwxrwxrwx 1 root root 10 Jun 1 11:56 gcc-nm -> gcc-nm-4.8
-rwxr-xr-x 1 root root 27032 Jan 26 2016 gcc-nm-4.8
-rwxr-xr-x 1 root root 31136 Nov 3 2016 gcc-nm-5
lrwxrwxrwx 1 root root 14 Jun 1 11:56 gcc-ranlib -> gcc-ranlib-4.8
-rwxr-xr-x 1 root root 27032 Jan 26 2016 gcc-ranlib-4.8
-rwxr-xr-x 1 root root 31136 Nov 3 2016 gcc-ranlib-5
lrwxrwxrwx 1 root root 7 Jun 1 12:32 x86_64-linux-gnu-gcc -> gcc-4.8
lrwxrwxrwx 1 root root 7 Jan 26 2016 x86_64-linux-gnu-gcc-4.8 -> gcc-4.8
lrwxrwxrwx 1 root root 5 Nov 3 2016 x86_64-linux-gnu-gcc-5 -> gcc-5
lrwxrwxrwx 1 root root 10 Jun 1 12:34 x86_64-linux-gnu-gcc-ar -> gcc-ar-4.8
lrwxrwxrwx 1 root root 10 Jan 26 2016 x86_64-linux-gnu-gcc-ar-4.8 -> gcc-ar-4.8
lrwxrwxrwx 1 root root 8 Nov 3 2016 x86_64-linux-gnu-gcc-ar-5 -> gcc-ar-5
lrwxrwxrwx 1 root root 10 Jun 1 12:34 x86_64-linux-gnu-gcc-nm -> gcc-nm-4.8
lrwxrwxrwx 1 root root 10 Jan 26 2016 x86_64-linux-gnu-gcc-nm-4.8 -> gcc-nm-4.8
lrwxrwxrwx 1 root root 8 Nov 3 2016 x86_64-linux-gnu-gcc-nm-5 -> gcc-nm-5
lrwxrwxrwx 1 root root 14 Jun 1 12:35 x86_64-linux-gnu-gcc-ranlib -> gcc-ranlib-4.8
lrwxrwxrwx 1 root root 14 Jan 26 2016 x86_64-linux-gnu-gcc-ranlib-4.8 -> gcc-ranlib-4.8
lrwxrwxrwx 1 root root 12 Nov 3 2016 x86_64-linux-gnu-gcc-ranlib-5 -> gcc-ranlib-5

Installing tree-1.6.0 in cygwin. What am I missing?

I am trying to install tree 1.6.0 in my cygwin console. To do that, I downloaded the source.
Here is the content of the file
===> ls -lh
total 269K
-rw-r--r-- 1 user None 8.8K Jun 24 2011 CHANGES
-rw-r--r-- 1 user None 16K Jun 22 2011 color.c
-rw-r--r-- 1 user None 17K Apr 14 11:35 color.o
drwxr-xr-x+ 1 user None 0 Apr 14 11:35 doc
-rw-r--r-- 1 user None 3.1K Jun 24 2011 hash.c
-rw-r--r-- 1 user None 2.4K Apr 14 11:35 hash.o
-rw-r--r-- 1 user None 15K Jun 24 2011 html.c
-rw-r--r-- 1 user None 21K Apr 14 11:35 html.o
-rw-r--r-- 1 user None 596 Jun 24 2011 INSTALL
-rw-r--r-- 1 user None 18K Aug 12 2004 LICENSE
-rw-r--r-- 1 user None 2.6K Jun 24 2011 Makefile
-rw-r--r-- 1 user None 4.6K Jun 24 2011 README
-rw-r--r-- 1 user None 5.2K Aug 27 2008 strverscmp.c
-rw-r--r-- 1 user None 2.2K Jun 24 2011 TODO
-rw-r--r-- 1 user None 31K Jun 24 2011 tree.c
-rw-r--r-- 1 user None 5.0K Jun 24 2011 tree.h
-rw-r--r-- 1 user None 37K Apr 14 11:35 tree.o
-rw-r--r-- 1 user None 7.4K Jun 22 2011 unix.c
-rw-r--r-- 1 user None 11K Apr 14 11:35 unix.o
-rw-r--r-- 1 user None 8.7K Jun 24 2011 xml.c
-rw-r--r-- 1 user None 13K Apr 14 11:35 xml.o
When I run make, the following is what I get:
===> make
gcc -O4 -Wall -DLINUX -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -c -o tree.o tree.c
tree.c: In function ‘main’:
tree.c:481:7: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 3 has type ‘off_t’ [-Wformat=]
if (duflag) fprintf(outfile," <size>%lld</size>\n", size);
^
tree.c:481:7: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 3 has type ‘off_t’ [-Wformat=]
tree.c: In function ‘versort’:
tree.c:782:5: warning: implicit declaration of function ‘strverscmp’ [-Wimplicit-function-declaration]
if ((*a)->isdir == (*b)->isdir) return strverscmp((*a)->name,(*b)->name);
^
tree.c: In function ‘psize’:
tree.c:1107:3: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 3 has type ‘off_t’ [-Wformat=]
} else return sprintf(buf, sizeof(off_t) == sizeof(long long)? " %11lld" : " %9ld", size);
^
tree.c:1107:3: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 3 has type ‘off_t’ [-Wformat=]
gcc -O4 -Wall -DLINUX -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -c -o unix.o unix.c
gcc -O4 -Wall -DLINUX -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -c -o html.o html.c
gcc -O4 -Wall -DLINUX -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -c -o xml.o xml.c
xml.c: In function ‘xml_fillinfo’:
xml.c:301:3: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 3 has type ‘ off_t’ [-Wformat=]
if (sflag) fprintf(outfile, " size=\"%lld\"", ent->size);
^
xml.c:301:3: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 3 has type ‘ off_t’ [-Wformat=]
gcc -O4 -Wall -DLINUX -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -c -o hash.o hash.c
gcc -O4 -Wall -DLINUX -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -c -o color.o color.c
gcc -s -o tree tree.o unix.o html.o xml.o hash.o color.o
tree.o:tree.c:(.text+0x1ba): undefined reference to `strverscmp'
tree.o:tree.c:(.text+0x1ba): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `strve rscmp'
/usr/bin/ld: tree.o: bad reloc address 0x0 in section `.data'
/usr/bin/ld: final link failed: Invalid operation
collect2: error: ld returned 1 exit status
Makefile:86: recipe for target 'tree' failed
make: *** [tree] Error 1
What is wrong and how can I fix this?
You should follow the instructions in the document INSTALL, in the top level of the distribution directory. In particular the first step:
1. Edit the Makefile for your OS.

When I include a static library "libupnpx.a" in my project that is 6 MB, does this make my app 6 MB larger?

I have heard the compiler strips out unused code. But when I include a libupnpx.a static library archive of 6 MB, will this make app 6 MB larger? Or is this same as including the library source code directly?
The answer is not as simple as you may think:
Let's do an experiment:
We will create a libfoo.a with the following structure:
Makefile:
LIBOUT=libfoo.a
SRC=foo1.c foo2.c foo3.c
OBJ=$(SRC:%.c=%.o)
default: test1 test2 test3
test1: $(LIBOUT)
$(CC) -o $# test1.c -L. -lfoo
test2: $(LIBOUT)
$(CC) -o $# test2.c -L. -lfoo
test3: $(LIBOUT)
$(CC) -o $# test3.c -L. -lfoo
$(LIBOUT): $(OBJ)
$(AR) ruv $(LIBOUT) $(OBJ)
foo1.c:
#include <stdio.h>
int foo1_service_a() {
printf("Performing foo1_service_a\n");
return 0;
}
foo2.c:
#include <stdio.h>
int foo2_service_a() {
printf("Performing foo2_service_a\n");
return 0;
}
foo3.c:
#include <stdio.h>
int foo3_service_a() {
printf("Performing foo3_service_a\n");
return 0;
}
int foo3_service_b() {
printf("Performing foo3_service_b\n");
return 0;
}
And three test programs:
test1.c:
int main() {
foo1_service_a();
return 0;
}
test2.c:
int main() {
foo2_service_a();
return 0;
}
test3.c:
int main() {
foo3_service_a();
return 0;
}
When we compile them we get:
-rw-r--r-- 1 masud users 285 Aug 3 16:42 Makefile
-rw-r--r-- 1 masud users 96 Aug 3 16:38 foo1.c
-rw-r--r-- 1 masud users 1496 Aug 3 16:39 foo1.o
-rw-r--r-- 1 masud users 97 Aug 3 16:39 foo2.c
-rw-r--r-- 1 masud users 1496 Aug 3 16:39 foo2.o
-rw-r--r-- 1 masud users 173 Aug 3 16:39 foo3.c
-rw-r--r-- 1 masud users 1688 Aug 3 16:40 foo3.o
-rw-r--r-- 1 masud users 5008 Aug 3 16:40 libfoo.a
-rwxr-xr-x 1 masud users 9132 Aug 3 16:43 test1
-rw-r--r-- 1 masud users 45 Aug 3 16:43 test1.c
-rwxr-xr-x 1 masud users 9132 Aug 3 16:43 test2
-rw-r--r-- 1 masud users 45 Aug 3 16:43 test2.c
-rwxr-xr-x 1 masud users 9251 Aug 3 16:43 test3
-rw-r--r-- 1 masud users 45 Aug 3 16:43 test3.c
As you can tell that each of test1 test2 and test3 have foo1.o; foo2.o and foo3.o dictating their end sizes.
So it's the archive's content division that determines the size of the end binary.
Exercise for the reader
What happens to the sizes when you strip the binaries? do test1 test2 and test3 become the same size?
Why or why not ? :)
You can generally expect that static linking and "including the library source code directly" will have equivalent impacts on the size of the resulting executable. There are be some minor cases in which this may not be strictly true, but generally speaking, they should be approximately equivalent.

Make unnecessarily recompiles a target

Firstly, here's my Makefile, it's really, really cool.
It generates an executable for every 'c' file in the current directory.
Trivial with shell, PITA with Make... Did I mention, I haven't 'c'd in a decade so please don't laugh...
CC = gcc
#List all 'c' files by wildcard.
SOURCES=$(wildcard *.c)
#Get the 'exe' equivalent of said file
EXECUTABLES=$(SOURCES:%.c=%)
#For each of the '*.exe' files
#append a 'c' suffix to the target
build: $(EXECUTABLES)
$(CC) -c $(<:%=%.c) -o $<
clean:
find ./ ! -name "*.c" -a ! -name "Makefile" -type f -delete
rebuild: clean build
Here are contents of my directory:
% ls -la
total 32
drwxr-xr-x 2 yomom yomom 4096 2012-01-27 13:38 ./
drwx------ 94 yomom yomom 4096 2012-01-27 13:38 ../
-rw-r--r-- 1 yomom yomom 990 2012-01-27 12:47 array_example.c
-rw-r--r-- 1 yomom yomom 341 2012-01-27 13:38 Makefile
-rw-r--r-- 1 yomom yomom 430 2011-12-05 13:08 pointers.c
-rw-r--r-- 1 yomom yomom 319 2012-01-27 12:45 should_create_warning.c
-rw-r--r-- 1 yomom yomom 1472 2011-12-19 16:16 socket-client.c
-rw-r--r-- 1 yomom yomom 1150 2011-12-19 16:15 socket-server.c
Now I run make
% make
gcc array_example.c -o array_example
gcc pointers.c -o pointers
gcc should_create_warning.c -o should_create_warning
gcc socket-client.c -o socket-client
gcc socket-server.c -o socket-server
gcc -c array_example.c -o array_example
Great, it re-compiled everything, the last line of output looked a bit inconsistent though.
How come it's different to the others?
% ls -la
total 68
drwxr-xr-x 2 yomom yomom 4096 2012-01-27 13:38 ./
drwx------ 94 yomom yomom 4096 2012-01-27 13:38 ../
-rw-r--r-- 1 yomom yomom 1428 2012-01-27 13:38 array_example
-rw-r--r-- 1 yomom yomom 990 2012-01-27 12:47 array_example.c
-rw-r--r-- 1 yomom yomom 341 2012-01-27 13:38 Makefile
-rwxr-xr-x 1 yomom yomom 7164 2012-01-27 13:38 pointers*
-rw-r--r-- 1 yomom yomom 430 2011-12-05 13:08 pointers.c
-rwxr-xr-x 1 yomom yomom 7139 2012-01-27 13:38 should_create_warning*
-rw-r--r-- 1 yomom yomom 319 2012-01-27 12:45 should_create_warning.c
-rwxr-xr-x 1 yomom yomom 7515 2012-01-27 13:38 socket-client*
-rw-r--r-- 1 yomom yomom 1472 2011-12-19 16:16 socket-client.c
-rwxr-xr-x 1 yomom yomom 7579 2012-01-27 13:38 socket-server*
-rw-r--r-- 1 yomom yomom 1150 2011-12-19 16:15 socket-server.c
I run make again, expecting it to NOP, after all, I haven't changed anything
% make
gcc -c array_example.c -o array_example
But it producted output, what gives ?
% ls -la
total 68
drwxr-xr-x 2 yomom yomom 4096 2012-01-27 13:51 ./
drwx------ 94 yomom yomom 4096 2012-01-27 13:51 ../
-rw-r--r-- 1 yomom yomom 1428 2012-01-27 13:51 array_example
-rw-r--r-- 1 yomom yomom 990 2012-01-27 12:47 array_example.c
-rw-r--r-- 1 yomom yomom 341 2012-01-27 13:38 Makefile
-rwxr-xr-x 1 yomom yomom 7164 2012-01-27 13:38 pointers*
-rw-r--r-- 1 yomom yomom 430 2011-12-05 13:08 pointers.c
-rwxr-xr-x 1 yomom yomom 7139 2012-01-27 13:38 should_create_warning*
-rw-r--r-- 1 yomom yomom 319 2012-01-27 12:45 should_create_warning.c
-rwxr-xr-x 1 yomom yomom 7515 2012-01-27 13:38 socket-client*
-rw-r--r-- 1 yomom yomom 1472 2011-12-19 16:16 socket-client.c
-rwxr-xr-x 1 yomom yomom 7579 2012-01-27 13:38 socket-server*
-rw-r--r-- 1 yomom yomom 1150 2011-12-19 16:15 socket-server.c
And it's re-compiled that array_example file, why always that one?
THE SOLUTION (Thanks to Eldar Abusalimov)
CC = gcc
#List all 'c' files by wildcard.
SOURCES=$(wildcard *.c)
#Get the 'exe' equivalent of said file
EXECUTABLES=$(SOURCES:%.c=%)
all: $(EXECUTABLES)
.PHONY: all
$(EXECUTABLES): % : %.c
$(CC) -c $< -o $#
.PHONY clean:
clean:
find ./ ! -name "*.c" -a ! -name "Makefile" -type f -delete
rebuild: clean all
FINAL SESSION
Remove all generated files
% make clean
find ./ ! -name "*.c" -a ! -name "Makefile" -type f -delete
% ls -la
total 48
drwxr-xr-x 2 yomom yomom 4096 2012-01-27 18:07 ./
drwx------ 94 yomom yomom 4096 2012-01-27 18:07 ../
-rw-r--r-- 1 yomom yomom 990 2012-01-27 17:38 array_example.c
-rw-r--r-- 1 yomom yomom 428 2012-01-27 17:38 array_of_pointers.c
-rw-r--r-- 1 yomom yomom 274 2012-01-27 17:38 const_ptr.c
-rw-r--r-- 1 yomom yomom 293 2012-01-27 17:38 function_pointers.c
-rw-r--r-- 1 yomom yomom 313 2012-01-27 18:06 Makefile
-rw-r--r-- 1 yomom yomom 430 2012-01-27 17:38 pointers.c
-rw-r--r-- 1 yomom yomom 228 2012-01-27 17:38 pointer_to_constant.c
-rw-r--r-- 1 yomom yomom 253 2012-01-27 17:38 pointer_to_pointer.c
-rw-r--r-- 1 yomom yomom 1472 2012-01-27 17:38 socket-client.c
-rw-r--r-- 1 yomom yomom 1150 2012-01-27 17:38 socket-server.c
Run make again
% make
gcc -c array_example.c -o array_example
gcc -c array_of_pointers.c -o array_of_pointers
gcc -c const_ptr.c -o const_ptr
gcc -c function_pointers.c -o function_pointers
gcc -c pointers.c -o pointers
gcc -c pointer_to_constant.c -o pointer_to_constant
gcc -c pointer_to_pointer.c -o pointer_to_pointer
gcc -c socket-client.c -o socket-client
gcc -c socket-server.c -o socket-server
Now it doesn't do silly things anymore...
% make
make: Nothing to be done for `all'.
Just remove the recipe of build: $(EXECUTABLES). First, such rule is not supposed to create a build file. Second, and answering to your question about why only array_example is being always recompiled, $(<:%=%.c) results in the first listed prerequisite, which is likely to be the first one returned by wildcard (which sorts the result in the lexicographical order, not guaranteed, but usually it does). That is,
SOURCES=$(wildcard *.c)# returns 'array_example.c pointers.c ...'.
EXECUTABLES=$(SOURCES:%.c=%)# is 'array_example pointers ...'.
build: $(EXECUTABLES)
# Here '$<' is the first item of '$(EXECUTABLES)', which is 'array_example'.
# And '$(<:%=%.c)' returns 'array_example.c'
$(CC) -c $(<:%=%.c) -o $<
Finally, don't forget to add .PHONY target.
.PHONY: build
build: $(EXECUTABLES)
Make builds all programs listed in $(EXECUTABLES) using an implicit rule to make executables from C sources. There is no need to specify anything else.
In case when the implicit rule is not OK, you can, however, override it, e.g. as follows:
$(EXECUTABLES) : % : %.c
$(CC) -o $# $<

How to build a source code tree using multiple Makefiles

FYI: all work can be seen in the trac repo # http://matthewh.me/scripts/browser/c/shared_library?order=name
The original post was to long. It essentially asked why my Makefiles were not finding any of the source when building from the root directory.
UPDATE:
I did discover that the paths are all relative to the root directory, regardless of where the makefiles are placed.
I have the libs building now, however I am getting an undefined reference to main when compiling the app.
I will not paste the updated makefiles, but the source tree now looks like:
mehoggan#mehoggan-laptop:~/Code/shared_library$ make
gcc -c -o ./c_lib/c_lib.o ./c_lib/c_lib.c
rm -f ./c_lib/libClib.so.1.0.0 ./c_lib/libClib.so ./c_lib/libClib.so.1 ./c_lib/libClib.so.1.0
gcc -m32 -Wl,-O1 -shared -o ./c_lib/libClib.so.1.0.0 -lpthread
ln -s ./libClib.so.1.0.0 ./c_lib/libClib.so
ln -s ./libClib.so.1.0.0 ./c_lib/libClib.so.1
ln -s ./libClib.so.1.0.0 ./c_lib/libClib.so.1.0
rm -f ./c_lib/libClib.a
ar cqs ./c_lib/libClib.a ./c_lib/c_lib.o
cc -c -m32 -pipe -O2 -Wall -W -D_REENTRANT -I./c_lib/ -o ./app/main.o ./app/main.c
gcc -m32 -Wl,-O1 -o ./app/main.o -L./c_lib/ -lClib
/usr/lib/gcc/i486-linux-gnu/4.4.3/../../../../lib/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status
make: *** [app/main] Error 1
mehoggan#mehoggan-laptop:~/Code/shared_library$ ls -lR
.:
total 12
drwxr-xr-x 2 mehoggan mehoggan 4096 2011-11-20 20:23 app
drwxr-xr-x 2 mehoggan mehoggan 4096 2011-11-20 20:23 c_lib
-rw-r--r-- 1 mehoggan mehoggan 824 2011-11-20 19:50 Makefile
./app:
total 8
-rw-r--r-- 1 mehoggan mehoggan 291 2011-11-20 18:52 main.c
-rw-r--r-- 1 mehoggan mehoggan 503 2011-11-20 20:23 Makefile
./c_lib:
total 28
-rw-r--r-- 1 mehoggan mehoggan 245 2011-11-20 18:54 c_lib.c
-rw-r--r-- 1 mehoggan mehoggan 46 2011-11-20 19:53 c_lib.h
-rw-r--r-- 1 mehoggan mehoggan 864 2011-11-20 20:23 c_lib.o
-rw-r--r-- 1 mehoggan mehoggan 1008 2011-11-20 20:23 libClib.a
lrwxrwxrwx 1 mehoggan mehoggan 18 2011-11-20 20:23 libClib.so -> ./libClib.so.1.0.0
lrwxrwxrwx 1 mehoggan mehoggan 18 2011-11-20 20:23 libClib.so.1 -> ./libClib.so.1.0.0
lrwxrwxrwx 1 mehoggan mehoggan 18 2011-11-20 20:23 libClib.so.1.0 -> ./libClib.so.1.0.0
-rwxr-xr-x 1 mehoggan mehoggan 6588 2011-11-20 20:23 libClib.so.1.0.0
-rw-r--r-- 1 mehoggan mehoggan 930 2011-11-20 20:20 Makefile
The contents of main.c are:
#include <stdio.h>
#include "c_lib.h"
int main(int argc, char *argv[])
{
if (argc > 1) {
char *arg = argv[1];
printf("%s\n", arg);
}
char str[12] = "hello world\0";
printf("%s\n", str);
char *rev = reverse(str);
printf("%s\n", rev);
return 1;
}
Why can the compiler not find the main function?
UPDATE
Your fix helped get pass the undefined reference to main, however I am now getting another undefined reference:
[mehoggan#hogganz400 shared_library]$ make
gcc -c -m32 -pipe -O2 -Wall -W -D_REENTRANT -fPIC -I. -o ./c_lib/c_lib.o ./c_lib/c_lib.c
rm -f ./c_lib/libClib.so.1.0.0 ./c_lib/libClib.so ./c_lib/libClib.so.1 ./c_lib/libClib.so.1.0
gcc -m32 -Wl,-O1 -shared -o ./c_lib/libClib.so.1.0.0 -lpthread
ln -s ./libClib.so.1.0.0 ./c_lib/libClib.so
ln -s ./libClib.so.1.0.0 ./c_lib/libClib.so.1
ln -s ./libClib.so.1.0.0 ./c_lib/libClib.so.1.0
rm -f ./c_lib/libClib.a
ar cqs ./c_lib/libClib.a ./c_lib/c_lib.o
gcc -c -m32 -pipe -O2 -Wall -W -D_REENTRANT -I./c_lib/ -o ./app/main.o ./app/main.c
gcc -m32 -Wl,-O1 -o ./app/main -L./c_lib/ -lClib ./app/main.o
./app/main.o: In function `main':
main.c:(.text+0x49): undefined reference to `reverse'
collect2: ld returned 1 exit status
make: *** [app/main] Error 1
Should there be a readable string in the .so file that indicates that reverse is in there?
[mehoggan#hogganz400 shared_library]$ strings ./c_lib/libClib.so.1
__gmon_start__
_init
_fini
__cxa_finalize
_Jv_RegisterClasses
libpthread.so.0
libc.so.6
_edata
__bss_start
_end
GLIBC_2.1.3
gcc -m32 -Wl,-O1 -o ./app/main.o -L./c_lib/ -lClib
You have an error in the variable setting the output file, and the next argument (main.o) is interpreted as the output instead. main.o is thus not loaded and not linked.

Resources