NO symbol export in library generated from Corba IDL in VC - corba

Two IDL files, testbase.idl
module Test{
enum JobType{
TYPE1,
TYPE2,
TYPE3
};
struct UserContext{
string name;
string ssoToken;
};
};
testhello.idl:
#include "testbase.idl"
module Test
{
interface Hello
{
void createJob(in UserContext type);
};
};
and Hello.mpc content is:
project(testbaseIDL): taoidldefaults, anytypecode {
idlflags += -Wb,stub_export_macro=TEST_BASE_STUB_Export -Wb,stub_export_include=test_base_stub_export.h -Wb,skel_export_macro=TEST_BASE_SKEL_Export -Wb,skel_export_include=test_base_skel_export.h
IDL_Files {
testhello.idl
}
custom_only = 1
}
project(testhelloIDL): taoidldefaults, anytypecode {
idlflags += -Wb,stub_export_macro=TEST_HELLO_STUB_Export -Wb,stub_export_include=test_hello_stub_export.h -Wb,skel_export_macro=TEST_HELLO_SKEL_Export -Wb,skel_export_include=test_hello_skel_export.h
IDL_Files {
testhello.idl
}
custom_only = 1
}
project(test_base_server): naming, iortable, utils, avoids_corba_e_micro, anytypecode {
sharedname = test_base_server
after += *IDL
Source_Files {
testbaseS.cpp
}
Header_Files{
testbaseS.h
testbaseC.h
test_base_skel_export.h
}
dynamicflags += TEST_BASE_SKEL_BUILD_DLL TEST_BASE_STUB_BUILD_DLL
}
project(test_base_client): naming, iortable, utils,anytypecode {
sharedname = test_base_client
dynamicflags += TEST_BASE_STUB_BUILD_DLL
Source_Files {
testbaseC.cpp
}
Header_Files{
test_base_stub_export.h
testbaseC.h
}
}
project(testhelloserver): naming, iortable, utils, avoids_corba_e_micro,anytypecode {
sharedname = test_hello_server
dynamicflags += TEST_HELLO_SKEL_BUILD_DLL
libs += test_base_server test_hello_client test_base_client
Source_Files {
testhelloS.cpp
}
Header_Files{
testhelloS.h
testbaseS.h
test_hello_skel_export.h
}
}
project(testhelloclient): naming, iortable, utils,anytypecode {
sharedname = test_hello_client
dynamicflags += TEST_HELLO_STUB_BUILD_DLL
libs += test_base_client
Source_Files {
testhelloC.cpp
}
Header_Files{
testhelloC.h
testbaseC.h
test_hello_stub_export.h
}
}
I want to do some demo. The mpc would generate 4 main projects(testbaseClient, testbaseserver, testhelloServer and testhelloClient) and each projects would generate one dll and library and all of them are used as skeleton and stub for each IDL.
In VS2008, after building testUDL, testbaseclient, testbaseServer, the links for both testbaseserver and testbaseclient fail because link can not find some symbols. The error messages are:
1>testhelloC.obj : error LNK2019: unresolved external symbol "bool __cdecl operator::marshal(class TAO_OutputCDR &)" (?marshal#?$In_Var_Size_Argument_T#UUserContext#Test##VAny_Insert_Policy_Stream#TAO###TAO##UAE_NAAVTAO_OutputCDR###Z)
1>testhelloC.obj : error LNK2019: unresolved external symbol "void __cdecl operator::any_insert(class CORBA::Any *,struct Test::UserContext const &)" (?any_insert#?$Any_Insert_Policy_Stream#UUserContext#Test###TAO##SAXPAVAny#CORBA##ABUUserContext#Test###Z)
1>testhelloS.obj : error LNK2001: unresolved external symbol "void __cdecl operatortesthelloS.obj : error LNK2019: unresolved external symbol "bool __cdecl operator>>(class TAO_InputCDR &,struct Test::UserContext &)" (??5#YA_NAAVTAO_InputCDR##AAUUserContext#Test###Z) referenced in function "public: virtual bool __thiscall TAO::In_Var_Size_SArgument_T::demarshal(class TAO_InputCDR &)" (?demarshal#?$In_Var_Size_SArgument_T#UUserContext#Test##VAny_Insert_Policy_Stream#TAO###TAO##UAE_NAAVTAO_InputCDR###Z)
1>.\test_hello_serverd.dll : fatal error LNK1120: 3 unresolved externals
I understand the error: unresolved external symbol happens only if link could not find those symbol from itself or dependent libraries. Therefore, I added
libs += test_base_server test_base_client
for both testhelloclient and testhelloserver. After regenerating all project, the result is the same. The "unresolved external symbol" still there.
I suspect the two generated base library are wrong and I use command:
dumpbin /EXPORTS
to export all symbol and none reported unresolved external symbol are there.
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file test_base_clientd.dll
File Type: DLL
Section contains the following exports for test_base_clientd.dll
00000000 characteristics
526C30F9 time date stamp Sat Oct 26 18:15:37 2013
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00003130 ??4_Init_locks#std##QAEAAV01#ABV01##Z = ??4_Init_locks#std##QAEAAV01#ABV01##Z (public: class std::_Init_locks & __thiscall std::_Init_locks::operator=(class std::_Init_locks const &))
Summary
1000 .data
2000 .idata
3000 .rdata
1000 .reloc
1000 .rsrc
9000 .text
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file test_base_serverd.dll
File Type: DLL
Section contains the following exports for test_base_serverd.dll
00000000 characteristics
526C2AEE time date stamp Sat Oct 26 17:49:50 2013
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00003130 ??4_Init_locks#std##QAEAAV01#ABV01##Z = ??4_Init_locks#std##QAEAAV01#ABV01##Z (public: class std::_Init_locks & __thiscall std::_Init_locks::operator=(class std::_Init_locks const &))
Summary
1000 .data
2000 .idata
3000 .rdata
1000 .reloc
1000 .rsrc
9000 .text
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file test_base_serverd.lib
File Type: LIBRARY
Exports
ordinal name
??4_Init_locks#std##QAEAAV01#ABV01##Z (public: class std::_Init_locks & __thiscall std::_Init_locks::operator=(class std::_Init_locks const &))
Summary
E1 .debug$S
14 .idata$2
14 .idata$3
4 .idata$4
4 .idata$5
16 .idata$6
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file test_base_clientd.lib
File Type: LIBRARY
Exports
ordinal name
??4_Init_locks#std##QAEAAV01#ABV01##Z (public: class std::_Init_locks & __thiscall std::_Init_locks::operator=(class std::_Init_locks const &))
Summary
E1 .debug$S
14 .idata$2
14 .idata$3
4 .idata$4
4 .idata$5
16 .idata$6
Then what I am confused is that:
1) Would link requires all symbol available during making library project. What my past experience in unix is that all symbol is required only if it is on making executable file.
2) How to resolve this issue here? Should I add some arguments for testIDL projects?
[UPdate]:
Added all *C.cpp for testhelloclient and all *C.cpp and *S.cpp would make compilation work.
However, this is not as I expected. I want to compile each IDL into two libraries: one is for stub and another is for skeleton. Then in the future, I only need to deliver stub/skeleton with corresponding header files for other projects. It is unnecessary for skeleton/sub application to compile any of cpp files generated by IDL when .lib/.dll and header file is available.
Currently, none of *.lib files generated above contain symbol from *C.cpp or *S.cpp(the dumpbin result is similar as post previous, only 1 function). And other application would still report unresolve symbols because .lib does not contain any export symbols.
I read MSDN: http://msdn.microsoft.com/en-us/library/ms235636%28v=vs.90%29.aspx this afternoon. For export symbol of dll, the function is declared as:
static __declspec(dllexport) double Add(double a, double b);
but idl generated c header files seems not follow this way..
VC seems much different with GCC in Linux. Is there some solution?It is impossible for I to add _declsepc for each functions in IDL generated header files? The issue is simplified as: none of symbols is export in library generated from IDL in VC(I renamed title for more clarification)
[More update]
I go back to the tao_idl command, it seems it is caused by options like: -Wb,skeleton_export_include="headerfile.h" export_macro..
It seems all these files and macros are generated....Is there any better to gernated .mpc file and are these headerfile.h and macros?
[UPDATE]
It now works with updated mpc file(see above). The export files are generated by generate_export_file.pl which is in $ACE_ROOT/bin directory. The command is like:
generate_export_file.pl TEST_HELLO_STUB > test_hello_stub_export.h
Thanks all.

You have to add anytypecode also as base project in the other projects in the IDL file, not only with the IDL file itself. Also just use naming instead of namingexe, you only need to use the naming service stubs, not the full service implementation

Related

VS2019 and _NO_CRT_STDIO_INLINE, how to explain this weirdo?

Please check my short code below.
pwrapper.h
#include <stdio.h>
#include <stdarg.h>
extern"C" int mm_printfA(const char *fmt, ...);
extern"C" int mm_printfW(const wchar_t *fmt, ...);
pwrapper.cpp
#include "pwrapper.h"
int mm_printfA(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
int ret = vprintf(fmt, args);
va_end(args);
return ret;
}
int mm_printfW(const wchar_t *fmt, ...)
{
va_list args;
va_start(args, fmt);
int ret = vwprintf(fmt, args);
va_end(args);
return ret;
}
main.cpp
#include "pwrapper.h"
// cl /MT /D _NO_CRT_STDIO_INLINE main.cpp pwrapper.cpp
void main()
{
mm_printfA("What is %d?\n", 123);
}
#if 0
void usedull()
{
vprintf(NULL, NULL);
vwprintf(NULL, NULL);
}
#endif
For some reason, I need to compile it with _NO_CRT_STDIO_INLINE, like this:
cl /MT /D _NO_CRT_STDIO_INLINE main.cpp pwrapper.cpp
But link stage fails saying unresolved external symbol vwprintf and vprintf .
A very weird workaround I find out is: Enable the usedull() function body -- although never be called, and, link through pwrapper.lib, using bb.bat below:
#setlocal EnableDelayedExpansion
#set CFLAGS=/D _NO_CRT_STDIO_INLINE
cl /nologo /c /MT %CFLAGS% pwrapper.cpp
#if errorlevel 1 exit /b 4
lib /nologo /out:pwrapper.lib pwrapper.obj
#if errorlevel 1 exit /b 4
cl /nologo /c /MT main.cpp
#if errorlevel 1 exit /b 4
link /nologo main.obj pwrapper.lib
#if errorlevel 1 exit /b 4
Well, this really works, but why?
This is not a pleasant workaround, because each exe project needs to include a "useless" usedull() function. So, is there any better way?
I really can't tell why this workaround works, an explanation of it is very welcome.
==== Some Clarification ====
There were two main.cpp in my original post. Let me name them separately for later reference in case someone would bother to answer this weird question.
main.0.cpp refers to the one without usedull().
main.1.cpp refers to the one with usedull().
In this question, I use VC++ headers and libs for application(not for kernel), and
I compile main.0.cpp and main.1.cpp without _NO_CRT_STDIO_INLINE.
I always compile pwrapper.cpp with _NO_CRT_STDIO_INLINE.
Whether having pwrapper.obj go through pwrapper.lib produce the same result in this issue.
In short:
compiling pwrapper.cpp with -D _NO_CRT_STDIO_INLINE tells the compiler you are going to provide your own implementation of vprintf and vwprintf at link time, and
compiling main.cpp without -D _NO_CRT_STDIO_INLINE tells the compiler to include implementations of vprintf and vwprintf which are used at link time to satisfy both the references from usedull and mm_printfA/mm_printfW
so, this particular combination works to resolve all undefined symbols at link time. See below for more discussion however.
Discussion
In stdio.h, vprintf (which I'll focus on, but vwprintf is configured in the same way) is defined like so:
_Check_return_opt_
_CRT_STDIO_INLINE int __CRTDECL vprintf(
_In_z_ _Printf_format_string_ char const* const _Format,
va_list _ArgList
)
#if defined _NO_CRT_STDIO_INLINE
;
#else
{
return _vfprintf_l(stdout, _Format, NULL, _ArgList);
}
#endif
Note that
if _NO_CRT_STDIO_INLINE is defined, this becomes a forward declaration
whereas if it is not defined, the full body is included in the compilation of the including translation unit.
Additionally, in corecrt_stdio_config.h whether _NO_CRT_STDIO_INLINE is defined determines the value of _CRT_STDIO_INLINE; if it is defined, _CRT_STDIO_INLINE is defined as empty, otherwise it is defined as __inline.
Putting these together,
if _NO_CRT_STDIO_INLINE is not defined, these functions will be candidates for inline expansion,
otherwise a separate implementation of that function will need to be provided at link time.
Default Compilation (no /O1, /O2, no _NO_CRT_STDIO_INLINE)
The above works with the specific compile and link invocations you are using, as without optimization the compiler will simply include the function body in the compilation of main.1.obj. You can see this using dumpbin; running dumpbin -symbols main.1.obj | find "| vprintf" prints:
01D 00000000 SECT8 notype () External | vprintf
showing that main.1.obj provides vprintf as an externally available symbol.
Checking pwrapper.obj, we get:
00A 00000000 UNDEF notype () External | vprintf
showing that vprintf is undefined in this object file, and will need to be provided at link time.
Optimisation for Inline Expansion
However, if we change the optimisation option for inline expansion, we get different results. Using even the first level of optimisation (-Ob1, included in -O1 and -O2) like so:
cl -c -Ob1 main.1.cpp
causes the compiler to incorporate the body of vprintf directly into usedull, and remove the separate implementation of vprintf, which can be confirmed using dumpbin. So, as you would now expect, attempting to link main.1.obj and pwrapper.obj together will once again give your original error:
pwrapper.obj : error LNK2019: unresolved external symbol vwprintf referenced in function mm_printfW
pwrapper.obj : error LNK2019: unresolved external symbol vprintf referenced in function mm_printfA
main.exe : fatal error LNK1120: 2 unresolved externals
Multiple Implementations?
So, following on from that it is apparent that compiling both files with -D _NO_CRT_STDIO_INLINE will fail as there will be no implementations of the relevant methods. What about if both are compiled without this definition?
If we check the object files, both have defined symbols for vprintf:
01D 00000000 SECT8 notype () External | vprintf
and:
01A 00000000 SECT7 notype () External | vprintf
which under normal circumstances would result in errors due both to multiple definitions of a symbol and violations of the One Definition Rule. However, when performing inline expansion, the compiler and linker have your back. As per 2:
Rather than expand an inline function defined in a header file, the compiler may create it as a callable function in more than one translation unit. The compiler marks the generated function for the linker to prevent one-definition-rule (ODR) violations.

Eclipse CDT is reporting false erros while using std::index_sequence

UPDATED: Added complete example and compiler information
I have Eclipse 2019-03 (4.11.0) with CDT 9.7.0.20190309 and the build-in compiler reports false positive errors while using std::index_sequence in C++17:
#include <gtest/gtest.h>
#include <utility>
#include <array>
class Sample {
public:
template<std::size_t N >
std::size_t get_percentage( void ) {
return N;
}
template<std::size_t... Is>
inline std::array<std::size_t, sizeof...(Is)> calculate_percentages( std::index_sequence<Is...> ) noexcept {
return { this->get_percentage<Is>()... };
}
template<std::size_t N>
inline std::array<std::size_t, N> get_percentages( void ) noexcept {
return this->calculate_percentages( std::make_index_sequence<N>() );
/* ^^^^^^^^^^^^^^^^^^^^^ : Invalid arguments ' Candidates are: std::array calculate_percentages(std::integer_sequence) ' */
}
};
TEST( IntegerSequence, InvalidArgumentsError ) {
Sample test;
std::array<std::size_t, 5> data = test.get_percentages<5>();
for( int i = 0; i < 5; i++ ) {
std::cout << data[i] << std::endl;
}
}
int main( int argc, char ** argv ) {
testing::InitGoogleTest( &argc, argv );
return RUN_ALL_TESTS();
}
But the normal compilation succeeds without any problem.
My CDT GCC Built-in Compiler Settings in
Project Properties -> C/C++ General -> Preprocessor Include Paths, Macros etc. -> Providers is as follows:
${COMMAND} ${FLAGS} -E -P -v -dD -std=c++17 "${INPUTS}"
The same applies for CDT Cross GCC Built-in Compiler Settings.
Rebuilding the index does not helped in there.
The GCC version I am using:
gcc (Ubuntu 8.3.0-6ubuntu1) 8.3.0
Many thanks in advance to anyone willing to help...
The problem is caused by the fact that the standard library that comes with gcc 8 and newer uses a new compiler intrinsic called __integer_pack to implement std::make_integer_sequence (and related utilities like std::make_index_sequence).
Eclipse CDT's parser does not currently understand the __integer_pack intrinsic, and therefore it has trouble correctly parsing code that uses std::make_integer_sequence / std::make_index_sequence with these newer gcc versions.
I filed a CDT bug to track adding support for the __integer_pack intrinsic.
Meanwhile, a workaround you could employ is to use gcc 7 or older. If you need gcc 8 or newer to actually build your code, you could still tell Eclipse the look at the standard library headers of e.g. gcc 7 by replacing ${COMMAND} in the mentioned "built-in compiler settings" configuration with g++-7.
UPDATE: The Eclipse bug is now fixed, with the fix targeting CDT's 9.11 release (scheduled to be part Eclipse 2020-03).

error LNK2019: unresolved external symbol _ Open CV program

I am learning open CV and for the same i was trying few programs.
I am referring to this link.
http://docs.opencv.org/modules/contrib/doc/facerec/tutorial/facerec_gender_classification.html
I am using visual studio 10 to run the same, and i think somewhere i have messed up with some configuration.
I am facing the same problem in couple of more programs (picked from same source) ,
The error which i get is as follows:-
1>main.obj : error LNK2019: unresolved external symbol "int __cdecl cv::waitKey(int)" (?waitKey#cv##YAHH#Z) referenced in function __catch$_main$0
1>main.obj : error LNK2019: unresolved external symbol "class cv::Mat __cdecl cv::subspaceReconstruct(class cv::_InputArray const &,class cv::_InputArray const &,class cv::_InputArray const &)" (?subspaceReconstruct#cv##YA?AVMat#1#ABV_InputArray#1#00#Z) referenced in function __catch$_main$0
..... (more such unresolved external symbol error)
1>main.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall cv::_InputArray::empty(void)const " (?empty#_InputArray#cv##UBE_NXZ)
1>c:\users\isenses\documents\visual studio 2010\Projects\gender_classification\Debug\gender_classification.exe : fatal error LNK1120: 37 unresolved externals
1>
1>Build FAILED.
1>Time Elapsed 00:00:00.36
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
My Project Properties are as follows:-
Properties->Configuration Properties ->Debugging->command arguments->C:\Users\isenses\Documents\Visual Studio 2010\Projects\gender_classification\csv.txt
Properties->Configuration Properties ->VC++ directories->Include directories->(added C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib
&
C:\openCV_2.4\opencv\build\x86\vc10\lib)
C/C++->general->additional include directories (added include path of openCV ie:-
C:\openCV_2.4\opencv\build
Linker->General---
Enable incremental linking=no
Additional Library directories=C:\Program Files %28x86%29\Microsoft Visual Studio 10.0\VC\lib
C:\openCV_2.4\opencv\build\x86\vc10
linker->System---SubSystem= /SUBSYSTEM:CONSOLE
Linker->Input---
additional dependencies=
wsock32.lib
opencv_contrib2411d.lib
opencv_calib3d2411d.lib
opencv_ml2411d.lib
opencv_objdetect2411d.lib
Thank you.
Thanks to #miki i was able to build the file successfully.
The solution to my problem was:-
adding proper additional Dependencies in properties->linker->input.
Adding libraries path in windows environment variables.
I had not used proper additional dependencies as pointed by #miki and as quoted by him "well you also have to link opencv_coreXXX,opencv_highguiXXX, opencv_imgprocXXX etc... (with trailing "d" if in debug) in your Linker->Input--- additional dependencies"
Thanks again
I want to add an answer to this because I feel the documentation on the opencv site needs to be updated. I followed the tutorial and could not get the library to link. After many permutations I decided to look at the .lib files. My problem was quite simple. The lib files in the opencv tutorial are not complete. Specifically my lib directory includes three more lib files. I added three extra lib files to visual studio linker and the external symbol problem was solved.
I am unsure why this is the case because I was only trying to use functions contained within the core module. Anyway, hopefully this will help someone.
I am using opencv 3 and visual studio 2017.

Lua - "multiple vms detected" while trying to add extension for statically linked Lua

I have application that contain statically linked lua 5.2 inteperpreter (and haven't access to code).
When I trying to write extension with next code:
#define LUA_LIB
#define LUA_BUILD_AS_DLL
#include "lua.hpp"
extern "C"
{
static int test(lua_State* state)
{
return 1;
}
static const struct luaL_Reg functions[] = {
{"test", test},
{NULL, NULL},
};
int __declspec(dllexport) luaopen_test(lua_State* state)
{
luaL_newlibtable(state, functions);
luaL_setfuncs(state, functions, 0);
return 0;
}
}
And compile it with statically linked lua52.lib .
I get "multiple vms detected" error when I trying to require it fromn lua code.
What I can do in this situation?
You can't compile it with statically linked lua52.lib as the main application loads its own version of lua52.lib and when this module is "required", it loads its own copy, which leads to "multiple VMs detected" message.
With statically compiled VM you have two options (on Windows): (1) include all your modules statically, or (2) compile your modules against Lua52.dll, but instead of the actual DLL include a "proxy" DLL that will forward Lua API calls to the methods in the statically compiled executable (the API methods also need to be exported in the executable).
See this thread for the discussion on how the executable needs to be compiled and LuaProxyDllFour page for the proxy DLL.
On Linux you don't need to have a proxy library, but you still need to avoid linking Lua interpreter into the library and export symbols from the executable by using -Wl,-E linker option; see lhf's answer for details.

Cannot link a minimal Lua program

I have the following trivial Lua program which I copied from the book Programming In Lua
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main (void)
{
char buff[256];
int error;
lua_State *L = luaL_newstate(); /* opens Lua */
luaL_openlibs(L); /* opens the standard libraries */
while (fgets(buff, sizeof(buff), stdin) != NULL)
{
error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
lua_pcall(L, 0, 0, 0);
if (error)
{
fprintf(stderr, "%s", lua_tostring(L, -1));
lua_pop(L, 1); /* pop error message from the stack */
}
}
lua_close(L);
return 0;
}
my environment is cywin
my make file looks like this:
CC=gcc
INCLUDE='-I/home/xyz/c_drive/Program Files/Lua/5.1/include'
LINKFLAGS='-L/home/xyz/c_drive/Program Files/Lua/5.1/lib' -llua51
li.o:li.c
$(CC) $(INCLUDE) -c li.c
main:li.o
$(CC) -o main $(LINKFLAGS) li.o
clean:
rm *.o
rm main
My /home/xyz/c_drive/Program Files/Lua/5.1/lib directory contains lua5.1.dll lua5.1.lib lua51.dll and lua51.lib
Trying to build my main target I am getting the following errors:
li.o:li.c:(.text+0x35): undefined reference to `_luaL_newstate'
li.o:li.c:(.text+0x49): undefined reference to `_luaL_openlibs'
li.o:li.c:(.text+0xaf): undefined reference to `_luaL_loadbuffer'
li.o:li.c:(.text+0xd9): undefined reference to `_lua_pcall'
li.o:li.c:(.text+0x120): undefined reference to `_lua_tolstring'
li.o:li.c:(.text+0x154): undefined reference to `_lua_settop'
li.o:li.c:(.text+0x167): undefined reference to `_lua_close'
Any ideas about what I might be doing wrong here?
The problem is that you have named the libraries on the link command line before the object files that require them. The linker loads modules from left to right on the command line. At the point on the line where you name -llua51, no undefined symbols that could be satisfied by that library are known. Then you name li.o, which does have unknown symbols.
Some Unix-like environments don't treat this as an error because part of the link process is deferred to the program load when reference to .so files are satisfied. But Cygwin, MinGW, and Windows in general must treat this as an error because DLLs work quite differently from .so files.
The solution is to put -llua51 after all the .o files on your link line.
Edit: Incidentally, it appears you are linking against the Lua for Windows distribution, but building with GCC under Cygwin. You will want to use Dependency Walker to make sure that your program does not depend on the Cygwin runtime, and that it does depend on the same C runtime as the lua51.dll from Lua for Windows. IIRC, that will be the runtime for the previous version of Visual Studio. It is possible to make GCC link against that, but you will need to be using the MinGW port (which you can use from Cygwin), and link against a couple of specific libraries to get that version. I'm away from my usual PC, or I'd quote an exact link line. (I believe you need -lmoldname -lmsvcr80 or something like that, as the last items on the link line.)
It will cause mysterious and very hard to diagnose problems if more than one C runtime library is in use. The easy answer is to use the same one as your preferred Lua DLL. Another alternative is that the Lua Binaries project has pre-compiled Lua DLLs for a wide array of C toolchains on Windows. If you need a Lua application that understands the Cygwin environment, you will want one that is built by GCC for Cygwin and not the Lua for Windows flavor. Lua Binaries will be your friend, or you can build Lua your self from source.
The names in the Lua API do not have those leading underscores. Try compiling with -fno-leading-underscore.

Resources