0

background knowledge:

First I explain what do I understand of these gcc flags so far:

-L: As the gcc manual states, this flag add specified directory "to the list of directories to be searched for -l"

-l: Again as manual said, "Search the library named library when linking."

So, what I understand of these two, is first one adds directories to a list which, named library by the second one will be searched in, by the linker!

-I: As for this, manual says: "Add the directory dir to the list of directories to be searched for header files during preprocessing"! So I assume this one does the same as -L but for header files.

-Wl: The -Wl portion sends comma-separated options to the linker

What I'm trying to do:

I want to compile/build an executable which uses 3 .so shared libraries; And 2 of those (libpq and libsqlite3) are provided by official 3rd party vendors (Postgresql and Sqlite); And installed with apt install.
The 3rd one is one of mine; I wrote it myself and trying to link it with my executable to be able to use it at runtime.

What I tried so far:

If I compile my code without my own library (and respective function inside the code) using below command, it works fine:

g++ -std=c++20 full.cpp -o loadTester -L/usr/include/postgresql/libpq -lpq -lsqlite3

However, using these command, to also link my own library with my code, I get errors:

gcc -std=gnu17 -shared -o liblogwritter.so -fPIC logWritter.c
g++ -std=c++20 full-with-logger.cpp -o loadTester -L/usr/include/postgresql/libpq -L./ -lpq -lsqlite3 -llogwritter -Wl,-rpath=./ -I./

I've also tried by replacing ./ parts with the full path: /home/username/Desktop/Current/.

Error:

/usr/bin/ld: /tmp/ccSFD38J.o: in function `pgConncetionInit(char const*)':
full-with-logger.cpp:(.text+0xc3): undefined reference to `logWritter(char const*)'
/usr/bin/ld: /tmp/ccSFD38J.o: in function `pgInsertQuery(char**)':
full-with-logger.cpp:(.text+0x709): undefined reference to `logWritter(char const*)'
/usr/bin/ld: /tmp/ccSFD38J.o: in function `main':
full-with-logger.cpp:(.text+0x1994): undefined reference to `logWritter(char const*)'
/usr/bin/ld: full-with-logger.cpp:(.text+0x19e2): undefined reference to `logWritter(char const*)'
/usr/bin/ld: full-with-logger.cpp:(.text+0x1b0e): undefined reference to `logWritter(char const*)'
collect2: error: ld returned 1 exit status

Code for the library:

logWriter.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/un.h>

#define SV_SOCK_PATH "/tmp/shahab_logger"

int logWritter(const char* messageData)
{
    struct sockaddr_un addr;

    // Create a new client socket with domain: AF_UNIX, type: SOCK_STREAM, protocol: 0
    int sfd = socket(AF_UNIX, SOCK_STREAM, 0);

    // Construct server address, and make the connection.
    memset(&addr, 0, sizeof(struct sockaddr_un));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, SV_SOCK_PATH, sizeof(addr.sun_path) - 1);

    if (connect(sfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) == -1)
    {
        fprintf(stderr, "Error connecting to server\n");
        return 0;                
    }

    write(sfd, messageData, strlen(messageData));

    close(sfd);
    return 0;
}

logWriter.h:

#ifndef LOGWRITTER_H
#define LOGWRITTER_H
 
int logWritter(const char* messageData);
 
#endif  // LOGWRITTER_H

myprogram.cpp:

... //Several lines removed

logWritter(jobExecTime.c_str());

... //Several lines removed

Note:

I made a simple driver program for my library as below and it was working fine (Provided that I ran the server.c before to accept socket connection):

#include <stdio.h>
#include <stdlib.h>
#include "logWritter.h"

int main()
{
    printf("Test driver program!\n");
    if (logWritter("Test driver program!") > 0)
    {
        printf("Error!\n");
        exit(1);
    }

    return 0;
}

And I compiled this driver program as below:

gcc -c -Wall -Werror -fpic logWritter.c
gcc -shared logWritter.o -o liblogwritter.so
gcc -Wall testDriver.c -o testDriver -L/home/username/Desktop/logger/ -llogwritter -Wl,-rpath=/home/username/Desktop/logger/

Note 2:

Here is the list of files inside /home/username/Desktop/Current/ (which all files exist) just in case:

activity_main.db  full.cpp  full-with-logger.cpp  liblogwritter.so  logServer
logWritter.c  logWritter.h  postgresInit.sql  run.sh  server.c  sqliteInit.sql  unix_socket.h

Question:

I think it obvious at this point, after reading such lengthy post (my greatest regards and appreciation for your king effort and time in advance) but to follow standards here:

  1. Are my understanding which I explained in the first section, correct?
  2. What am I missing (knowledge-wise)?
  3. How should I compile my executable? Please explain for both two cases which I copied the header file in /usr/include/ and shared library file in /usr/local/lib, or if I want to link them from current working folder, as it is now in the case of examples above.
Shahaboddin
  • 136
  • 1
  • 9
  • 1
    ***Are my understanding which I explained in the first section, correct?*** Yes. – drescherjm Jul 22 '23 at 15:32
  • 1
    `-L/usr/include/postgresql/libpq` is wrong but unnecessary. This is a header path not the location of the library. It's unnecessary because the library should have been installed by your package manager in `/usr/lib` which will be in a system path that your linker already searches by default. – drescherjm Jul 22 '23 at 15:35
  • 1
    Edited 2x now. duh!: `-L/usr/include/postgresql/libpq` ?? Usually `-L` directories are like `/usr/lib/`, but `/usr/include` is usually where the `-I` files live. It also strikes me that the `libpq` tail end of your `-L` is a file, not a directory, but I have not experience with postgresql. Good luck. – shellter Jul 22 '23 at 15:47
  • @drescherjm That is correct, thanks for correction. Sometime in the development, I had an error which solved by adding these flags and I made mistake with capital i and capital L – Shahaboddin Jul 23 '23 at 06:05
  • @shellter You are right; I fixed it. Though `libpq` in `/usr/include/postgresql/libpq` is actually a directory! – Shahaboddin Jul 23 '23 at 06:06

1 Answers1

3

Since you define logWritter in .c, it must be declared with C linkage when used in C++, hence logWriter.h must be

#ifndef LOGWRITTER_H
#define LOGWRITTER_H
#ifdef __cplusplus
extern "C" {
#endif

int logWritter(const char* messageData);

#ifdef __cplusplus
}
#endif
#endif
273K
  • 29,503
  • 10
  • 41
  • 64