find_package(ODBC) cause error on mingw-w64 cross compile
FindODBC.cmake does not work properly on mingw cross env.
When build a project depends on odbc on mingw-w64 environment in linux, a project fails with link error.
how to reproduce
CMakeLists.txt
cmake_minimum_required (VERSION 3.12)
project(odbc_example LANGUAGES C)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
find_package(ODBC)
set(CMAKE_CXX_STANDARD 11)
add_library(example SHARED example.c)
target_link_libraries(example PRIVATE ODBC::ODBC)
example.c
include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <odbcinst.h>
#include <winver.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
static BOOL
InUn(int remove, char *drivername, char *dllname, char *dll2name, char *dsname)
{
char path[301], driver[300], attr[300], inst[400], inst2[400];
WORD pathmax = sizeof (path) - 1, pathlen;
DWORD usecnt, mincnt;
usecnt = 0;
SQLInstallDriverEx(driver, NULL, path, pathmax, &pathlen,
ODBC_INSTALL_INQUIRY, &usecnt);
}
mingw-x86_64.toolchain.cmake
SET(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32/)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
What happens
This cause an error with CMake 3.12.3
-- The C compiler identification is GNU 4.8.2
-- Check for working C compiler: /usr/bin/x86_64-w64-mingw32-gcc
-- Check for working C compiler: /usr/bin/x86_64-w64-mingw32-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Found ODBC: odbc32.lib
-- Configuring done
-- Generating done
-- Build files have been written to: /vagrant/tmp/odbc/build
$ make
/opt/cmake-3.12.3-Linux-x86_64/bin/cmake -H/vagrant/tmp/odbc -B/vagrant/tmp/odbc/build --check-build-system CMakeFiles/Makefile.cmake 0
/opt/cmake-3.12.3-Linux-x86_64/bin/cmake -E cmake_progress_start /vagrant/tmp/odbc/build/CMakeFiles /vagrant/tmp/odbc/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/vagrant/tmp/odbc/build'
make -f CMakeFiles/example.dir/build.make CMakeFiles/example.dir/depend
make[2]: Entering directory `/vagrant/tmp/odbc/build'
cd /vagrant/tmp/odbc/build && /opt/cmake-3.12.3-Linux-x86_64/bin/cmake -E cmake_depends "Unix Makefiles" /vagrant/tmp/odbc /vagrant/tmp/odbc /vagrant/tmp/odbc/build /vagrant/tmp/odbc/build /vagrant/tmp/odbc/build/CMakeFiles/example.dir/DependInfo.cmake --color=
Scanning dependencies of target example
make[2]: Leaving directory `/vagrant/tmp/odbc/build'
make -f CMakeFiles/example.dir/build.make CMakeFiles/example.dir/build
make[2]: Entering directory `/vagrant/tmp/odbc/build'
[ 50%] Building C object CMakeFiles/example.dir/example.c.obj
/usr/bin/x86_64-w64-mingw32-gcc -Dexample_EXPORTS @CMakeFiles/example.dir/includes_C.rsp -o CMakeFiles/example.dir/example.c.obj -c /vagrant/tmp/odbc/example.c
[100%] Linking C shared library libexample.dll
/opt/cmake-3.12.3-Linux-x86_64/bin/cmake -E cmake_link_script CMakeFiles/example.dir/link.txt --verbose=1
/opt/cmake-3.12.3-Linux-x86_64/bin/cmake -E remove -f CMakeFiles/example.dir/objects.a
/usr/bin/x86_64-w64-mingw32-ar cr CMakeFiles/example.dir/objects.a @CMakeFiles/example.dir/objects1.rsp
/usr/bin/x86_64-w64-mingw32-gcc -shared -o libexample.dll -Wl,--out-implib,libexample.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -Wl,--whole-archive CMakeFiles/example.dir/objects.a -Wl,--no-whole-archive @CMakeFiles/example.dir/linklibs.rsp
CMakeFiles/example.dir/objects.a(example.c.obj):example.c:(.text+0x7a): undefined reference to `SQLInstallDriverEx'
collect2: error: ld returned 1 exit status
make[2]: *** [libexample.dll] Error 1
make[2]: Leaving directory `/vagrant/tmp/odbc/build'
make[1]: *** [CMakeFiles/example.dir/all] Error 2
make[1]: Leaving directory `/vagrant/tmp/odbc/build'
make: *** [all] Error 2
ToBe
There is a problem, -- Found ODBC: odbc32.lib
is wrong, which should be libodbc32.dll
or libodbc32.a
and then lead undefined reference to 'SQLInstallDriverEx'
.
When comment out line 93 in FindODBC.cmake
# List names of ODBC libraries on Windows
# set(ODBC_LIBRARY odbc32.lib)
set(_odbc_lib_names odbc32;)
then a build is success.
-- The C compiler identification is GNU 4.8.2
-- Check for working C compiler: /usr/bin/x86_64-w64-mingw32-gcc
-- Check for working C compiler: /usr/bin/x86_64-w64-mingw32-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Found ODBC: /usr/x86_64-w64-mingw32/lib/libodbc32.a
-- Configuring done
-- Generating done
-- Build files have been written to: /vagrant/tmp/odbc/build
vagrant@gdal-vagrant:/vagrant/tmp/odbc$ cd build/
vagrant@gdal-vagrant:/vagrant/tmp/odbc/build$ make
/opt/cmake-3.12.3-Linux-x86_64/bin/cmake -H/vagrant/tmp/odbc -B/vagrant/tmp/odbc/build --check-build-system CMakeFiles/Makefile.cmake 0
/opt/cmake-3.12.3-Linux-x86_64/bin/cmake -E cmake_progress_start /vagrant/tmp/odbc/build/CMakeFiles /vagrant/tmp/odbc/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/vagrant/tmp/odbc/build'
make -f CMakeFiles/example.dir/build.make CMakeFiles/example.dir/depend
make[2]: Entering directory `/vagrant/tmp/odbc/build'
cd /vagrant/tmp/odbc/build && /opt/cmake-3.12.3-Linux-x86_64/bin/cmake -E cmake_depends "Unix Makefiles" /vagrant/tmp/odbc /vagrant/tmp/odbc /vagrant/tmp/odbc/build /vagrant/tmp/odbc/build /vagrant/tmp/odbc/build/CMakeFiles/example.dir/DependInfo.cmake --color=
Scanning dependencies of target example
make[2]: Leaving directory `/vagrant/tmp/odbc/build'
make -f CMakeFiles/example.dir/build.make CMakeFiles/example.dir/build
make[2]: Entering directory `/vagrant/tmp/odbc/build'
[ 50%] Building C object CMakeFiles/example.dir/example.c.obj
/usr/bin/x86_64-w64-mingw32-gcc -Dexample_EXPORTS @CMakeFiles/example.dir/includes_C.rsp -o CMakeFiles/example.dir/example.c.obj -c /vagrant/tmp/odbc/example.c
[100%] Linking C shared library libexample.dll
/opt/cmake-3.12.3-Linux-x86_64/bin/cmake -E cmake_link_script CMakeFiles/example.dir/link.txt --verbose=1
/opt/cmake-3.12.3-Linux-x86_64/bin/cmake -E remove -f CMakeFiles/example.dir/objects.a
/usr/bin/x86_64-w64-mingw32-ar cr CMakeFiles/example.dir/objects.a @CMakeFiles/example.dir/objects1.rsp
/usr/bin/x86_64-w64-mingw32-gcc -shared -o libexample.dll -Wl,--out-implib,libexample.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -Wl,--whole-archive CMakeFiles/example.dir/objects.a -Wl,--no-whole-archive @CMakeFiles/example.dir/linklibs.rsp
make[2]: Leaving directory `/vagrant/tmp/odbc/build'
[100%] Built target example
make[1]: Leaving directory `/vagrant/tmp/odbc/build'
/opt/cmake-3.12.3-Linux-x86_64/bin/cmake -E cmake_progress_start /vagrant/tmp/odbc/build/CMakeFiles 0