【问题标题】:/usr/bin/ld: Cannot Find -l Error (Using GCC in Linux GCC Linker Error)/usr/bin/ld: 找不到 -l 错误(在 Linux GCC 链接器中使用 GCC 错误)
【发布时间】:2013-11-22 04:55:00
【问题描述】:

尝试在 Linux 中使用 gcc 编译此 C++ 代码。它使用一个外部库/名为 SCIP 的应用程序。

我正在使用此代码进行编译:

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

但我收到此错误:

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

该文件存在于文件夹中。不知道为什么它没有把它捡起来链接

#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;
}

【问题讨论】:

    标签: gcc linker


    【解决方案1】:

    -l./scipF/scip/lib/libscip.a 更改为-lscip

    来自documentation

    -l图书馆

    -l图书馆

    在链接时搜索名为 library 的库。 (将库作为单独参数的第二种选择仅用于 POSIX 合规性,不推荐。)

    ...

    链接器搜索库的标准目录列表,该库实际上是一个名为 liblibrary.a 的文件。链接器然后使用这个文件,就好像它是通过名称精确指定的一样。

    搜索的目录包括几个标准系统目录以及您使用-L 指定的任何目录。

    【讨论】:

      【解决方案2】:

      您想要链接一个预编译的静态库 libscip.a,它是一组打包到一个方便存档中的 .o 文件。链接此类库的最简单方法是将其作为输入文件简单地传递给 GCC。 GCC 会识别它并将其传递给链接器。

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

      【讨论】:

        【解决方案3】:

        -l./scipF/scip/lib/libscip.a 更改为-l:./scipF/scip/lib/libscip.a

        来自文档:

        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.
        

        警告:关于动态库有possible caveat

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-01-03
          • 1970-01-01
          • 2023-01-07
          • 1970-01-01
          • 1970-01-01
          • 2018-02-06
          • 2014-10-19
          • 1970-01-01
          相关资源
          最近更新 更多