New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMakeFile produces VS2015 Projects with Link Errors #981

Closed
randy-armstrong opened this Issue Aug 25, 2016 · 19 comments

Comments

Projects
None yet
5 participants
@randy-armstrong

randy-armstrong commented Aug 25, 2016

Ran cmake to create VS0125 projects with
-DHTTP_ONLY:BOOL=ON -DBUILD_CURL_EXE:BOOL=OFF
msbuild /p:Configuration=Debug CURL.sln

I expected it to work but a bunch of test programs failed with linker errors.

The cmake options don't make a difference.
Same problem with no options.

I reverted to 7_48_0 and everything was fine.

@bagder

This comment has been minimized.

Member

bagder commented Aug 25, 2016

Can you please show us some of those errors too?

@bagder bagder added the cmake label Aug 25, 2016

@randy-armstrong

This comment has been minimized.

randy-armstrong commented Aug 25, 2016

build\tests\unit\unit1603.vcxproj" (default target) (135) ->
  unit1603.obj : error LNK2019: unresolved external symbol _Curl_hash_init referenced in function _unit_setup [\src\curl\build\tests\unit\unit1603.vcxproj]
  unit1603.obj : error LNK2019: unresolved external symbol _Curl_hash_add referenced in function _test [src\curl\build\tests\unit\unit1603.vcxproj]
  unit1603.obj : error LNK2019: unresolved external symbol _Curl_hash_delete referenced in function _test [src\curl\build\tests\unit\unit1603.vcxproj]
  unit1603.obj : error LNK2019: unresolved external symbol _Curl_hash_pick referenced in function _test [src\curl\build\tests\unit\unit1603.vcxproj]
  unit1603.obj : error LNK2019: unresolved external symbol _Curl_hash_destroy referenced in function _unit_stop [src\curl\build\tests\unit\unit1603.vcxproj]
  unit1603.obj : error LNK2019: unresolved external symbol _Curl_hash_clean referenced in function _test [src\curl\build\tests\unit\unit1603.vcxproj]
  unit1603.obj : error LNK2019: unresolved external symbol _Curl_hash_str referenced in function _test [src\curl\build\tests\unit\unit1603.vcxproj]
  unit1603.obj : error LNK2019: unresolved external symbol _Curl_str_key_compare referenced in function _unit_setup [src\curl\build\tests\unit\unit1603.vcxproj]
  src\curl\build\tests\unit\Debug\unit1603.exe : fatal error LNK1120: 8 unresolved externals [src\curl\build\tests\unit\unit1603.vcxproj]

    1 Warning(s)
    38 Error(s)
@bagder

This comment has been minimized.

Member

bagder commented Aug 25, 2016

Ok, yes the unit tests can only build with debug versions of libcurl since it requires that a bunch of otherwise hidden symbols are available - to get tested. As they're not part of the regular API, they're not reachable in a normal build.

I suppose the cmake build files need to skip building the unit tests unless that condition is met. That's what the autoconf based build does.

@bagder

This comment has been minimized.

Member

bagder commented Aug 25, 2016

I should add that all the 16xx tests (that are in tests/unit) are such unit tests.

@randy-armstrong

This comment has been minimized.

randy-armstrong commented Aug 25, 2016

A cmake option to disable all tests would be nice,
When you use cmake to build for Visual Studio you end up with a single solution and you cannot pick and choose which projects build to without using the GUI (which is not good for automated builds).

@jay

This comment has been minimized.

Member

jay commented Aug 25, 2016

-DBUILD_TESTING=OFF

I tried building the tests just now, I also ran into problems.

@bagder

This comment has been minimized.

Member

bagder commented Aug 25, 2016

Right, the cmake build should only try to build the unit tests when asked to build debug builds as otherwise it fails like this...

@snikulov

This comment has been minimized.

Member

snikulov commented Aug 26, 2016

@bagder @SparhawkSoftware @jay In fact Curl_hash_init symbols will be available if -DCURL_STATICLIB=ON because it's not exported as dllexport attribute.

@SparhawkSoftware So if you want to fix build use -DBUILD_TESTING=OFF or enable static linking with -DCURL_STATICLIB=ON (check appveyor configuration here https://ci.appveyor.com/project/curlorg/curl)

@bagder

This comment has been minimized.

Member

bagder commented Aug 26, 2016

It is probably still a good idea to have the build script check if the unit tests can get built before doing that, to avoid this build error.

@snikulov

This comment has been minimized.

Member

snikulov commented Aug 26, 2016

@bagder Linux exports all symbols by default. So all Curl_hash is in libcurl.so library.
So here you should decide if same for Windows and Curl_hash... should use dllexport.

@bagder

This comment has been minimized.

Member

bagder commented Aug 26, 2016

Aha! but that's a bug - it should hide symbols by default and what's what it does in the autoconf build! That's why the "regular" build can't be used for the unit test. Also, some unit tests use symbols that are otherwise marked static and I'm not sure they're always made available even if symbols aren't hidden.

@randy-armstrong

This comment has been minimized.

randy-armstrong commented Aug 26, 2016

Confirmed that -DBUILD_TESTING=OFF fixes my issue.

I should have noticed that flag in the CMAKE.

Adding this near the top would be nice:
option(BUILD_TESTING "This includes the unit tests. Only valid when building the static library" OFF)

@bagder

This comment has been minimized.

Member

bagder commented Aug 29, 2016

The build should simply not build the unit tests if it can't link them...

@snikulov

This comment has been minimized.

Member

snikulov commented Aug 29, 2016

@SparhawkSoftware According to documentation this option already there and ON by default.

@bagder So what's the decision? Are Curl_hash_ functions optional? From which build option it depends?

@bagder

This comment has been minimized.

Member

bagder commented Aug 29, 2016

@snikulov They're not "optional". They're internal functions that are tested with unit tests. Those functions are not public and will never be, they're not part of any official API. All functions in libcurl that start with an uppercase 'Curl' are like that. They're also subject to change at any time, but then we of course also need to update the tests.

@randy-armstrong

This comment has been minimized.

randy-armstrong commented Aug 29, 2016

@snikulov the option statement with a comment makes it clearer.

@bagder the issue comes from the way cmake works with VisualStudio because cmake adds all projects to a single solution and msbuild always builds all projects in the solution. It is not possible to not build the test projects without manually editing the outputs of cmake which defeats the purpose of using cmake.

@bagder

This comment has been minimized.

Member

bagder commented Aug 29, 2016

I'm just saying that when cmake is invoked, it can determine if the unit tests can get built or not and only if they can it should attempt that.

jzakrzewski added a commit that referenced this issue Sep 9, 2016

CMake: Try to (un-)hide private library symbols
Detect support for compiler symbol visibility flags and apply those
according to CURL_HIDDEN_SYMBOLS option.
It should work true to the autotools build except it tries to unhide
symbols on Windows when requested and prints warning if it fails.

Ref: #981 (comment)
Reported-by: Daniel Stenberg
@randy-armstrong

This comment has been minimized.

randy-armstrong commented Sep 14, 2016

The fix does not work.
Need:

if (NOT CURL_HIDDEN_SYMBOLS)
    include(CTest)
    if(BUILD_TESTING)
        add_subdirectory(tests)
    endif()
endif()
@pedro-vicente

This comment has been minimized.

pedro-vicente commented Jan 1, 2018

I have a similar problem, in Windows.
It's not in the curl build itself, but on a library (netcdf) that uses curl. When using

-DCURL_STATICLIB=ON

, the windows sockets library is missing from the curl library , so you get linking errors

libcurl-d.lib(select.obj) : error LNK2019: unresolved external symbol __imp__select@20 referenced in function _Curl_socket_check

one way to fix this is to manually edit the generated libcurl.vcxproj and add

<Lib>
      <AdditionalOptions>%(AdditionalOptions) /machine:X86 /machine:X86</AdditionalOptions>
      <AdditionalDependencies>ws2_32.lib</AdditionalDependencies>
    </Lib>

but this should be fixed in some way on the curl Cmake script

to reproduce the bug, do

https://github.com/pedro-vicente/nco_bld
cd nco_bld
clone.bat
bld.bat

this clones and builds curl and netcdf

for curl, it is used

cmake .. -G "Visual Studio 14 2015" ^
           -DCMAKE_BUILD_TYPE=Debug ^
           -DBUILD_SHARED_LIBS=OFF ^
           -DBUILD_TESTING=OFF ^
           -DHTTP_ONLY=ON ^
           -DENABLE_DEBUG=ON ^
           -DENABLE_CURLDEBUG=ON ^
           -DCURL_STATICLIB=ON
  msbuild curl.sln /target:build /property:configuration=debug

@lock lock bot locked as resolved and limited conversation to collaborators May 6, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.