Linking with Apache Portable Runtime on MS Windows - windows

I'm trying to build a Python extension which links to APR. And this time it's on MS Windows... (It works on Linux).
Here's where the build fails, the command, and the output formatted for readability:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\link.exe
/nologo
/INCREMENTAL:NO
/LTCG
/DLL
/MANIFEST:EMBED,ID=2
/MANIFESTUAC:NO
/LIBPATH:c:\dev\protopy\lib/apr
/LIBPATH:c:\bin\python\Libs
/LIBPATH:c:\dev\protopy\.venv\libs
/LIBPATH:c:\dev\protopy\.venv\PCbuild\amd64
"/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\amd64"
"/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.10240.0\ucrt\x64"
"/LIBPATH:C:\Program Files (x86)\Windows Kits\8.1\lib\winv6.3\um\x64"
apr-1.lib
/EXPORT:PyInit_wrapped build\temp.win-amd64-3.6\Release\protopy/lib/descriptors.obj
build\temp.win-amd64-3.6\Release\protopy/lib/binparser.obj
build\temp.win-amd64-3.6\Release\protopy/lib/defparser.obj
build\temp.win-amd64-3.6\Release\protopy/lib/protopy.lex.obj
build\temp.win-amd64-3.6\Release\protopy/lib/protopy.tab.obj
build\temp.win-amd64-3.6\Release\protopy/lib/pyhelpers.obj
build\temp.win-amd64-3.6\Release\protopy/lib/list.obj
build\temp.win-amd64-3.6\Release\protopy/wrapper.obj
/OUT:build\lib.win-amd64-3.6\protopy\wrapped.cp36-win_amd64.pyd
/IMPLIB:build\temp.win-amd64-3.6\Release\protopy/lib\wrapped.cp36-win_amd64.lib
wrapper.obj : warning LNK4197: export 'PyInit_wrapped' specified multiple times; using first specification
Creating library build\temp.win-amd64-3.6\Release\protopy/lib\wrapped.cp36-win_amd64.lib \
and object build\temp.win-amd64-3.6\Release\protopy/lib\wrapped.cp36-win_amd64.exp
descriptors.obj : error LNK2001: unresolved external symbol \
__imp_apr_hash_set
(it actually misses all symbols I've used, not just this one).
I've built the apr-1.lib by running nmake -f Makefile.win in APR's top-level directory before, and this is how I produced libapr-1.lib. Then I renamed to apr-1.lib it and put it in c:\dev\protopy\lib/apr, so the linker is actually able to find it, but it cannot find the required symbols...
Question 1
How can I see what symbols are in the library? (Maybe I compiled something wrong?)
OK, I found dumpbin.exe, but now I see that the symbol in the apr-1.lib is called __imp__apr_hash_set (notice the second double underscore), but the linker looks for __imp_apr_hash_set (single underscore). What gives? They were compiled with the same compiler / linker...
Question 2
Is there anything specific to building Python extensions on MS Windows that makes it work in this way? (I only tried this once in my life, and couldn't get it to work, but for different reasons).

According to APR project document
choose either aprutil or libaprutil (for static or dynamic libraries)
means apr-1.lib-->static and libapr-1.lib -->dynamic and
To target the static .lib versions of the library, the consuming compiliation must define the macros APR_DECLARE_STATIC and APU_DECLARE_STATIC. This prevents the apr and apr-util symbols from being tagged as __declspec(dllimport), eliminating compiliation warnings and speeding up execution.

Related

Unable to replicate Visual Studio Build

We have a Visual Studio 2015 driver project. For various reasons, we use "make" (the unix tool, built for windows) to build our entire product. It is also preferred to use make to build the windows-only components (keeps the build process consistent).
Running Server 2012R2, VS 2015 Update 3, DDK 10 and SDK 10.
The project builds fine in VS2015 and the driver works, so, the codebase is good.
I enabled the verbose build output and captured that to analyze what VS is doing to build the project (the driver is simply a bunch of C files, does not appear to be anything too earth-shatteringly unique). The VS build sets LIB, LIBPATH and INCLUDE variables, then issues a "cl.exe" command to build, followed by a "link.exe" command to link. There are also commands to build the message file (mc.exe) and resource file "rc.exe". I captured all of these commands and incorporated them into a makefile.
I can get the project to compile but, my problem is with the link phase. I will show the error in a few lines. I have tried simply running the commands (from the log) by themselves in a "VS2015 x64 Native Tools Command Prompt" (%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64) and I get the same error.
When I link, I get:
LINK : error LNK2001: unresolved external symbol GsDriverEntry
os_win.obj : error LNK2001: unresolved external symbol __stdio_common_vsprintf
winbuild\x64\Win7Release\driver.sys : fatal error LNK1120: 2 unresolved externals
I had to make one change from the cl.exe command line that VS logged, which was to specify /GS- (VS enabled the option). Otherwise, when I run the compile and link comands, I get a bunch of additional errors:
os_win.obj : error LNK2001: unresolved external symbol __security_cookie
So, Googling the vsprintf error, I came across suggestions to link with legacy_stdio_definitions.lib to access those functions, but that did not work (and using cygwin's nm.exe to examine the lib, showed that the vsprintf functions are Undefined.
If I build from the makefile, I lose the error about GsDriverEntry being undefined but I still have the vsprintf errors.
I tried also removing the /nodefaultlib link option... no effect.
So, I am at a complete loss as to what is going on. It makes no sense to me that, VS can build the project, but I cannot, using the same commands. What details or concept am I missing?
My link command line:
link /OUT:Win7Release/driver.sys \
/NOLOGO /INCREMENTAL:NO /IGNOREIDL /OPT:ICF /MAP /SUBSYSTEM:CONSOLE /OPT:REF \
/PDB:none /MACHINE:X64 /MANIFEST:NO /WX /PROFILE /kernel /Driver /RELEASE \
/VERSION:"10.0" /osversion:10.0 /ENTRY:"GsDriverEntry" \
/IGNORE:4198,4010,4037,4039,4065,4070,4078,4087,4089,4221,4108,4088,4218,4218,4235 \
/ERRORREPORT:PROMPT /MERGE:"_TEXT=.text;_PAGE=PAGE" /SECTION:"INIT,d" \
/IMPLIB:"Win7Release/driver.lib" /SUBSYSTEM:NATIVE",6.01" \
.. list of obj files .. \
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib \
shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib \
legacy_stdio_definitions.lib ntoskrnl.lib hal.lib wmilib.lib BufferOverflowK.lib
Okay, well, I found this post, which helped me earlier this year with another similar problem... seems that vsprintf is also declared inline, now. Setting _NO_CRT_STDIO_INLINE as /D option to cl.exe allows the code to build AND link.
So.. why would the Visual Studio 2015 project build properly? That define is NOT in the build output.

How can I find out which library is including libcmt?

I'm trying to link a Windows executable that depends on a several static libraries (some of which I have built, some of which I have not). When I do the link, I get a flock of errors like:
LIBCMT.lib(mlock.obj) : error LNK2005: _unlock already defined in MSVCRT.lib(MSVCR100.dll)
which is the classic /MD vs. /MT problem (whether the C runtime is statically or dynamically linked). I tried the easy solution first, adding the linker flags
/nodefaultlib:libcmt /nodefaultlib:libcpmt
but that just gave different errors:
msvcprt.lib(MSVCP100.dll) : error LNK2005: "public: __cdecl std::_Locinfo::~_Locinfo(void)" (??1_Locinfo#std##QEAA#XZ) already defined in gtest.lib(gtest-all.cc.obj)
gtest.lib(gtest-all.cc.obj) : error LNK2001: unresolved external symbol "private: static int std::locale::id::_Id_cnt" (?_Id_cnt#id#locale#std##0HA)
I've gone through the libraries I'm building, and as far as I can tell I'm building them all /MD. I say "as far as I can tell" because some of them are third-party libraries that come with their own makefiles so I don't have complete control over the build process..
I don't think "depends" works on libraries (only EXEs and DLLs), is there a tool that would let me look at the various libraries I'm linking in, and see which one is bringing in libcmt when I want to be using msvcrt instead?
I have had the same problem and I used dumpbin ( http://msdn.microsoft.com/en-us/library/z66yd3h6.aspx ) with /DIRECTIVES options on the libs. It will show a number of /DEFAULTLIB sections, each one is another lib that your lib try to use. Dumpbin needs to run from the Visual Studio command promt.
dumpbin /DIRECTIVES liblua52.lib
I had 100+ libs with all the solution configurations and platforms so I made a python 2.7 script (crtdisplay.py) to do it for me. It can be found on my bitbucket repository at https://bitbucket.org/vimarina/ctrlcv/src/57b7ddca15b5c7fefddcf20ffcea0633223a4bd6/crtdisplay . Put it in the root directory of your libs. Not much error checking in that code so do not be surprised if it fails :). I used Visual Studio 2010 so might fail on other versions of Visual Studio.
crtdisplay.py > info.txt

Building with Visual Studio 2010, MFC, and FFmpeg

I'm working on building a Windows MFC application in Visual Studio 2010 using FFmpeg and SDL. However, I can't get the project to build after creating an MFC project from scratch and including the FFmpeg development libraries (avcodec.lib, avdevice.lib, avformat.lib, etc.). I'm using the development build from Zeranoe FFmpeg. I have configured the following in the Project Properties:
Set VC++ Directories -> Include Directories (added the FFmpeg "include" directories)
Set VC++ Directories -> Library Directories (to the FFmpeg "lib" directory)
Set Linker -> Input -> Additional Dependencies (to include avcodec.lib, etc.)
For what it's worth, the build succeeds when I omit FFmpeg's "include\libavutil" include from the VC++ Directories -> Include Directories.
Below are some of the first build errors I'm receiving (I won't post all, since it's long). Any help would be appreciated.
ClCompile:
stdafx.cpp
c:\program files\microsoft visual studio 10.0\vc\atlmfc\include\atltime.h(371): error C3861: '_mktime64': identifier not found
c:\program files\microsoft visual studio 10.0\vc\atlmfc\include\atltime.h(386): error C3861: '_localtime64_s': identifier not found
c:\program files\microsoft visual studio 10.0\vc\atlmfc\include\atltime.h(409): error C3861: '_gmtime64_s': identifier not found
c:\program files\microsoft sdks\windows\v7.0a\include\intsafe.h(144): warning C4005: 'INT8_MIN' : macro redefinition
c:\program files\microsoft visual studio 10.0\vc\atlmfc\include\afxtaskspane.h(279): error C2146: syntax error : missing ';' before identifier 'm_nLastAnimTime'
c:\program files\microsoft visual studio 10.0\vc\atlmfc\include\afxribboncategory.h(282): error C2146: syntax error : missing ';' before identifier 'm_ActiveTime'
c:\program files\microsoft visual studio 10.0\vc\atlmfc\include\afxdockingmanager.h(353): error C2146: syntax error : missing ';' before identifier 'm_clkLastTime'
Build FAILED.
I've referenced both of these articles, which were of help:
Visual Studio and libavcodec
Visual Studio and SDL
I think what you did is this. When you did your first 2 steps
Set VC++ Directories -> Include Directories (added the FFmpeg
"include" directories)
Set VC++ Directories -> Library Directories
(to the FFmpeg "lib" directory)
You have included them at the top of the list before MFC and ATL paths. Please move them to the bottom of the list using the up/down buttons. This should solve the problem
Have a look at Use FFmpeg in Visual Studio - it has a link to small Visual Studio 2010 project that builds against Zeranoe binaries.
Note that you need a inttypes.h file to succeed in building.
Your log shows issues with stdafx.cpp and this means that you have either search paths set wrong, or something is wrong in stdafx.h. Putting FFmpeg directories on top of search list might work out, however it might equally well break building for MFC part. I would rather have them on the bottom of the list, however the code itself should have the correct order of explicit #includes.

Building/Using CppUnit Library on VS2010

I downloaded and compiled CppUnit to compile with Visual Studio 2010.
After the conversion, I could load the CppUnitLibraries, and it gives me cppunit.lib and cppunit_dll.lib/dll. After copying the headers and libs to a directory, I run this command to get a lot of errors.
I found the conflict of libraries as follows
LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library
However, the following command doesn't seem to work.
cl main.cpp complex.cpp testset.cpp /I"C:\CppUnit\include" /link /libpath:"C:\CppUnit\lib" cppunit.lib /NODEFAULTLIB:library
What's wrong with them?
This is the command that I used for compilation/link.
cl main.cpp complex.cpp testset.cpp /I"C:\CppUnit\include" /link /libpath:"C:\CppUnit\lib" cppunit.lib
This is the error message from VS2010.
cppunit.lib(TestResult.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL':
...
node###Z) already defined in LIBCMT.lib(typinfo.obj)
LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:lib
rary
main.exe : fatal error LNK1169: one or more multiply defined symbols found
ADDED
The CppUnit provides older version of project file (dsw), so I needed to convert the file to 2010 solution project manually.
For the error, missing /MD for compilation was the source of the problem. For other compilation warning, I needed to add /EHsc parameter.
cl /EHsc /MD /c /I"./CppUnit/include" main.cpp testset.cpp complex.cpp
link /libpath:"CppUnit/lib" main.obj testset.obj complex.obj cppunit.lib /out:cpptest_static.exe
link /libpath:"CppUnit/lib" main.obj testset.obj complex.obj cppunit_dll.lib /out:cpptest_dynamic.exe
seems like you compiled CppUnit in debug mode, weheras you're now compiling your current files in release mode. Those should not be mixed, and that's what the compiler is telling you.
The quickest way to resolve this would probably be to use a VS project, and check it's settings against the project used to compile CppUnit.
on your edit: you're also mixing runtime libraries (eg check that both are compiled using the /MD switch aka Multi-Threaded DLL)
I upgraded my CPPUNIT projects to visual studio 2010 and had to manually fix it.
The problem in the build was in the final actions where the output files are copied.
For the cppunit_dll project, one of the custom commands is:
copy "$(TargetPath)" ..\..\lib\$(TargetName).dll
copy "$(TargetDir)$(TargetName).lib" ..\..\lib\$(TargetName).lib
$(TargetName) is "cppunit_dll".
This conflicts with what we're actually building: if you look at the Linker options, you see that the output file name is "cppunitd_dll.dll".
The solution I used is to go to ConfigurationPropertys\General, and change "Target Name" from $(ProjectName) to"cppunitd_dll".
I had to to a similar solution for the cppunit project.
read INSTALL-VS.Net2008.txt in the cppunit folder after checking out the source code from SVN.
basically:
there is a visual studio solution under the examples folder.
that being said... i still can't get it to build without errors on vs2010 after converting it. i get 'cmd.exe' failed and failures to copy dlls.

setting up GLEW windows?

I have visual studio 2010 and I want to set up glew.h on it.
i do this step but still I have linker error:
1.download glew pack
2.copy .h files to C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include
3.copy .lib files to C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib
4.copy glew32.dll to C:\Windows\SysWOW64
5.and finally go to myproject properties then go to linker->input add glew32.lib,
glu32.lib, and opengl32.lib to Additional Dependencies
but I still have this error:
error LNK2001: unresolved external symbol __imp____glewBlendEquation
I've been confronted to the same issue today, so even if I'm one month late for the answer, just add GLEW_STATIC to your preprocessor's definitions.
That's a common problem. Just download the source, recompile it and it will work.

Resources