user3020339
user3020339

Reputation: 21

/usr/bin/ld: Cannot Find -l Error (Using GCC in Linux GCC Linker Error)

Trying to compile this C++ code using gcc in Linux. It uses an external library/ the application called SCIP.

I am compiling using this code:

gcc TestC.cpp -I./scipF/scip/src -L./scipF/scip/lib -l./scipF/scip/lib/libscip.a

but I get this error:

/usr/bin/ld: cannot find -l./scipF/scip/lib/libscip.a

The file exists in the folder. Not sure why it is not picking it up to link

#include <iostream>

#include "objscip/objscip.h"
#include "objscip/objscipdefplugins.h"


/** reads parameters */
static
SCIP_RETCODE readParams(
   SCIP*                      scip,               /**< SCIP data structure */
   const char*                filename            /**< parameter file name, or NULL */
   )
{
   if( filename != NULL )
   {
      if( SCIPfileExists(filename))
      {
         std::cout << "reading parameter file <" << filename << ">" << std::endl;
         SCIP_CALL( SCIPreadParams(scip, filename) );
      }
      else
         std::cout << "parameter file <" << filename << "> not found - using default parameters" << std::endl;
   }
   else if( SCIPfileExists("scipmip.set") )
   {
      std::cout << "reading parameter file <scipmip.set>" << std::endl;
      SCIP_CALL( SCIPreadParams(scip, "scipmip.set") );
   }

   return SCIP_OKAY;
}

/** starts SCIP */
static
SCIP_RETCODE fromCommandLine(
   SCIP*                      scip,               /**< SCIP data structure */
   const char*                filename            /**< input file name */
   )
{
   /********************
    * Problem Creation *
    ********************/

   std::cout << std::endl << "read problem <" << filename << ">" << std::endl;
   std::cout << "============" << std::endl << std::endl;
   SCIP_CALL( SCIPreadProb(scip, filename, NULL) );


   /*******************
    * Problem Solving *
    *******************/

   /* solve problem */
   std::cout << "solve problem" << std::endl;
   std::cout << "=============" << std::endl;
   SCIP_CALL( SCIPsolve(scip) );

   std::cout << std::endl << "primal solution:" << std::endl;
   std::cout << "================" << std::endl << std::endl;
   SCIP_CALL( SCIPprintBestSol(scip, NULL, FALSE) );


   /**************
    * Statistics *
    **************/

   std::cout << std::endl << "Statistics" << std::endl;
   std::cout << "==========" << std::endl << std::endl;

   SCIP_CALL( SCIPprintStatistics(scip, NULL) );

   return SCIP_OKAY;
}

/** starts user interactive mode */
static
SCIP_RETCODE interactive(
   SCIP*                      scip                /**< SCIP data structure */
   )
{
   SCIP_CALL( SCIPstartInteraction(scip) );

   return SCIP_OKAY;
}

/** creates a SCIP instance with default plugins, evaluates command line parameters, runs SCIP appropriately,
 *  and frees the SCIP instance
 */
static
SCIP_RETCODE runSCIP(
   int                        argc,               /**< number of shell parameters */
   char**                    argv                /**< array with shell parameters */
   )
{
   SCIP* scip = NULL;

   /*********
    * Setup *
    *********/

   /* initialize SCIP */
   SCIP_CALL( SCIPcreate(&scip) );

   /***********************
    * Version information *
    ***********************/

   SCIPprintVersion(scip, NULL);
   std::cout << std::endl;


   /* include default SCIP plugins */
   SCIP_CALL( SCIPincludeDefaultPlugins(scip) );


   /**************
    * Parameters *
    **************/

   if( argc >= 3 )
   {
      SCIP_CALL( readParams(scip, argv[2]) );
   }
   else
   {
      SCIP_CALL( readParams(scip, NULL) );
   }
   /*CHECK_OKAY( SCIPwriteParams(scip, "scipmip.set", TRUE) );*/


   /**************
    * Start SCIP *
    **************/

   if( argc >= 2 )
   {
      SCIP_CALL( fromCommandLine(scip, argv[1]) );
   }
   else
   {
      printf("\n");

      SCIP_CALL( interactive(scip) );
   }


   /********************
    * Deinitialization *
    ********************/

   SCIP_CALL( SCIPfree(&scip) );

   BMScheckEmptyMemory();

   return SCIP_OKAY;
}

/** main method starting SCIP */
int main(
   int    argc,          /**< number of arguments from the shell */
   char** argv                     /**< array of shell arguments */
   )
{
   SCIP_RETCODE retcode;
      argc = 3;
      argv [2]= "InputFile";
   retcode = runSCIP(argc, argv);
   if( retcode != SCIP_OKAY )
   {
      SCIPprintError(retcode);
      return -1;
   }

   return 0;
}

Upvotes: 2

Views: 5920

Answers (3)

Telvas
Telvas

Reputation: 158

You want to link a precompiled static library libscip.a, which is a set of .o files packed into a convenient archive. Easiest way to link such library is to simply pass it to GCC as input file. GCC will recognise it and pass it to the linker.

gcc TestC.cpp -I./scipF/scip/src ./scipF/scip/lib/libscip.a

Upvotes: 1

Michael Pankov
Michael Pankov

Reputation: 3701

Change the -l./scipF/scip/lib/libscip.a to -l:./scipF/scip/lib/libscip.a.

From the documentation:

LD(1)                        GNU Development Tools                       LD(1)



NAME
       ld - The GNU linker

SYNOPSIS
       ld [options] objfile ...
...

       -l namespec
       --library=namespec
           Add the archive or object file specified by namespec to the list of
           files to link.  This option may be used any number of times.  If
           namespec is of the form :filename, ld will search the library path
           for a file called filename, otherwise it will search the library
           path for a file called libnamespec.a.

           On systems which support shared libraries, ld may also search for
           files other than libnamespec.a.  Specifically, on ELF and SunOS
           systems, ld will search a directory for a library called
           libnamespec.so before searching for one called libnamespec.a.  (By
           convention, a ".so" extension indicates a shared library.)  Note
           that this behavior does not apply to :filename, which always
           specifies a file called filename.

           The linker will search an archive only once, at the location where
           it is specified on the command line.  If the archive defines a
           symbol which was undefined in some object which appeared before the
           archive on the command line, the linker will include the
           appropriate file(s) from the archive.  However, an undefined symbol
           in an object appearing later on the command line will not cause the
           linker to search the archive again.

           See the -( option for a way to force the linker to search archives
           multiple times.

           You may list the same archive multiple times on the command line.

           This type of archive searching is standard for Unix linkers.
           However, if you are using ld on AIX, note that it is different from
           the behaviour of the AIX linker.

Warning: there's possible caveat with regards to dynamic libraries.

Upvotes: 0

Alok Singhal
Alok Singhal

Reputation: 96241

Change the -l./scipF/scip/lib/libscip.a to -lscip.

From the documentation:

-llibrary

-l library

Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX compliance and is not recommended.)

...

The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name.

The directories searched include several standard system directories plus any that you specify with -L.

Upvotes: 1

Related Questions