-
Notifications
You must be signed in to change notification settings - Fork 80
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
MacOS compiler error on wcsnrtombs (UNICODE) #251 #252
Conversation
Nice! Assuming this passes the full test suite this PR is a win in my book. Thank you for the work! |
the total build actually has more compiling errors on the examples (unrelated to this) also the Cmake change , you probably want to clean it a bit, I ignored the previous ODBC detection
|
My original intent was to debug a nasty UNICODE string conversion in MacOS defined this macro, like you do
and then use std::u16string and do in the function call both a cast to SQLWCHAR* and the string to char* call
|
your API it's very intuitive to use , but the code itself seems more complicated than it needs to be a while ago, I did a simple ODBC C++ wrapper (no UNICODE) https://github.com/pedro-vicente/lib_odbc just old fashioned and effective C++ 03 |
I'm a firm believer that, at the API level, KISS (Keep It Simple Stupid) just passes the complexity on to the users of the API. Significant complexity is often required to offer your users the facility to keep their applications simple in the first place. |
Thanks for your PR!
The conversions in the nanodbc code is a bit complicated but for reasons:
AFAIS and IMHO, that would too simplistic for what nanodbc aims to offer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to update this PR to include only changes to test/base_test_fixture.h
and the CMake issue on OSX is solved in separate PR.
As I explained in previous comment, I'd prefer to use CMake 3.12 with FindODBC.cmake or incorporate detection logic from the Find-module in our configuration.
CMakeLists.txt
Outdated
if(UNIX) | ||
find_path(ODBC_INCLUDE sql.h ${find_opt}) | ||
if(NOT ODBC_INCLUDE) | ||
message(FATAL_ERROR "sql.h header file not found") | ||
else() | ||
message("-- Found sql.h header file at: " ${ODBC_INCLUDE}) | ||
endif() | ||
include_directories(${ODBC_INCLUDE}) | ||
find_library(ODBC_LIBRARY NAMES odbc PATHS "/usr/local/lib") | ||
if(NOT ODBC_LIBRARY) | ||
message(FATAL_ERROR "ODBC library not found$") | ||
else() | ||
message("-- Found ODBC library at: " ${ODBC_LIBRARY}) | ||
endif() | ||
set(lib_dep ${lib_dep} ${ODBC_LIBRARY}) | ||
endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry but I'm not convinced to this solution.
I'd rather prefer to switch to CMake 3.12 or later which provides FindODBC.cmake
module which I submitted a while (https://gitlab.kitware.com/cmake/cmake/-/merge_requests/2069) and is well tested on multiple Unix platforms.
If CMake 3.12 seems too new, then we should simply copy the detection from FindODBC.cmake
into nanodbc CMake configuration.
By the way, our CMake configuration does need some modernisation in general, and we should strive to make it target-based and avoid commands like include_directories
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, the CMake configuration for nanodbc definitely needs to be modernized. I'm not against updating to a newer version of CMake as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error that happens with your Cmake version
ld: library not found for -lodbc
is because you are setting an hard coded library relative name "odbc".
set(ODBCLIB odbc)
A possible solution is to use an absolute path for the library name.
Using
find_library(ODBC_LIBRARY NAMES odbc PATHS "/usr/local/lib")
it returns an absolute path, the recommended use
https://cmake.org/cmake/help/v3.2/command/link_directories.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other solution is to use the absolute path returned by
odbc_config --libs
-L/usr/local/Cellar/unixodbc/2.3.9/lib -lodbc
and then use a call to
https://cmake.org/cmake/help/latest/command/target_link_libraries.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one way to extract the absolute path
if(APPLE)
# string(SUBSTRING <string> <begin> <length> <output_variable>)
string(SUBSTRING ${ODBC_LINK_FLAGS} 2 -1 ODBCLIB_tmp) #trim first 3 characters "-L/"
message(STATUS "ODBCLIB_tmp = ${ODBCLIB_tmp}")
string(REPLACE " -lodbc" "" ODBCLIB_tmp ${ODBCLIB_tmp})
message(STATUS "ODBCLIB_tmp = ${ODBCLIB_tmp}")
set(ODBCLIB "${ODBCLIB_tmp}/libodbc.dylib")
message(STATUS "ODBCLIB = ${ODBCLIB}")
endif()
-- ODBCLIB_tmp = /usr/local/Cellar/unixodbc/2.3.9/lib -lodbc
-- ODBCLIB_tmp = /usr/local/Cellar/unixodbc/2.3.9/lib
-- ODBCLIB = /usr/local/Cellar/unixodbc/2.3.9/lib/libodbc.dylib
using
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error that happens with your Cmake version
ld: library not found for -lodbc
is because you are setting an hard coded library relative name "odbc".
set(ODBCLIB odbc)
Please, could you try CMake 3.12 or later with its FindODBC.cmake
?
dest += src.at(idx);
This is just
char s;
wchar_t d;
d = s;
and it's not the character conversion we want (std::widen
is not either).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you try CMake 3.12 or later with its FindODBC.cmake?
FindODBC.cmake found the correct library, but not the right include path;
So, I used it to set the library, and kept some of the old detection for the path
Regarding all string casts (that code was just a cast for the test), it's better that you decide what to use; pushed this version
https://github.com/pedro-vicente/nanodbc/commit/e3fd3d430a4fe4a6991cde665d2e1dacf83809b5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for testing.
FindODBC.cmake found the correct library, but not the right include path;
Can you tell what is the right include path?
Was the unixODBC installed from the official packages?
It's important to remember that CMake Find-modules, in general, are just guessers and as such they do not promise to accurately detect every library in every environment, and that is why Find-modules provide variables a user can define to workaround such limitations, as I explain here https://gitlab.kitware.com/cmake/cmake/-/merge_requests/2069#note_410663
The Find*.cmake modules are "guessers" only.
So, the module has some detection logic for find_module, but users may find it useful to specify the non-standard or not inspected by the module locations viaODBC_INCLUDE_DIR
andODBC_LIBRARY
We need to draw a line how far we want to push complexity of CMake script we maintain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my bad, I had a missing call to
include_directories(${ODBC_INCLUDE_DIRS})
I installed with HomeBrew and doing
odbc_config --include-prefix
/usr/local/Cellar/unixodbc/2.3.9/include
gives me a different path than the FindODBC module does, but this path also contains the same file
-- ODBC include: /usr/local/include
-- ODBC library: /usr/local/lib/libodbc.dylib
-- ODBC config: /usr/local/bin/odbc_config
so, now only the call to FindODBC.cmake is present
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry but this PR has become a bit too tangled and I'm not confident it is ready to be merged.
So, I labelled it with work-in-progress
for now.
As I suggested in one of comments in this review round, @pedro-vicente, I'd extract simple PR that corrects the preprocessor conditions for LLVM.
Next, let's discuss upgrade to CMake 3.12
After we upgrade to CMake 3.12, we can try again to find out what issues still need to be fixed for Mac OS, and we address those.
Thank you for your work and help @pedro-vicente
/cc @lexicalunit lex
@@ -1,4 +1,5 @@ | |||
cmake_minimum_required(VERSION 3.0.0) | |||
cmake_minimum_required(VERSION 3.12) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lexicalunit What do you think about requiring CMake 3.12 and rely on FindODBC.cmake
?
See #252 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason not to bump all the way to 3.19?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lexicalunit I think, users who build nanodbc with CMake installed from packages of their OS distributions may complain.
Personally, I'm always on the latest CMake.
void nanodbc_to_str(std::wstring &dest, const nanodbc::string &src) | ||
{ | ||
for (size_t idx = 0; idx < src.size(); idx++) | ||
{ | ||
dest += src.at(idx); | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I explained in earlier comments, this is too simplistic.
auto const nid = std::stoll(sid); | ||
std::wstring tmp; | ||
nanodbc_to_str(tmp, sid); | ||
auto const nid = std::stoll(tmp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why this is needed
@@ -16,7 +16,7 @@ | |||
|
|||
#ifdef NANODBC_ENABLE_BOOST | |||
#include <boost/locale/encoding_utf.hpp> | |||
#elif defined(__GNUC__) && __GNUC__ < 5 | |||
#elif defined(__GNUC__) && __GNUC__ < 5 && !defined(__llvm__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I understand, this is needed for Mac OS regardless of changes to the CMakeLists.txt
.
If that is correct, then I'd suggest to submit the fix to these conditions in separate PR.
@lexicalunit am I right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's been a while since I compiled the library but I've only ever worked on macOS myself and I've never needed these. Maybe something changed within the last couple years? 🤷♀️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No idea, I don't use macOS myself.
Based on @pedro-vicente experience as reported in this issue, I assume that still is a problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR has 2 issues, I don't know what is the best way to fix, I'll wait for you to make a decision
-
issue 1 is Mac port
as seen in MacOS compiler error on wcsnrtombs (UNICODE) #251 this is the latest MacOS; since you don't have a Mac, I suggest to do whatever changes you feel must be done on this item, test it, and push here , and I'll test on the Mac -
issue 2 is CMake
I think, users who build nanodbc with CMake installed from packages of their OS distributions may complain.
the homebrew installed Cmake is
/usr/local/opt/cmake/bin/cmake --version
cmake version 3.18.4
so, that should be fine
What does this PR do?
Fix #251
What are related issues/pull requests?
Tasklist
Environment
Provide environment details, if relevant:
Fix described in
#251