CMakeFile produces VS2015 Projects with Link Errors #981

Closed
SparhawkSoftware opened this Issue Aug 25, 2016 · 18 comments

Projects

None yet

4 participants

@SparhawkSoftware
SparhawkSoftware commented Aug 25, 2016 edited

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
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
@SparhawkSoftware
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
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
Member
bagder commented Aug 25, 2016

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

@SparhawkSoftware

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
Member
jay commented Aug 25, 2016

-DBUILD_TESTING=OFF

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

@bagder
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
Member
snikulov commented Aug 26, 2016 edited

@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
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
Member
snikulov commented Aug 26, 2016 edited

@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
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.

@SparhawkSoftware
SparhawkSoftware commented Aug 26, 2016 edited

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
Member
bagder commented Aug 29, 2016

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

@snikulov
Member

@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
Member
bagder commented Aug 29, 2016 edited

@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.

@SparhawkSoftware
SparhawkSoftware commented Aug 29, 2016 edited

@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
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 jzakrzewski added a commit that referenced this issue Sep 9, 2016
@jzakrzewski jzakrzewski 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
6140dfc
@jzakrzewski jzakrzewski added a commit that closed this issue Sep 9, 2016
@jzakrzewski jzakrzewski CMake: Don't build unit tests if private symbols are hidden
This only excludes building unit tests from default build ( 'all' Make
target or "Build Solution" in VisualStudio). The projects and Make
targets will still be generated and shown in supporting IDEs.

Fixes #981
Reported-by: Randy Armstrong

Closes #990
257bf3a
@SparhawkSoftware
SparhawkSoftware commented Sep 14, 2016 edited

The fix does not work.
Need:

if (NOT CURL_HIDDEN_SYMBOLS)
    include(CTest)
    if(BUILD_TESTING)
        add_subdirectory(tests)
    endif()
endif()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment