Hi,

I need to use the libraries of a commercial solver NOMAD in my C++ code. I got error LNK2001 error. I have #include "nomad.hpp". In the NOMAD handbook, the following is written.
If you are using Visual C++, your programs will not link with this version of the library and you must compile the library yourself. After NOMAD installation, nomad.hpp and nomad.cpp files are saved. I tried to compile it with a C++ project, it was successfully compiled? I also saved the nomad.hpp to the source code's directory. Still did not work... Can you help me please?

Dani AI

Generated

This thread demonstrates the classic LNK2001 case: the linker can’t find the definition of a declared symbol (here the missing NOMAD::end). was right that the problem is at link time, and ’s final note that rebuilding the NOMAD libraries and adding the produced .lib into the project (plus installing the VS service pack) resolved the immediate issue. The checklist below gives practical diagnostics and things to verify so the same error doesn’t reappear.

  • Confirm which binary you’re linking: a static .lib or an import .lib for a .dll. The linker needs the .lib at link time; the .dll is needed only at runtime.
  • Match toolchain and architecture: the library must be built with a compatible MSVC toolset and for the same target (x86 vs x64). Mixing compilers or bitness often causes unresolved symbols.
  • Match build settings: ensure Release/Debug, and runtime flags (e.g. /MD vs /MT) are consistent between the library and your project.
  • Verify the symbol actually exists in the library (name mangling): use the Visual Studio tools to inspect the library’s symbols and confirm NOMAD::end (or its mangled form) is present.
  • Use the linker verbose output to see which libraries are searched and which ones satisfy (or don’t satisfy) the unresolved symbol.

Useful commands (run in a Visual Studio Developer Command Prompt):

dumpbin /symbols path\to\nomad.lib | findstr /I "end NOMAD"
link /verbose > link_log.txt   (enable via Linker settings or add /VERBOSE)
dumpbin /exports path\to\nomad.dll

If the symbol is missing from the .lib, rebuild NOMAD with the same MSVC configuration as the application (static vs DLL, same runtime flag). If the symbol appears but the linker still complains, the verbose linker log and the dumpbin symbol list will show why (wrong lib, wrong path, wrong architecture). Installing MSVC service packs can change toolset compatibility, which explains why ’s install-step made the final difference.

Recommended Answers

All 9 Replies

>> I tried to compile it with a C++ project, it was successfully compiled?

How would we know whether the compile was successful or not??? Your compiler will tell you that, all you have to do is read the error and warning messages.

>>Can you help me please?
Go back to where you got the source code and ask them how to do it. Its very unlikely anyone here will know anything about that.

The problem is with calling the libraries not with the NOMAD software. I do not know how to use libraries and how to handle problems related to that. That's why I am asking it here.

Link your program with the libraries, just like you would like to any other library. Each version of Microsoft compilers does it a little differently. For vc++ 2010 do this:

Select menu Project --> Properties (at the bottom of the menu). Expand the Configuration Properties tab on the left pane. The expand Linker --> Input. On the right pane the first item is "Additional Dependencies". Add the library names there. Once that is done, select Linker --> General. On the right pane you will find "Additional Library Directories". Add the path to where the NOMAD libraries were installed.

Another option is to use a pragma inside one of the source files for your program #pragma comment(lib,"nomad.lib") Replace nomad.lib with the name of the library. Use multiple pragmas if you need to link with more than one library.

thanks but it did not work. Here is the code if it makes sense ever.

/*-----------------------------------------------------*/
/*  how to use the NOMAD library with a user function  */
/*-----------------------------------------------------*/
#include "nomad.hpp"
using namespace std;
// using namespace NOMAD; avoids putting NOMAD:: everywhere

/*----------------------------------------*/
/*               The problem              */
/*----------------------------------------*/
class My_Evaluator : public NOMAD::Evaluator {
public:
  My_Evaluator  ( const NOMAD::Parameters & p ) :
    NOMAD::Evaluator ( p ) {}

  ~My_Evaluator ( void ) {}

  bool eval_x ( NOMAD::Eval_Point   & x          ,
		const NOMAD::Double & h_max      ,
		bool                & count_eval   ) const {

    NOMAD::Double c1 = 0.0 , c2 = 0.0;
    for ( int i = 0 ; i < 5 ; i++ ) {
      c1 += (x[i]-1).pow2();
      c2 += (x[i]+1).pow2();
    }
    x.set_bb_output  ( 0 , x[4]  ); // objective value
    x.set_bb_output  ( 1 , c1-25 ); // constraint 1
    x.set_bb_output  ( 2 , 25-c2 ); // constraint 2

    count_eval = true; // count a black-box evaluation

    return true;       // the evaluation succeeded
  }
};

/*------------------------------------------*/
/*            NOMAD main function           */
/*------------------------------------------*/
int main ( int argc , char ** argv ) {

  // display:
  NOMAD::Display out ( std::cout );
  out.precision ( NOMAD::DISPLAY_PRECISION_STD );

  try {

    // NOMAD initializations:
    NOMAD::begin ( argc , argv );

    // parameters creation:
    NOMAD::Parameters p ( out );

    p.set_DIMENSION (5);             // number of variables

    vector<NOMAD::bb_output_type> bbot (3); // definition of
    bbot[0] = NOMAD::OBJ;                   // output types
    bbot[1] = NOMAD::PB;
    bbot[2] = NOMAD::EB;
    p.set_BB_OUTPUT_TYPE ( bbot );

    p.set_DISPLAY_STATS ( "bbe ( sol ) obj" );

    // p.set_DISPLAY_DEGREE ( FULL_DISPLAY );

    p.set_X0 ( NOMAD::Point ( 5 , 0.0 ) );  // starting point

    p.set_LOWER_BOUND ( NOMAD::Point ( 5 , -6.0 ) ); // all var. >= -6
    NOMAD::Point ub ( 5 );                    // x_4 and x_5 have no bounds
    ub[0] = 5.0;                              // x_1 <= 5
    ub[1] = 6.0;                              // x_2 <= 6
    ub[2] = 7.0;                              // x_3 <= 7
    p.set_UPPER_BOUND ( ub );

    p.set_MAX_BB_EVAL (100);     // the algorithm terminates after
                                 // 100 black-box evaluations

    // p.set_TMP_DIR ("/tmp");   // directory for temporary files

    // parameters validation:
    p.check();

    // custom evaluator creation:
    My_Evaluator ev   ( p );

    // algorithm creation and execution:
    NOMAD::Mads mads ( p , &ev );
    mads.run();
  }
  catch ( exception & e ) {
    cerr << "\nNOMAD has been interrupted (" << e.what() << ")\n\n";
  }

  NOMAD::Slave::stop_slaves ( out );
  NOMAD::end();

  return EXIT_SUCCESS;
}

and here is one of the errors:

error LNK2001: unresolved external symbol "void_cdeck NOMAD:end(void)"(? end@NOMAD@@YAXXZ).

That error message ALWAYS means that you are not linking with one or more libraries. Are you trying to link with a library that was compiled with the compiler you are using? Each compiler has its own way of mangling function and object names.

With suggestion of Xander314 in cplusplus.org I tried to do the following, as I am using Visual Studio 2010 but it did not work so far.
1) Find the library files resulting from this build (.lib extension for MSVC)
2) Add these files to your link libraries list in your active project: "Project -> Properties -> Configuration Properties -> Linker -> Input" and then click "Additional Dependencies", and finally click the arrow on the right and "Edit"
Add additional link libraries - add the NOMAD ones.

I also added the library paths to your VC++ directories.

There is no CMakeLists.txt but the problem is solved thanks to Xander314 and Yusuf from Hemosoft. Here is the solution:

After creating the libraries using the cpp and hpp files, I defined the location of the created library file as additional library directories. (Project properties >> Configuration properties >> Linker >> General) Also, the created library file (lib file) is defined as additional dependencies. (Project properties >> Configuration properties >> Linker >> Input).

When I first tried it did not work. Then I installed the Service pack. Then it worked. Thanks again.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.