Skip to content

Link libcurl statically #24

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

Merged
merged 1 commit into from
Oct 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 63 additions & 17 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ if (${WIN32})
else (${WIN32})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")
endif (${WIN32})
message("C flags: ${CMAKE_C_FLAGS} .")

# driver's source dir
set(DRV_SRC_DIR driver)
Expand Down Expand Up @@ -176,49 +175,91 @@ aux_source_directory(${CTIMESTAMP_PATH_SRC}/ DRV_SRC)
#
set(LIBCURL_PATH_SRC ${CMAKE_SOURCE_DIR}/libs/curl CACHE PATH
"Lib curl source path")
set(LIBCURL_BUILD_TYPE debug CACHE STRING
"Lib curl build type: debug (default) or release")
set(LIBCURL_LINK_MODE static CACHE STRING
"Lib curl linking mode: static (default) or dll")

if (${LIBCURL_BUILD_TYPE} MATCHES debug)
set(LIBCURL_DEBUG_ENABLED yes)
set(LIBCURL_BUILD_SUFFIX _debug)
else (${LIBCURL_BUILD_TYPE} MATCHES debug)
set(LIBCURL_DEBUG_ENABLED no)
# empty LIBCURL_BUILD_SUFFIX
endif (${LIBCURL_BUILD_TYPE} MATCHES debug)

set(LIBCURL_LD_PATH
# Curl "installs" the .dll and .lib in different directories -> use the
# build dir to find both files in same directory instead of installing.
# Curl's win build root directory is not configurable.
# The path built below is only constant for the subtree tag (current:
# 7.61.0) and it's default nmake options (only with: IPv6, SSPI, WinSSL).
${LIBCURL_PATH_SRC}/builds/libcurl-vc-${TARCH}-release-dll-ipv6-sspi-winssl-obj-lib/
# 7.61.0) and default/below nmake options (only with: IPv6, SSPI, WinSSL).
${LIBCURL_PATH_SRC}/builds/libcurl-vc-${TARCH}-${LIBCURL_BUILD_TYPE}-${LIBCURL_LINK_MODE}-ipv6-sspi-winssl-obj-lib/
CACHE PATH "Lib curl load library path")
set(LIBCURL_INC_PATH ${LIBCURL_PATH_SRC}/include CACHE PATH
"Lib curl include path")

# Build libcurl.
# Note: this happens at config time as a pre-requisite, for now. This might
# be changed to a build target later (possibly as a CMake subproject).
if (NOT IS_DIRECTORY ${LIBCURL_LD_PATH})
# Note: building libcurl happens at config time (as a pre-requisite), for
# now. This might be changed to a build target later.
# TODO: add non-WiN32 building.
execute_process(COMMAND buildconf.bat
RESULT_VARIABLE CMD_RETURN
WORKING_DIRECTORY "${LIBCURL_PATH_SRC}"
)
if (NOT ${CMD_RETURN})
execute_process(COMMAND nmake /f Makefile.vc mode=dll MACHINE=${TARCH}
execute_process(COMMAND
nmake /f Makefile.vc mode=${LIBCURL_LINK_MODE} MACHINE=${TARCH}
ENABLE_WINSSL=yes ENABLE_IDN=yes ENABLE_IPV6=yes ENABLE_SSPI=yes
# build type needs to be synchronized (to link in the same CRT)
DEBUG=${LIBCURL_DEBUG_ENABLED}
# This "sneaks in" a define to disable all other protocols than
# HTTP in libcurl. There's currently (7.61.1) no way of doing this
# on Windows, without patching library's code/makefiles (or using
# currently still "poorly maintained" CMake generation).
# Ideally, one would use ${CMAKE_CXX_COMPILER} here. However,
# curl's makefile simply expects a 'cl.exe' available in the PATH.
"CC=cl.exe /DHTTP_ONLY"
RESULT_VARIABLE CMD_RETURN
WORKING_DIRECTORY "${LIBCURL_PATH_SRC}/winbuild"
)
endif (NOT ${CMD_RETURN})
if (${CMD_RETURN})
message(FATAL_ERROR "Building libcurl failed:")
message(FATAL_ERROR "Building libcurl failed.")
endif (${CMD_RETURN})
endif(NOT IS_DIRECTORY ${LIBCURL_LD_PATH})

# add libcurl as dependency
add_library(libcurl SHARED IMPORTED)
if (${WIN32})
set_property(TARGET libcurl PROPERTY IMPORTED_LOCATION
${LIBCURL_LD_PATH}/libcurl${CMAKE_SHARED_LIBRARY_SUFFIX})
set_property(TARGET libcurl PROPERTY IMPORTED_IMPLIB
${LIBCURL_LD_PATH}/libcurl${CMAKE_STATIC_LIBRARY_SUFFIX})
if (${LIBCURL_LINK_MODE} MATCHES dll)
add_library(libcurl SHARED IMPORTED)
set_property(TARGET libcurl PROPERTY IMPORTED_LOCATION
${LIBCURL_LD_PATH}/libcurl${LIBCURL_BUILD_SUFFIX}${CMAKE_SHARED_LIBRARY_SUFFIX})
set_property(TARGET libcurl PROPERTY IMPORTED_IMPLIB
${LIBCURL_LD_PATH}/libcurl${LIBCURL_BUILD_SUFFIX}${CMAKE_IMPORT_LIBRARY_SUFFIX})
# empty LIBCURL_WIN_LIBS
else (${LIBCURL_LINK_MODE} MATCHES dll)
add_library(libcurl STATIC IMPORTED)
set_property(TARGET libcurl PROPERTY IMPORTED_LOCATION
${LIBCURL_LD_PATH}/libcurl_a${LIBCURL_BUILD_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /DCURL_STATICLIB")
# Libraries that libcurl/WinSSL links against.
# Removed: wldap32 advapi32 gdi32 user32 (wth current config unused)
set(LIBCURL_WIN_LIBS ws2_32 crypt32 normaliz)
endif (${LIBCURL_LINK_MODE} MATCHES dll)
else (${WIN32})
set_property(TARGET libcurl PROPERTY IMPORTED_LOCATION
${LIBCURL_LD_PATH}/libcurl${CMAKE_SHARED_LIBRARY_SUFFIX})
endif (${WIN32})

add_custom_target(curlclean
COMMAND nmake /f Makefile.vc mode=dll clean
WORKING_DIRECTORY "${LIBCURL_PATH_SRC}/winbuild"
COMMAND nmake /f Makefile.vc mode=${LIBCURL_LINK_MODE} clean
COMMAND ../buildconf.bat -clean
WORKING_DIRECTORY "${LIBCURL_PATH_SRC}/winbuild"
)


message("C flags: ${CMAKE_C_FLAGS} .")
message("Driver source files: ${DRV_SRC} .")
message("Driver include paths: " ${ODBC_INC} ${DRV_SRC_DIR}
${LIBCURL_INC_PATH} ${UJSON4C_INC} ${CTIMESTAMP_PATH_SRC})
Expand All @@ -237,7 +278,8 @@ target_compile_definitions(${DRV_NAME} PRIVATE "DRIVER_BUILD")
include_directories(${ODBC_INC} ${DRV_SRC_DIR} ${LIBCURL_INC_PATH}
${UJSON4C_INC} ${CTIMESTAMP_PATH_SRC})

target_link_libraries(${DRV_NAME} odbccp32 legacy_stdio_definitions libcurl)
target_link_libraries(${DRV_NAME} odbccp32 legacy_stdio_definitions libcurl
${LIBCURL_WIN_LIBS})

# add testing project/target
enable_testing()
Expand All @@ -258,9 +300,13 @@ set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY TRUE)
# add instalation project/target
install(FILES
LICENSE.rtf LICENSE.txt
DESTINATION ${INSTALL_DIR})
if (${LIBCURL_LINK_MODE} MATCHES dll)
install(FILES
# need to use FILE : https://public.kitware.com/Bug/view.php?id=14311
${LIBCURL_LD_PATH}/libcurl${CMAKE_SHARED_LIBRARY_SUFFIX}
${LIBCURL_LD_PATH}/libcurl${LIBCURL_BUILD_SUFFIX}${CMAKE_SHARED_LIBRARY_SUFFIX}
DESTINATION ${INSTALL_DIR})
endif (${LIBCURL_LINK_MODE} MATCHES dll)
install(TARGETS ${DRV_NAME}
DESTINATION ${INSTALL_DIR})

Expand Down
49 changes: 28 additions & 21 deletions build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,6 @@ if /i not [%ARG:install=%] == [%ARG%] (
call:PACKAGE_CONF
)

REM presence of type: invoke BUILDTYPE "function"
if /i not [%ARG:type=%] == [%ARG%] (
call:BUILDTYPE
) else (
set BUILD_TYPE=Debug
set MSBUILD_ARGS=/p:Configuration=!BUILD_TYPE!
echo %~nx0: invoked without 'type', !BUILD_TYPE!-building (default^).
)

REM absence of nobuild: invoke BUILD "function";
REM 'all' and 'test' arguments presence checked inside the "function".
if /i [%ARG:nobuild=%] == [%ARG%] (
Expand Down Expand Up @@ -248,6 +239,7 @@ REM USAGE function: output a usage message
echo Extra development arguments:
echo nobuild : skip project building (the default is to build^).
echo genonly : generate project/make files, but don't build anything.
echo curldll : link libcurl dynamically.
echo exports : dump the exported symbols in the DLL after buildint it.
echo depends : dump the dependents libs of the build DLL.
echo regadd : register the driver into the registry;
Expand Down Expand Up @@ -313,7 +305,7 @@ REM INSTALL_CONF function: extract install location, if any; this will be
REM injected into the project files generated by cmake
:INSTALL_CONF
if exist ALL_BUILD.vcxproj (
echo %~nx0: NOTICE: project files already generated, install configuration skipped.
echo %~nx0: NOTICE: build files already generated, install configuration skipped.
goto:eof
)
if not [%INSTALL_DIR%] == [] (
Expand All @@ -339,7 +331,7 @@ REM PACKAGE_CONF function: extract versioning string, if any; this will be
REM injected into the project files generated by cmake
:PACKAGE_CONF
if exist ALL_BUILD.vcxproj (
echo %~nx0: NOTICE: project files already generated, package configuration skipped.
echo %~nx0: NOTICE: build files already generated, package configuration skipped.
goto:eof
)

Expand All @@ -363,18 +355,22 @@ REM injected into the project files generated by cmake

REM BUILDTYPE function: set the build config to feed MSBuild
:BUILDTYPE
REM cycle through the args, look for 'type:' token and use the
REM follow-up token
for %%a in (%ARG:"=%) do (
set crr=%%a
if /i ["!crr:~0,5!"] == ["type:"] (
set BUILD_TYPE=!crr:~5!
set MSBUILD_ARGS=/p:Configuration=!BUILD_TYPE!
echo %~nx0: setting the build type to: !MSBUILD_ARGS!.
goto:eof
if /i not [%ARG:type=%] == [%ARG%] (
REM cycle through the args, look for 'type:' token and use the
REM follow-up token
for %%a in (%ARG:"=%) do (
set crr=%%a
if /i ["!crr:~0,5!"] == ["type:"] (
set BUILD_TYPE=!crr:~5!
)
)
REM no check against empty val (type:) here
)
set MSBUILD_ARGS=
if [%BUILD_TYPE%] == [] (
set BUILD_TYPE=Debug
)
set MSBUILD_ARGS=/p:Configuration=!BUILD_TYPE!
echo %~nx0: setting the build type to: !BUILD_TYPE!.

goto:eof

Expand All @@ -383,15 +379,26 @@ REM BUILD function: build various targets
if not exist ALL_BUILD.vcxproj (
echo %~nx0: generating the project files.

REM set the wanted build type.
call:BUILDTYPE

set CMAKE_ARGS=-DDRIVER_BASE_NAME=%DRIVER_BASE_NAME%
REM no explicit x86 generator and is the default (MSVC2017 only?).
set CMAKE_ARGS=!CMAKE_ARGS! -DCMAKE_GENERATOR_PLATFORM=%TARCH:x86=%
if /i not [%ARG:curldll=%] == [%ARG%] (
set CMAKE_ARGS=!CMAKE_ARGS! -DLIBCURL_LINK_MODE=dll
)
if not [!INSTALL_DIR!] == [] (
set CMAKE_ARGS=!CMAKE_ARGS! -DINSTALL_DIR=!INSTALL_DIR!
)
if not [!PACKAGE_VER!] == [] (
set CMAKE_ARGS=!CMAKE_ARGS! -DVERSION_QUALIFIER=!PACKAGE_VER!
)
if /i [!BUILD_TYPE!] == [Debug] (
set CMAKE_ARGS=!CMAKE_ARGS! -DLIBCURL_BUILD_TYPE=debug
) else (
set CMAKE_ARGS=!CMAKE_ARGS! -DLIBCURL_BUILD_TYPE=release
)

echo %~nx0: cmake params: !CMAKE_ARGS!.
%CMAKE% !CMAKE_ARGS! !SRC_PATH!
Expand Down
16 changes: 16 additions & 0 deletions driver/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,15 @@ BOOL connect_init()
ERR("libcurl: failed to initialize: '%s' (%d).",
curl_easy_strerror(code), code);
return FALSE;
} else {
/* if libcurl is loaded, log main attributes (most relevant for dynamic
* loading). */
curl_version_info_data *curl_info = curl_version_info(CURLVERSION_NOW);
assert(curl_info);
/* these are available from "age" 0. */
INFO("Using libcurl version: %s, features: 0x%x, SSL ver.: %s.",
curl_info->version, curl_info->features,
curl_info->ssl_version ? curl_info->ssl_version : "NONE");
}

http_headers = curl_slist_append(http_headers, HTTP_ACCEPT_JSON);
Expand Down Expand Up @@ -310,6 +319,13 @@ static SQLRETURN dbc_curl_init(esodbc_dbc_st *dbc)
goto err;
}
}

/*
* TODO expose: CURLOPT_SSLVERSION, CURLOPT_SSLCERTTYPE
* CURLOPT_SSL_ENABLE_ALPN, CURLOPT_SSL_ENABLE_NPN,
* (CURLOPT_SSL_FALSESTART), CURLOPT_SSL_VERIFYSTATUS,
* CURLOPT_PROXY_*
*/
}

/* set authentication parameters */
Expand Down
12 changes: 8 additions & 4 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,14 @@ message("Test cases: ${TEST_CASES}")
set(EXTRA_SRC connected_dbc.cc)

# copy DLLs linked (later) against, so that test exes can load them
file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${DRV_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}
file(TO_NATIVE_PATH
${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${DRV_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}
SRC_PATH_ESODBC_DLL)
file(TO_NATIVE_PATH ${LIBCURL_LD_PATH}/libcurl${CMAKE_SHARED_LIBRARY_SUFFIX}
SRC_PATH_CURL_DLL)
if (${LIBCURL_LINK_MODE} MATCHES dll)
file(TO_NATIVE_PATH
${LIBCURL_LD_PATH}/libcurl${CMAKE_SHARED_LIBRARY_SUFFIX}
SRC_PATH_CURL_DLL)
endif (${LIBCURL_LINK_MODE} MATCHES dll)
file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR}/test/${CMAKE_CFG_INTDIR}/
DST_PATH_DLL)

Expand All @@ -83,7 +87,7 @@ add_custom_target(install_shared
# dir's otherwise created only later on test target execution
COMMAND if not exist ${DST_PATH_DLL} mkdir ${DST_PATH_DLL}
COMMAND xcopy /E /Y ${SRC_PATH_ESODBC_DLL} ${DST_PATH_DLL}
COMMAND xcopy /E /Y ${SRC_PATH_CURL_DLL} ${DST_PATH_DLL}
COMMAND if exist ${SRC_PATH_CURL_DLL} xcopy /E /Y ${SRC_PATH_CURL_DLL} ${DST_PATH_DLL}
# gtest->gtestd hack
# if googletest just built (i.e. not OS'es) AND the -d version exists
COMMAND if exist ${GTEST_NATIVE_PREFIX} if exist ${GTEST_LIBD}
Expand Down