0
votes

I need to compile arithchk.c (from the gdtoa library) on windows using visual studio 2013 running under cygwin. Everything was working fine with VS2008, but when I tried to switch to VS2013 I ran into this problem:

ladanyi@WIN64-01$ echo $LIB
;c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/LIB/amd64;c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/ATLMFC/LIB/amd64;c:/Program Files (x86)/Windows Kits/8.1/lib/winv6.3/um/x64;

ladanyi@WIN64-01$ echo $INCLUDE
;c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/INCLUDE;c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/ATLMFC/INCLUDE;c:/Program Files (x86)/Windows Kits/8.1/include/shared;c:/Program Files (x86)/Windows Kits/8.1/include/um;c:/Program Files (x86)/Windows Kits/8.1/include/winrt;

ladanyi@WIN64-01$ echo $PATH
:/cygdrive/c/Program Files (x86)/Microsoft Visual Studio 12.0/Common7/IDE:/cygdrive/c/Program Files (x86)/Microsoft Visual Studio 12.0/VC/BIN:/cygdrive/c/Program Files (x86)/Microsoft Visual Studio 12.0/Common7/Tools:/cygdrive/c/Program Files (x86)/Microsoft Visual Studio 12.0/VC/VCPackages:/cygdrive/c/Program Files (x86)/Windows Kits/8.1/bin/x64:/cygdrive/c/Program Files (x86)/Windows Kits/8.1/bin/x86:/usr/local/bin:/usr/bin:/bin:/usr/bin:/cygdrive/c/Program Files (x86)/Intel/Composer XE 2011 SP1/redist/intel64/ipp:/cygdrive/c/Program Files (x86)/Intel/Composer XE 2011 SP1/redist/intel64/mkl:/cygdrive/c/Program Files (x86)/Common Files/Intel/Shared Libraries/redist/intel64/compiler:/cygdrive/c/Windows/system32:/cygdrive/c/Windows:/cygdrive/c/Windows/System32/Wbem:/cygdrive/c/Windows/System32/WindowsPowerShell/v1.0:/cygdrive/c/Program Files/Microsoft SQL Server/110/Tools/Binn:/cygdrive/c/Program Files (x86)/Microsoft SDKs/TypeScript/1.0:/cygdrive/c/Program Files (x86)/Windows Kits/10/Windows Performance Toolkit:/cygdrive/c/Program Files/MATLAB/R2015b/bin

ladanyi@WIN64-01$ LIB="$LIB" INCLUDE="$INCLUDE" cl -DNO_FPINIT arithchk.c -DNO_LONG_LONG -DNO_SSIZE_T  /INCREMENTAL:NO /VERBOSE
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.40629 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

cl : Command line warning D9035 : option 'V' has been deprecated and will be removed in a future release
arithchk.c
Microsoft (R) Incremental Linker Version 12.00.40629.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:arithchk.exe 
arithchk.obj 
arithchk.obj : error LNK2001: unresolved external symbol _asin
arithchk.obj : error LNK2001: unresolved external symbol _exp
arithchk.obj : error LNK2001: unresolved external symbol _log
arithchk.obj : error LNK2001: unresolved external symbol _sqrt
arithchk.obj : error LNK2001: unresolved external symbol _acos
arithchk.obj : error LNK2019: unresolved external symbol ___iob_func referenced in function _main
arithchk.obj : error LNK2019: unresolved external symbol _fprintf referenced in function _main
arithchk.obj : error LNK2019: unresolved external symbol _printf referenced in function _ccheck
arithchk.obj : error LNK2019: unresolved external symbol __errno referenced in function _main
arithchk.obj : error LNK2019: unresolved external symbol @__security_check_cookie@4 referenced in function _Lcheck
arithchk.obj : error LNK2019: unresolved external symbol ___security_cookie referenced in function _Lcheck
arithchk.obj : error LNK2001: unresolved external symbol __fltused
LINK : error LNK2001: unresolved external symbol _mainCRTStartup
arithchk.exe : fatal error LNK1120: 13 unresolved externals

LIB and INCLUDE and PATH are set to what the results is when I run vcvarsall.bat in a command window.

I just can't figure out why are those symbols unresolved and would greatly appreciate any help.

Thanks, --Laci

UPDATE

If I open a DOS command prompt, run vcvarsall.bat, and then compile, then it works just fine. Note that after running vcvarsall.bat and doing an echo %LIB% and echo %INCLUDE% I get the same values as above. So the problem is in the interaction with cygwin somewhere, just I can't figure out where, yet :-(...

1
Two things jump out at me. First you have spaces in all of your paths, i.e. "c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/LIB/amd64". Spaces on the command line are normally what separates tokens. Secondly, I don't see you actually linking in libraries, you have the paths where libraries might be found, but I don't see any *.lib being used on the command line. You are not going to be able to compile arithchk.c and get an executable, as there is not main in that file.thurizas
The last function in that file is main().LaszloLadanyi
Yes, there are spaces in the variables, but I use, e.g., LIB="$LIB", i.e., the value of LIB is in quotes, so the spaces will not be token separators.LaszloLadanyi
Finally, on windows cl.exe is supposed to use the default libs (like msvcrt.lib) without having to explicitly list it (just like on linux with gcc you don't have to specify -lc).LaszloLadanyi
Don't know what to tell you. I don't have VS2013, but I can compile arithchk.c using the VS2010 command prompt by doing: cl -DNO_FPINIT arithchk.c -DNO_LONG_LONG -DNO_SSIZE_T /INCREMENTAL:NO /VERBOSE (I get the warning about option 'v' being deprecated. I'd suggest trying from a VS command shell rather then a cygwin shell (guessing you are using cygwin based on you echo commands).thurizas

1 Answers

0
votes

Verify the situation

Cygwin prepends /usr/local/bin:/usr/bin to PATH by default, and it is likely that the errors are due to Cygwin's GNU link tool being used despite how you have setup your environment. You may verify this with echo $PATH, and with link --version or which link.1

Quick fix

If this is the situation, then define the PATH variable in ~/.bash_profile so that the MSVC linker is found first. Since Cygwin stores the complete path from the Windows environment where it was started as ORIGINAL_PATH, you can use:

# Reorder PATH in .bash_profile
PATH="${ORIGINAL_PATH}/usr/local/bin:/usr/bin"

With PATH defined this way, Windows utilities will take precedence wherever there are conflicts with Cygwin utilities - the official docs mention find, link, and sort as examples.

The minimal route

Rather than taking the entire PATH from Windows, you may wish to take a more minimal route and define your new PATH with only those items you need. You can, of course, do this in .bash_profile, but also from Cygwin.bat itself before Cygwin is started. For example:

:: Minimal path defined in Cygwin.bat. Note the double quotes!
set PATH="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin"

Again, this is stored as ORIGINAL_PATH in Cygwin and then you change the default order as explained above. Just remember, the minimal approach can become a little "fiddly" for more complex scenarios as you work out dependencies, etc.

Start Cygwin with a selected environment

I usually prefer to keep it simple and put the Cygwin utilities at the end of the entire Windows PATH when I need to use MSVC or other Windows utilities. But not always, and I do like my tools flexible. In the following minimal example the standard Cygwin.bat file is modified so that one of a few predefined setups can be selected via a command line argument when Cygwin is started.

@echo off
if "%1"==""   (goto run-1)
if "%1"=="-m" (goto prepend-1)
if "%1"=="-w" (goto prepend-2)
if "%1"=="-h" (goto help-1)

:help-1
echo  Cygwin.bat: modifed to set PATH via command line arg
echo  ARG    Description
echo  (none) Default - Prepend Cygwin PATH to the full Windows PATH. [CYG,WIN]
echo  -m     Prepend only MSVC utilities to the Cygwin PATH (minimal approach). [MSVC,CYG]
echo  -w     Prepend full Windows PATH to the Cygwin PATH. [WIN,CYG]
echo  -h     Print this help msg and exit.
exit /b

:prepend-1
set MSVC_KW=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin
goto run-1

:prepend-2
set WIN_KW=1
goto run-1

:run-1
C:
chdir C:\cygwin64\bin
bash --login -i

This must be accompanied by reordering the path in .bash_profile as shown below.

# Modify the default PATH in .bash_profile according to KW from Cygwin.bat
if [ -n "${MSVC_KW}" ] ; then
    PATH="${MSVC_KW}:/usr/local/bin:/usr/bin"
    export PATH
    unset MSVC_KW
elif [ -n "${WIN_KW}" ] ; then
    PATH="${ORIGINAL_PATH}:/usr/local/bin:/usr/bin"
    export PATH
    unset WIN_KW
fi

1 See similar SO topics here and here. This answer adds to those.