Skip to content

Build fails on Windows (both mingw and VC++) with option -DEMBED_SSH_PATH #6254

Closed
@apnadkarni

Description

@apnadkarni

I have alternatives for fixes but need advice before making a pull request.

Reproduction steps

VC++

cmake  .. -A x64 -DBUILD_EXAMPLES=ON -DEMBED_SSH_PATH="D:/src/AAThirdparty/C,C++/libssh2-1.10.0" -DCMAKE_INSTALL_PREFIX="D:/temp/lg2" -DDEPRECATE_HARD=ON  -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
cmake --build .

MingW

cmake .. -G "MinGW Makefiles" -DBUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=Release -DUSE_BUNDLED_ZLIB=ON -DEMBED_SSH_PATH=/d/src/AAThirdparty/C,C++/libssh2-1.10.0 -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON  -DDEPRECATE_HARD=ON
cmake --build .

Expected behavior

Build completes successfully as it did for 1.3.0.

Actual behavior

Build fails. See below for diagnosis and details.

Version of libgit2 (release number or SHA1)

1.4.x, main (1.5.x)

Operating system(s) tested

Windows, MingW and VC++

Details

There are multiple issues with the EMBED_SSH_PATH option. The first is that the libssh is built twice - once directly via src/CMakeLists.txt and then again via the include of SelectSSH.

Clearly one of these has to be removed. Both alternatives lead to further issues as below.

Alternative 1 - keep the include SelectSSH

The cleaner alternative would seem to be to keep the include SelectSSH and remove fragment at src/CMakeLists.txt. This requires some additional fixes to SelectSSH.cmake as otherwise it picks up libssh headers from the MingW system directory instead of from the
EMBED_SSH_PATH directory. This breaks the build with undefines symbols if (as in my case) the latter is a newer version than the one with MingW. Also, need the bcrypt library to be added.

@@ -34,8 +34,12 @@ if(WIN32 AND EMBED_SSH_PATH) 
         list(APPEND LIBGIT2_DEPENDENCY_OBJECTS ${SSH_SRC})
         list(APPEND LIBGIT2_DEPENDENCY_INCLUDES "${EMBED_SSH_PATH}/include")        
+       include_directories("${EMBED_SSH_PATH}/include")                           
+       list(APPEND LIBGIT2_SYSTEM_LIBS "crypt32" "bcrypt")                         
+       list(APPEND LIBGIT2_PC_LIBS "-lcrypt32" "-lbcrypt") 
          file(WRITE "${EMBED_SSH_PATH}/src/libssh2_config.h" "#define HAVE_WINCNG\n#define LIBSSH2_WINCNG\n#include \"../win32/libssh2_config.h\"")                  
           set(GIT_SSH 1) 
endif() 

With this change and deletion of the src/CMakeLists.txt fragment building libssh, mingw builds work correctly and all tests pass.
However, Visual Studio builds fail with errors I cannot decipher :-( due to being lost in cmake and visual studio build environments. It's quite possibly something simple in configuration but having spent most of the day, I can't spend more time on it.

...just a sampling of many similar errors...
D:\src\AAThirdparty\C,C++\libssh2-1.10.0\src\scp.c(742): error C2039: 'st_mtim': is not a member of '_stat64' [D:\src\libgit2\vc64\tests\libgit2_tests.vcxproj
"D:\src\libgit2\vc64\src\git2.vcxproj" (default target) (7) ->
(ClCompile target) -> 
  D:\src\AAThirdparty\C,C++\libssh2-1.10.0\src\agent.c : fatal error C1083: Cannot open precompiled header file: 'git2.dir\Debug\git2.pch': No such file or directory [D:\src\libgit2\vc64\src\git2.vcxproj]

The only place I see st_mtim is in win32_compat.h but cannot understand how that impacts libssh. The error with git2.pch is because that file is not being generated (or should it really be looking for git2internal.h?)

Alternative 2 - use the fragment in Cmakelists.txt, and eliminate SelectSSH

(This would be only if EMBED_SSH_PATH was defined on WIN32). This needs the following changes:

The line set_target_properties(git2internal PROPERTIES C_EXTENSIONS OFF) has to be removed (again under a EMBED_SSH_PATH define). Turning extensions off causes the compiler --std=gnu90 to --std=c90 which causes libssh build to fail because it uses the inline keyword which is not part of the C90 standard.

As above the bcrypt library also has to be added.

With these changes both mingw and VC++ builds are successful. The former has no test errors. The latter has 3 test errors, all of which are because it expects current drive to be C: and I'm running on D:.

I need further guidance as to which of the above approaches (or some other) is a better fix and be a suitable candidate for a pull request. Alternative 1 seems cleaner but I would need some help with diagnosing further as I'm a little lost in how that st_atim #define is getting picked up. For alternative 2, how does one limit the -std compiler setting to only impact libssh? Or is it ok to switch back to gnu90 mode?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions