LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Thread Tools
Old 10-19-2003, 03:11 AM   #1
Xiangbuilder
Member
 
Registered: Apr 2003
Location: Shandong province China
Distribution: fedora core 1.0
Posts: 206
Thanked: 0
How to compile a tiny simple library by g++?


[Log in to get rid of this advertisement]
I only know use the command g++ filename.cpp -o filename to compile a exetcuable file so far, recently, I want compile a library, the code is from <<thinking in c++>>
Code:
//: C04:CLib.h
// Header file for a C-like library
// An array-like entity created at runtime

typedef struct CStashTag {
  int size;      // Size of each space
  int quantity;  // Number of storage spaces
  int next;      // Next empty space
  // Dynamically allocated array of bytes:
  unsigned char* storage;
} CStash;

void initialize(CStash* s, int size);
void cleanup(CStash* s);
int add(CStash* s, const void* element);
void* fetch(CStash* s, int index);
int count(CStash* s);
void inflate(CStash* s, int increase);
///:~
another file:
Code:
//: C04:CLib.cpp {O}
// Implementation of example C-like library
// Declare structure and functions:
#include "CLib.h"
#include <iostream>
#include <cassert> 
using namespace std;
// Quantity of elements to add
// when increasing storage:
const int increment = 100;

void initialize(CStash* s, int sz) {
  s->size = sz;
  s->quantity = 0;
  s->storage = 0;
  s->next = 0;
}

int add(CStash* s, const void* element) {
  if(s->next >= s->quantity) //Enough space left?
    inflate(s, increment);
  // Copy element into storage,
  // starting at next empty space:
  int startBytes = s->next * s->size;
  unsigned char* e = (unsigned char*)element;
  for(int i = 0; i < s->size; i++)
    s->storage[startBytes + i] = e[i];
  s->next++;
  return(s->next - 1); // Index number
}

void* fetch(CStash* s, int index) {
  // Check index boundaries:
  assert(0 <= index);
  if(index >= s->next)
    return 0; // To indicate the end
  // Produce pointer to desired element:
  return &(s->storage[index * s->size]);
}

int count(CStash* s) {
  return s->next;  // Elements in CStash
}

void inflate(CStash* s, int increase) {
  assert(increase > 0);
  int newQuantity = s->quantity + increase;
  int newBytes = newQuantity * s->size;
  int oldBytes = s->quantity * s->size;
  unsigned char* b = new unsigned char[newBytes];
  for(int i = 0; i < oldBytes; i++)
    b[i] = s->storage[i]; // Copy old to new
  delete [](s->storage); // Old storage
  s->storage = b; // Point to new memory
  s->quantity = newQuantity;
}

void cleanup(CStash* s) {
  if(s->storage != 0) {
   cout << "freeing storage" << endl;
   delete []s->storage;
  }
} ///
What command I should use?
Thank you.

Last edited by Xiangbuilder; 10-19-2003 at 03:13 AM..
Xiangbuilder is offline     Reply With Quote
Old 10-19-2003, 04:17 AM   #2
SaTaN
Member
 
Registered: Aug 2003
Location: Suprisingly in Heaven
Posts: 223
Thanked: 1
I think
Quote:
g++ CLib.cpp -o CLib
would do it for you

You don't have to compile the library again as you have included it
in CLib.cpp

Last edited by SaTaN; 10-19-2003 at 04:19 AM..
SaTaN is offline     Reply With Quote
Old 10-19-2003, 04:45 AM   #3
Xiangbuilder
Member
 
Registered: Apr 2003
Location: Shandong province China
Distribution: fedora core 1.0
Posts: 206
Thanked: 0

Original Poster
We know a c++ program must have an int main function, but there is no in main function in the file. So I guess the files is used to create a library file such as *.lib, Only is my guess, in fact, I don't if g++ can be used to create a linrary or not.
Here is the error information:
Code:
[root@localhost a_a]# g++ CLib.cpp -o CLib
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crt1.o(.text+0x18): In function `_start':
../sysdeps/i386/elf/start.S:77: undefined reference to `main'
collect2: ld returned 1 exit status
[root@localhost a_a]#
Thank you.
Xiangbuilder is offline     Reply With Quote
Old 10-19-2003, 06:15 AM   #4
SaTaN
Member
 
Registered: Aug 2003
Location: Suprisingly in Heaven
Posts: 223
Thanked: 1
Maybe the author wants you to write the main program by yourself using any of the functions mentioned in both CLib.h and CLib.cpp files.
SaTaN is offline     Reply With Quote
Old 10-19-2003, 06:44 AM   #5
Xiangbuilder
Member
 
Registered: Apr 2003
Location: Shandong province China
Distribution: fedora core 1.0
Posts: 206
Thanked: 0

Original Poster
Perhaps.
Thank you.
Xiangbuilder is offline     Reply With Quote
Old 10-19-2003, 11:26 AM   #6
lenlutz
Member
 
Registered: May 2003
Location: philadelhpia pa
Posts: 92
Thanked: 0
i didnt see, the "-c" option,
which is: only make an obj.... not an a.out

ALSO, once done, to make a lib, you use ar... like this:

ar ruv CLib.a CLib.o
(you can remove the .o)
now, you have a linkable module
lenlutz is offline     Reply With Quote
Old 10-19-2003, 10:41 PM   #7
Xiangbuilder
Member
 
Registered: Apr 2003
Location: Shandong province China
Distribution: fedora core 1.0
Posts: 206
Thanked: 0

Original Poster
Code:
[root@localhost a_a]# g++ CLib.cpp -c CLib.o
g++: CLib.o: no such directory or file
However, there is a file Clib.o. After
Code:
ar ruv CLib.a
there is a file Clib.a.
Thank you.
Xiangbuilder is offline     Reply With Quote
Old 10-19-2003, 11:44 PM   #8
dvogel
LQ Newbie
 
Registered: Mar 2003
Posts: 9
Thanked: 0
To create a shared library use

g++ -shared -o <lib name> <cpp files>
dvogel is offline     Reply With Quote
Old 10-20-2003, 05:34 AM   #9
Xiangbuilder
Member
 
Registered: Apr 2003
Location: Shandong province China
Distribution: fedora core 1.0
Posts: 206
Thanked: 0

Original Poster
Thank you.
I find some sentences below in the book: "To test the library, two CStashes are created. The first holds ints and the second holds arrays of 80 chars:"
Code:
//: C04:CLibTest.cpp
//{L} CLib
// Test the C-like library
#include "CLib.h"
#include <fstream>
#include <iostream>
#include <string>
#include <cassert>
using namespace std;

int main() {
  // Define variables at the beginning
  // of the block, as in C:
  CStash intStash, stringStash;
  int i;
  char* cp;
  ifstream in;
  string line;
  const int bufsize = 80;
  // Now remember to initialize the variables:
  initialize(&intStash, sizeof(int));
  for(i = 0; i < 100; i++)
    add(&intStash, &i);
  for(i = 0; i < count(&intStash); i++)
    cout << "fetch(&intStash, " << i << ") = "
         << *(int*)fetch(&intStash, i)
         << endl;
  // Holds 80-character strings:
  initialize(&stringStash, sizeof(char)*bufsize);
  in.open("CLibTest.cpp");
  assert(in);
  while(getline(in, line))
    add(&stringStash, line.c_str());
  i = 0;
  while((cp = (char*)fetch(&stringStash,i++))!=0)
    cout << "fetch(&stringStash, " << i << ") = "
         << cp << endl;
  cleanup(&intStash);
  cleanup(&stringStash);
} ///
How to compile the file and test the library, in other words, what command I should use?
So far, I can successfully compiled the source code by the command
Code:
[root@localhost a_a]# g++ CLibTest.cpp CLib.cpp -o CLibTest
but I want to test the library, how to do?
Thank you.
Xiangbuilder is offline     Reply With Quote
Old 10-20-2003, 09:54 AM   #10
dakensta
Member
 
Registered: Jun 2003
Location: SEUK
Distribution: Debian & OS X
Posts: 194
Thanked: 0
1) g++ -c CLib.cpp

2) ar rcs libCLib.a CLib.o

3) g++ CLibTest.cpp -o CLibTest -L. -lCLib
dakensta is offline     Reply With Quote
Old 10-20-2003, 10:01 AM   #11
mr_segfault
Member
 
Registered: Oct 2003
Location: Australia
Distribution: Redhat 9
Posts: 95
Thanked: 0
To link in your lib:

assuming name and path :
Code:
/usr/local/lib/libMyLib.so
you would use

Code:
g++ CLibTest.cpp -o CLibTest -L/usr/local/lib -lMyLib
Note the -L path is the path to where the libMyLib.so file is, so modify that line to be correct for your lib location.

So if the lib is called libMyLib.so and is located in the same directory as you are compiling in the use

Code:
g++ CLibTest.cpp -o CLibTest -L. -lMyLib
Note: When specifying libraries with the -l flag you leave off the lib and the .so.. ie ( libMyLib.so becomes MyLib ):

Do a:

Code:
man gcc
Hope that helps.

Cheers..
mr_segfault is offline     Reply With Quote
Old 10-20-2003, 10:50 AM   #12
Xiangbuilder
Member
 
Registered: Apr 2003
Location: Shandong province China
Distribution: fedora core 1.0
Posts: 206
Thanked: 0

Original Poster
Thank you.
Code:
[root@localhost a_a]# g++ CLibTest.cpp -o CLibTest -L. -lCLib
/usr/bin/ld: cannot find -lCLib 
collect2: ld returned 1 exit status
[root@localhost a_a]#
but I don't use the -l flag, then can successfully compiled
Code:
[root@localhost a_a]# g++ CLibTest.cpp -o CLibTest -L. CLib.o
I think this is because of my gcc problem perhaps. My guess.
Thank you.
Very helpful to me.

Last edited by Xiangbuilder; 10-20-2003 at 10:52 AM..
Xiangbuilder is offline     Reply With Quote
Old 10-20-2003, 11:46 AM   #13
dakensta
Member
 
Registered: Jun 2003
Location: SEUK
Distribution: Debian & OS X
Posts: 194
Thanked: 0
Quote:
[root@localhost a_a]# g++ CLibTest.cpp -o CLibTest -L. -lCLib
/usr/bin/ld: cannot find -lCLib
Can you list (ls) the contents of your working directory and print it here, please.

There should be a file called libCLib.a in your working (i.e. current / compiling / active ) directory, created by the line,

ar rcs libCLib.a CLib.o

I would stick with this for now, then move on to shared libraries (bottom), purely for the sake of keeping things simple and not having to worry about anything like the dynamic linker setup. I am assuming you are clear on the differences between shared (*.so) and static (*.a) libraries.


N.B. As mr_segfault says, you can specify the location of this library file using the -L compiler option, although it's probably just easier to get started by working in one directory.

----------------------------------------------------------------

Quote:
[root@localhost a_a]# g++ CLibTest.cpp -o CLibTest -L. CLib.o
is NOT using the library, you are simply building the raw (unarchived) object file in to your executable.

----------------------------------------------------------------

To create the shared (*.so) library, use these steps

1) g++ -fpic -c CLib.cpp

2) g++ -shared -o libCLib.so CLib.o

3) g++ CLibTest.cpp -o CLibTest -L. -lCLib

Last edited by dakensta; 10-20-2003 at 11:49 AM..
dakensta is offline     Reply With Quote
Old 10-20-2003, 09:33 PM   #14
Xiangbuilder
Member
 
Registered: Apr 2003
Location: Shandong province China
Distribution: fedora core 1.0
Posts: 206
Thanked: 0

Original Poster
Thank you.

"Can you list (ls) the contents of your working directory and print it here, please."[code]
[root@localhost a_a]# ls
CLib.cpp CLib.h CLibTest.cpp
[root@localhost a_a]# g++ -c CLib.cpp
[root@localhost a_a]# ls
CLib.cpp CLib.h CLib.o CLibTest.cpp
[root@localhost a_a]# ar ruv CLib.a CLib.o
a - CLib.o
[root@localhost a_a]# ls
CLib.a CLib.cpp CLib.h CLib.o CLibTest.cpp
[root@localhost a_a]# g++ CLibTest.cpp -o CLibTest -L. -lCLib
/usr/bin/ld: cannot find -lCLib
collect2: ld returned 1 exit status
[root@localhost a_a]#
Code:
[root@localhost a_a]# ls
CLib.cpp  CLib.h  CLibTest.cpp
[root@localhost a_a]# g++ -c CLib.cpp
[root@localhost a_a]# ls
CLib.cpp  CLib.h  CLib.o  CLibTest.cpp
[root@localhost a_a]# ar rcs libCLib.a CLib.o 
[root@localhost a_a]# ls
CLib.cpp  CLib.h  CLib.o  CLibTest.cpp  libCLib.a
[root@localhost a_a]# g++ CLibTest.cpp -o CLibTest -L. -lCLib
[root@localhost a_a]# ls
CLib.cpp  CLib.h  CLib.o  CLibTest  CLibTest.cpp  libCLib.a
[root@localhost a_a]# ./CLibTest
fetch(&intStash, 0) = 0
... ...
[root@localhost a_a]#
It works fine this time.
When I use
Code:
ar ruv CLib.a CLib.o
, it works not very good. It is because of my poor knowledge instead of lenlutz' command, lenlutz just want to show me the method, but I can't use the method correct.
Sorry, I am not clear on the diffrences between shared (*.so) and static (*.a).
Thank you.
Xiangbuilder is offline     Reply With Quote

Reply

Bookmarks


Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Setting a different library path on compile brainlesspinkey Linux - Software 7 11-13-2005 06:42 PM
compile error srgp library in C csst0136 Programming 13 10-25-2005 10:36 PM
x86_64 library compile problem zypo Fedora 1 10-10-2005 05:46 AM
howto compile bin with my library using all-static and shared linked standart library stpg Programming 4 06-29-2004 05:20 AM
simple g++ library path question harry349 Programming 2 05-31-2004 04:11 PM


All times are GMT -5. The time now is 08:47 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
RSS2  LQ Podcast
RSS2  LQ Radio
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration