Closed cgilles closed 5 years ago
If i replace :
ssize_t l = readlink (proc, path,sizeof(path)-1);
by : ssize_t l = 0; //readlink (proc, path,sizeof(path)-1);
All the core library compile fine.
[gilles@localhost build]$ make [ 20%] Built target xmp [ 48%] Built target exiv2lib_int Scanning dependencies of target exiv2lib [ 49%] Building CXX object src/CMakeFiles/exiv2lib.dir/futils.cpp.obj [ 50%] Building CXX object src/CMakeFiles/exiv2lib.dir/image.cpp.obj /mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/image.cpp:871:77: warning: unused parameter 'useCurl' [-Wunused-parameter] BasicIo::AutoPtr ImageFactory::createIo(const std::wstring& wpath, bool useCurl) ^ [ 51%] Building CXX object src/CMakeFiles/exiv2lib.dir/ini.cpp.obj [ 52%] Building CXX object src/CMakeFiles/exiv2lib.dir/iptc.cpp.obj [ 54%] Building CXX object src/CMakeFiles/exiv2lib.dir/jp2image.cpp.obj [ 55%] Building CXX object src/CMakeFiles/exiv2lib.dir/jpgimage.cpp.obj [ 56%] Building CXX object src/CMakeFiles/exiv2lib.dir/matroskavideo.cpp.obj [ 57%] Building CXX object src/CMakeFiles/exiv2lib.dir/metadatum.cpp.obj [ 58%] Building CXX object src/CMakeFiles/exiv2lib.dir/mrwimage.cpp.obj [ 60%] Building CXX object src/CMakeFiles/exiv2lib.dir/orfimage.cpp.obj [ 61%] Building CXX object src/CMakeFiles/exiv2lib.dir/pgfimage.cpp.obj [ 62%] Building CXX object src/CMakeFiles/exiv2lib.dir/preview.cpp.obj [ 63%] Building CXX object src/CMakeFiles/exiv2lib.dir/properties.cpp.obj [ 64%] Building CXX object src/CMakeFiles/exiv2lib.dir/psdimage.cpp.obj [ 65%] Building CXX object src/CMakeFiles/exiv2lib.dir/quicktimevideo.cpp.obj [ 67%] Building CXX object src/CMakeFiles/exiv2lib.dir/rafimage.cpp.obj [ 68%] Building CXX object src/CMakeFiles/exiv2lib.dir/riffvideo.cpp.obj [ 69%] Building CXX object src/CMakeFiles/exiv2lib.dir/rw2image.cpp.obj [ 70%] Building CXX object src/CMakeFiles/exiv2lib.dir/tags.cpp.obj [ 71%] Building CXX object src/CMakeFiles/exiv2lib.dir/tgaimage.cpp.obj [ 72%] Building CXX object src/CMakeFiles/exiv2lib.dir/tiffimage.cpp.obj [ 74%] Building CXX object src/CMakeFiles/exiv2lib.dir/types.cpp.obj [ 75%] Building CXX object src/CMakeFiles/exiv2lib.dir/utilsvideo.cpp.obj [ 76%] Building CXX object src/CMakeFiles/exiv2lib.dir/value.cpp.obj [ 77%] Building CXX object src/CMakeFiles/exiv2lib.dir/version.cpp.obj [ 78%] Building CXX object src/CMakeFiles/exiv2lib.dir/webpimage.cpp.obj [ 80%] Building CXX object src/CMakeFiles/exiv2lib.dir/xmp.cpp.obj [ 81%] Building CXX object src/CMakeFiles/exiv2lib.dir/xmpsidecar.cpp.obj [ 82%] Building CXX object src/CMakeFiles/exiv2lib.dir/pngimage.cpp.obj [ 83%] Linking CXX shared library ../bin/libexiv2.dll [100%] Built target exiv2lib
So the problem is only located to found a right replacement of readlink() call under Mingw, or to disable this function for the moment under MinGW.
As i can see, readlink() support is problematic, as symbolic link is completly different under Windows.
https://stackoverflow.com/questions/39785170/replacement-for-readlink-function-in-windows
Gilles
Patch to compile under Mingw with NLS support.
https://cgit.kde.org/digikam.git/tree/project/bundles/3rdparty/ext_exiv2/exiv2-0.27-mxe.patch
I use it with digiKam Windows bundle. Sound like the function getProcessPath() is only used with Exiv2 CLI tool, so we don't care as we use only the shared lib.
Gilles
Seasons Greetings.
getProcessPath()
was added about RC2 to assist the localisation code to find the pot files. I'm very surprised that it's creating trouble with MinGW. I believe it's only called from main() in exiv2.cpp.
From what you've said, this is inconvenient, but not preventing you from moving forward. The fix will be in Exiv2 v0.27.1 which I've scheduled for 31 March 2019.
My little finger tells me that a specific #define must be set before to include unistd.h from mingw to be able to use readlink().
As i can see, the function exists well in mingw header provided by MXE. So we must be able to use it Gilles
Look the unistd.h provided by MXE. Look especially the condition "#if __SSP_FORTIFY_LEVEL > 0" :
[gilles@localhost ssp]$ pwd /mnt/devel/GIT/6.x/project/bundles/mxe/build.win64/usr/lib/gcc/x86_64-w64-mingw32.shared/5.5.0/include/ssp
[gilles@localhost ssp]$ cat unistd.h /* Checking macros for unistd functions. Copyright (C) 2005, 2009 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.
In addition to the permissions in the GNU General Public License, the Free Software Foundation gives you unlimited permission to link the compiled version of this file into combinations with other programs, and to distribute those combinations without any restriction coming from the use of this file. (The General Public License restrictions do apply in other respects; for example, they cover modification of the file, and distribution when not linked into a combine executable.)
GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional permissions described in the GCC Runtime Library Exception, version 3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see http://www.gnu.org/licenses/. */
extern ssize_t SSP_REDIRECT (__read_alias, (int fd, void *__buf, size_t __nbytes), read);
extern inline attribute((always_inline__)) ssize_t read (int fd, void *buf, size_t nbytes) { if (ssp_bos0 (buf) != (size_t) -1 && nbytes > ssp_bos0 (buf)) chk_fail (); return __read_alias (fd, buf, __nbytes); }
extern int SSP_REDIRECT (__readlink_alias, (const char *restrict path, char *restrict __buf, size_t __len), readlink);
extern inline attribute((always_inline)) int readlink (const char *restrict path, char *restrict __buf, size_t len) { if (ssp_bos (__buf) != (size_t) -1 && len > ssp_bos (buf)) chk_fail (); return readlink_alias (path, buf, __len); }
extern char __SSP_REDIRECT (__getcwd_alias, (char __buf, size_t __size), getcwd);
extern inline attribute((always_inline)) char getcwd (char buf, size_t size) { if (ssp_bos (__buf) != (size_t) -1 && size > ssp_bos (buf)) chk_fail (); return getcwd_alias (buf, size); }
Thanks, Gilles. I'm very surprised by your report. Are you using MinGW/msys1.0 or MinGW/msys2?
I would like to have a break before digging into this. The effort to release v0.27 has been intense. Many 12 hour days.
I don't install Msys or mingw directly. I use MXE cross compiler envirronnement for Linux. There is no windows, and i will never install this stuff in the future on my computer : it's not my religion (:=)))
So MXE do the stuff very : all the whole shared lib are compiled like this for the digiKam Windows installer : Qt5, opencv, boost, ffmpeg, KDElibs, etc...
So, i'm sure that a simple solution can be found for this problem...
Due to my hard work in my office to port a giant Java code to Qt5, i was very busy for Open Source cake while the week ends, since more than 2 months... So it's the holidays, and now i can look over the next world again...
I know well the time to pass to release open source. It's never complete. It still always the 5% to kill in the list. So, for me this kind of situation are normal. You must to process by priority the most important problem first, the rest it's for later (:=)))
Gilles
Look like the path use to found unistd from mxe install : /mnt/devel/GIT/6.x/project/bundles/mxe/build.win64/usr/lib/gcc/x86_64-w64-mingw32.shared/5.5.0/include/ssp
It's G++ 5.5.0 so, it's probably MinGW 5.5.0 in background...
Gilles
We've been building with GCC 7.3.0 and the MinGW build is fine. I'll look at 5.5.0.
Relax and take your dog for a walk.
In all cases, the code below taken from getProcessPath() will never work under Windows through Mingw : /proc directory is Linux stuff, not Windows (:=)))...
// http://stackoverflow.com/questions/606041/how-do-i-get-the-path-of-a-process-in-unix-linux
char proc[100];
char path[500];
sprintf(proc,"/proc/%d/exe", getpid());
ssize_t l = readlink (proc, path,sizeof(path)-1); << =========== Do not exists under Mingw
if (l>0) {
path[l]=0;
ret = path;
}
If getProcessPath() function is only used by exiv2 CLI tool, I recommend to move this function inside the Exiv2 CLI implementation, not n th shared library. At least, this last one will still compilable alone without problem.
Separate well both parts from Exiv2 is always a good idea, as you can disable the CLI at configuration time with cmake options.
Gilles
I didn't write that code. I think Luis intends the WIN32 branch. It uses readlink on Linux (and possibly Cygwin). I think he cut'n'pasted the code from somewhere.
The code is working. I pulled down the MinGW64 build from exiv2.org. The command: $ exiv2 -vV --grep process --grep exec
is reporting the correct information. I know because I added the code to version.cpp to report processpath
by calling getProcessPath().
I'm building GCC 5.5.0 at the moment.
The code was copied from stackoverflow... I see the link in source code...
Can you explain to me how this code work with readlink() and /proc/... under Windows ?
This path is specific to Linux. With a cross compilation, you generate a binary target which will run on Windows without anything about a Linux env. emulation installed (as Cygwin for ex).
Do you mean that Mingw layer reroute the internal Windows process list to a emulation layer somewhere in memory for Posix compatibility ? So the process list is dupplicate to a "virtual" FS in memory as Linux like ?
Gilles Caulier
Windows manages processes in psapi (process api). Linux uses this /proc
magic. I believe (on Cygwin at any rate), the /proc APIs are implemented in cygwin1.dll.
I couldn't build GCC5.5.0 from source. ./configure complains about dependencies which I believe I have installed.
I have installed GCC 5.4.0, however the compiler dies on the first file at psdk_inc/_fd_types.h complaining about conflicts with fd_set.
I will instrument getProcessPath() with some printf's to find out how/why this code is working.
The code is executing the linux branch.
std::string getProcessPath()
{
std::string ret("unknown");
#if defined(WIN32)
printf("in WIN32\n";
HANDLE processHandle = NULL;
...
}
#elif defined(__APPLE__)
printf("in __APPLE__\n");
...
#elif defined(__linux__) || defined(__CYGWIN__) || defined(__MINGW__)
printf("in __linux__\n");
// http://stackoverflow.com/questions/606041/how-do-i-get-the-path-of-a-process-in-unix-linux
...
#endif
When I run from the command-line:
514 MSYS64:rmills@rmillsmm-w7:~/gnu/github/exiv2/buildserver/build $ bin/exiv2 -vVg process --grep executable
in __linux__
exiv2 0.27.0
in __linux__
processpath=/c/msys64/home/rmills/gnu/github/exiv2/buildserver/build/bin
executable=C:\msys64\home\rmills\gnu\github\exiv2\buildserver\build\bin\exiv2.exe
515 MSYS64:rmills@rmillsmm-w7:~/gnu/github/exiv2/buildserver/build $
The comment about stack overflow is in version.cpp. I put it there about 6 years ago. Luis copy and pasted that code when he implemented getProcessPath() for use in localisation. The code in version.cpp reports the files in the Windows FS, so executable=c:\msys64...
and Luis's getProcessPath() reports in the MinGW file-system so processpath=/c/msys64/home/rmills/gnu/github/exiv2/buildserver/build/bin
cygwin1.dll implements readlink()
. You can see it with nm -g --demangle cygwin1.dll | grep readlink
. MinGW/msys2 is derived from cygwin, however it loads different dlls:
513 MSYS64:rmills@rmillsmm-w7:~/gnu/github/exiv2/buildserver/build $ bin/exiv2 -vVg library
in __linux__
exiv2 0.27.0
in __linux__
library=C:\WINDOWS\SYSTEM32\ntdll.dll
library=C:\WINDOWS\System32\KERNEL32.DLL
library=C:\WINDOWS\System32\KERNELBASE.dll
library=C:\msys64\home\rmills\gnu\github\exiv2\buildserver\build\bin\msys-exiv2-27.dll
library=C:\msys64\usr\bin\msys-2.0.dll
library=C:\WINDOWS\System32\PSAPI.DLL
library=C:\WINDOWS\System32\WS2_32.dll
library=C:\WINDOWS\System32\RPCRT4.dll
library=C:\msys64\usr\bin\msys-gcc_s-seh-1.dll
library=C:\msys64\usr\bin\msys-stdc++-6.dll
library=C:\msys64\usr\bin\msys-intl-8.dll
library=C:\msys64\usr\bin\msys-iconv-2.dll
library=C:\msys64\usr\bin\msys-z.dll
library=C:\msys64\usr\bin\msys-expat-1.dll
library=C:\WINDOWS\System32\advapi32.dll
library=C:\WINDOWS\System32\msvcrt.dll
library=C:\WINDOWS\System32\sechost.dll
library=C:\WINDOWS\SYSTEM32\CRYPTBASE.DLL
library=C:\WINDOWS\System32\bcryptPrimitives.dll
514 MSYS64:rmills@rmillsmm-w7:~/gnu/github/exiv2/buildserver/build $
I think /usr/bin/msys-2.0.dll is something very like cygwin1.dll. It's a platform emulator that enables MinGW code to behave in a Linux like manner and the "transition" to the underlying Windows APIs happens there.
524 MSYS64:rmills@rmillsmm-w7:/usr/bin $ nm -g --demangle msys-2.0.dll | grep readlink
000000018011e5f0 T _sigfe_readlink
000000018011e5fe T _sigfe_readlinkat
00000001800e9b00 T readlink
000000018013e340 T readlinkat
525 MSYS64:rmills@rmillsmm-w7:/usr/bin $
The reason for the difference between version.cpp/dumpLibraryInfo() and futils.cpp/getProcessPath() is historical. I implemented dumpLibraryInfo() about 2012 and Luis implemented getProcessPath() a few weeks ago. Neither is better. Luis and I discussed the difference when I reviewed his PR for that change. #535
There's something different in your setup. It is unlikely that GCC 5.5 would deal with this in a fundamentally different way from GCC 7.3.0. I think you're using MinGW/msys1.0 which isn't supported by Exiv2 v0.27 because it was so troublesome. MinGW/msys2 works well.
Here's the output of uname -a
on the two platforms:
MinGW/msys1/32: MINGW32_NT-6.2 RMILLSMBP-W7 1.0.18(0.48/3/2) 2012-11-21 22:34 i686 Msys
Msys2/64: MSYS_NT-10.0 rmillsmm-w7 2.10.0(0.325/5/3) 2018-02-09 15:25 x86_64 Msys
This a very elderly 32 bit msys1.0 that is still on my laptop. The Msys2 is very recent (probably the current release). I believe it was installed in September 2018 when I started to work on releasing Exiv2 v0.27.
I know you like to build all the code that goes into DigiKam. Is it possible to Download the MinGW64 build from exiv2.org and just use it in DigiKam? Downloading and integrating our binary library might be a good work-around for this.
Whoops. I've read your comments about using MXE to cross-compile. This issue is coming from that environment. I have never got cross-compilation to work on Exiv2.
I agree that this is probably quite easy to fix. I'll see if I can build Exiv2 on the elderly MinGW/msys1.0 on the laptop. If I can get that to work, we'll know the solution. However let me have a break for Christmas and the family.
Best Wishes to you and your family for Christmas and New Year. And thank you for the effort you put into Exiv2. Luis, Dan and I appreciate your feedback and insights.
I've looked at building Exiv2 with msys/1.0. Impossible. I can't even build the dependencies expat and zlib. Further effort with msys/1.0 is almost certainly time wasted.
I've investigated cross-compiling. Perhaps this isn't so painful. Here's a good article about setting up Toolchain-cross-mingw32-linux.cmake
https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/cross_compiling/Mingw
And once we have that (in <exiv2dir>/cmake/Toolchain-cross-mingw32-linux.cmake
we should be able to build with:
$ cd <exiv2dir>
$ rm -rf build ; mkdir build ; cd build
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw32.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install
$ make
Here's Toolchain-cross-mingw32-linux.cmake
# the name of the target operating system
SET(CMAKE_SYSTEM_NAME Windows)
# Choose an appropriate compiler prefix
# for classical mingw32
# see http://www.mingw.org/
#set(COMPILER_PREFIX "i586-mingw32msvc")
# for 32 or 64 bits mingw-w64
# see http://mingw-w64.sourceforge.net/
set(COMPILER_PREFIX "i686-w64-mingw32")
#set(COMPILER_PREFIX "x86_64-w64-mingw32"
# which compilers to use for C and C++
find_program(CMAKE_RC_COMPILER NAMES ${COMPILER_PREFIX}-windres)
#SET(CMAKE_RC_COMPILER ${COMPILER_PREFIX}-windres)
find_program(CMAKE_C_COMPILER NAMES ${COMPILER_PREFIX}-gcc)
#SET(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
find_program(CMAKE_CXX_COMPILER NAMES ${COMPILER_PREFIX}-g++)
#SET(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
# here is the target environment located
SET(USER_ROOT_PATH /home/erk/erk-win32-dev)
SET(CMAKE_FIND_ROOT_PATH /usr/${COMPILER_PREFIX} ${USER_ROOT_PATH})
# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
This all smells of msvc (resource compilers and 32 bit). However, I'll work on this after Christmas. I feel we could add "support for cross-compiling" in 0.27.1 In the process of getting cross-compiling from Linux to Windows to work, I will encounter the issues which Gilles has encountered from MXE.
Hi guys. Thanks for reporting the issue and the investigation. I took a quick look to the issue but I cannot dedicate much time to this during the holidays. The problem comes from not treating MinGW as a first citizen in our CI system ... I'll investigate the way to add a MinGW job in Appveyor, test this functionality properly and fix the issue.
We had a short discussion about deprecating features in 0.28 on Friday and we released v0.27 on Thursday. We need to do more work on Exiv2 v0.28 and decide what we should be deprecated and what we intend to do about deprecating features. Getting the compiler to flag deprecated classes in "the dots" sounds like a good idea in addition to putting this information into the release notes.
Jenkins does our MinGW builds on Windows using Msys2. @cgilles is using MXE to cross-build on Linux for MinGW. I've never used that and I'm investigating what's involved. I kicked off MXE to build on an Ubuntu 18.04 VM about 7am this morning. 12 hours later it's still running and has consumed 10GB. It appears to have pulled down about 200 libraries (mostly Qt) and is building them for Windows.
I've also tried to directly cross-compile using the Toolchain stuff mentioned above. I can't get libz to build because I haven't cross-compiled something (LibC, I think). I tried to cross compile "hello world" and that also complained about missing libraries. I'm hoping MXE will deliver something functional.
You don't need to install whole MXE packages, but only few ones needs by Exiv2 to be crosscompiled, as G++ of course...
If you take a look to the script that i shared few week ago to cross compiled Exiv2 with MXE, all is listed. This will take only 30 mns to run. That all.
Gilles Caulier
I'm not sure what script you are talking about. I'm pulling down this: https://github.com/KDE/digikam.git
This is a curious bug report. It cannot be reproduced on our supported build platforms. It takes 24 hours to build/install MXE, then we we need digicam (1.5 million lines of code). And we do all of this on Linux to reproduce an issue on Windows. I know you're playing games with me.
The scripts you mentioned. Is this them? https://github.com/Exiv2/exiv2/issues/473
-rwxr-xr-x 1 gilles gilles 3358 oct. 13 13:49 bootstrap-exiv2.mxe*
-rwxr-xr-x 1 gilles gilles 4992 oct. 13 13:51 build-mxe.sh*
I'll deal with this later in the week. Time to relax and have some fun with the family.
Exaclty this script. No need more. With it you can cross compile Exiv2 as stand alone library for windows with the CLI tool if you turn on right cmake options.
That all. It's very simple and fast. You don't need to compile digiKam as you mention (:=)))...
Best
Gilles
Le lun. 24 déc. 2018 à 18:16, Robin Mills notifications@github.com a écrit :
I'm not sure what script you are talking about. I'm pulling down this: https://github.com/KDE/digikam.git
This is a curious bug report. It cannot be reproduced on our supported build platforms. It takes 24 hours to build/install MXE, then we we need digicam (1.5 million lines of code). And we do all of this on Linux to reproduce an issue on Windows. I know you're playing games with me.
The scripts you mentioned. Is this them? #473 https://github.com/Exiv2/exiv2/issues/473
-rwxr-xr-x 1 gilles gilles 3358 oct. 13 13:49 bootstrap-exiv2.mxe -rwxr-xr-x 1 gilles gilles 4992 oct. 13 13:51 build-mxe.sh
I'll deal with this later in the week. Time to relax and have some fun with the family.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Exiv2/exiv2/issues/610#issuecomment-449756525, or mute the thread https://github.com/notifications/unsubscribe-auth/ACd9eGoQYBkVIB6QPBZ6JxpOTiGdAileks5u8Qv5gaJpZM4ZfW15 .
Hello,
I'm facing the same issue. I'm using a custom built FreeBSD-to-Windows GCC-MinGW64 cross-compiler (GCC 8.2.0 and a very recent MinGW64 from their repository). Trying to build a static Exiv2 without NLS (-DEXIV2_ENABLE_SHARED=OFF -DEXIV2_ENABLE_NLS=OFF
).
It compiles fine with Exiv2 0.26, but the build process broken on 0.27.0.
I've run build-mxe.sh (1 hour 9 minutes)
rmills@rmillsmm-ubuntu:/media/psf/Home/gnu/github/exiv2/exiv2$ chmod +x ./build-mxe.sh
rmills@rmillsmm-ubuntu:/media/psf/Home/gnu/github/exiv2/exiv2$ ./build-mxe.sh
** (gedit:9896): WARNING **: 08:08:46.568: Could not load theme icon text-x-generic: Icon 'text-x-generic' not present in theme ubuntu-mono-dark
build-mxe.sh : build a bundle MXE install with Exiv2 dependencies.
-----------------------------------------------------------------------
Target Windows architecture: 32 bits.
CPU Cores to use : 1
Cloning into '/media/psf/Home/gnu/github/exiv2/exiv2/build.win32'...
** (gedit:9896): WARNING **: 08:08:46.587: Could not load theme icon text-x-generic: Icon 'text-x-generic' not present in theme ubuntu-mono-dark
Checking out files: 100% (1135/1135), done.
---------- Updating MXE
Already up to date.
---------- Building Exiv2 low level dependencies with MXE
[create settings.mk]
[check reqs]
[download] binutils-2.28.tar.bz2
[nonet lib] /media/psf/Home/gnu/github/exiv2/exiv2/build.win32/usr/x86_64-pc-linux-gnu/lib/nonetwork.so
[git-log] 1c77cfc0 qtdeclarative: fix build with gcc4.8
[build] mxe-conf i686-w64-mingw32.shared
[done] mxe-conf i686-w64-mingw32.shared 0 KiB 0m4.921s
[build] binutils i686-w64-mingw32.shared
[done] binutils i686-w64-mingw32.shared 0 KiB 3m0.245s
...
[build] pthreads i686-w64-mingw32.shared
[done] pthreads i686-w64-mingw32.shared 0 KiB 0m14.955s
Elaspsed time for script execution : 1 hours 9 minutes 26 seconds
rmills@rmillsmm-ubuntu:/media/psf/Home/gnu/github/exiv2/exiv2$
Then bootstrap-exiv2-mxe.sh. I had to read/edit the script to discover that it expects a full path to the build.win32 directory.
rmills@rmillsmm-ubuntu:/media/psf/Home/gnu/github/exiv2/exiv2$ ./bootstrap-exiv2-mxe.sh ${PWD}/build.win32
MXE target : 32 bits shared
Installing to /media/psf/Home/gnu/github/exiv2/exiv2/build.win32 for target i686-w64-mingw32.shared with build mode RelWithDebInfo and configure options -DBUILD_SHARED_LIBS=ON \
-DEXIV2_ENABLE_XMP=ON \
-DEXIV2_ENABLE_EXTERNAL_XMP=OFF \
-DEXIV2_ENABLE_PNG=ON \
-DEXIV2_ENABLE_NLS=ON \
-DEXIV2_ENABLE_PRINTUCS2=ON \
-DEXIV2_ENABLE_LENSDATA=ON \
-DEXIV2_ENABLE_VIDEO=OFF \
-DEXIV2_ENABLE_WEBREADY=OFF \
-DEXIV2_ENABLE_DYNAMIC_RUNTIME=OFF \
-DEXIV2_ENABLE_CURL=OFF \
-DEXIV2_ENABLE_SSH=OFF \
-DEXIV2_BUILD_SAMPLES=OFF \
-DEXIV2_BUILD_PO=OFF \
-DEXIV2_BUILD_EXIV2_COMMAND=ON \
-DEXIV2_BUILD_UNIT_TESTS=OFF \
-DEXIV2_BUILD_DOC=OFF \
-DEXIV2_TEAM_EXTRA_WARNINGS=OFF \
-DEXIV2_TEAM_WARNINGS_AS_ERRORS=OFF \
-DEXIV2_TEAM_USE_SANITIZERS=OFF \
-DEXIV2_ENABLE_WIN_UNICODE=OFF
MXE_BUILD_TARGETS = i686-w64-mingw32.shared
----- PATH ---------
/media/psf/Home/gnu/github/exiv2/exiv2/build.win32/usr/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
-----------------------------
== Using MXE wrapper: /media/psf/Home/gnu/github/exiv2/exiv2/build.win32/usr/bin/i686-w64-mingw32.shared-cmake
- cmake version 3.10.0
- warnings for unused CMAKE_POLICY_DEFAULT variables can be ignored
== Using MXE toolchain: /media/psf/Home/gnu/github/exiv2/exiv2/build.win32/usr/i686-w64-mingw32.shared/share/cmake/mxe-conf.cmake
== Using MXE runresult: /media/psf/Home/gnu/github/exiv2/exiv2/build.win32/usr/share/cmake/modules/TryRunResults.cmake
loading initial cache file /media/psf/Home/gnu/github/exiv2/exiv2/build.win32/usr/share/cmake/modules/TryRunResults.cmake
-- The CXX compiler identification is GNU 5.5.0
-- The C compiler identification is GNU 5.5.0
...
Then I run make. It has been downloading and building for several hours.
rmills@rmillsmm-ubuntu:/media/psf/Home/gnu/github/exiv2/exiv2/build.win32$ make
[build] mxe-conf i686-w64-mingw32.static
[done] mxe-conf i686-w64-mingw32.static 0 KiB 0m4.677s
[build] binutils i686-w64-mingw32.static
[done] binutils i686-w64-mingw32.static 0 KiB 2m50.916s
[build] mingw-w64 i686-w64-mingw32.static
[done] mingw-w64 i686-w64-mingw32.static 0 KiB 0m4.961s
[build] gcc i686-w64-mingw32.static
[done] gcc i686-w64-mingw32.static 0 KiB 31m19.560s
....
I hope it will finish today and I'll investigate the issue you're reported.
I expect those tools will work fine, once they are correctly installed and in working order.
@kamgha I have never succeeded in getting anything to cross-compile. This isn't about Exiv2. I have never even succeeded in getting hello.cpp to build. @cgilles advocates MXE as solid, fast and reliable, I am still to succeed on building in this environment.
We had a bug reported on GCC 8.2.0 in September. I was able to build static, however I could not build shared. I don't remember the setting of NLS. I'm confident that you can build with/without NLS.
The MinGW build is documented in README.md and works on Windows. If you don't have Windows, Microsoft provide developments VMs which are valid for 90 days. I've successfully built on that platform.
After another few hours of building, MXE dropped dead having not compiled a single line of Exiv2 code.
Makefile:796: recipe for target '/media/psf/Home/gnu/github/exiv2/exiv2/build.win32/usr/i686-w64-mingw32.static/installed/nettle' failed
make: *** [/media/psf/Home/gnu/github/exiv2/exiv2/build.win32/usr/i686-w64-mingw32.static/installed/nettle] Error 1
rmills@rmillsmm-ubuntu:/media/psf/Home/gnu/github/exiv2/exiv2/build.win32$ cmake --build . --target help
Error: could not load cache
rmills@rmillsmm-ubuntu:/media/psf/Home/gnu/github/exiv2/exiv2/build.win32$ cmake --build .
Error: could not load cache
rmills@rmillsmm-ubuntu:/media/psf/Home/gnu/github/exiv2/exiv2/build.win32$ make
[build] nettle i686-w64-mingw32.static
[done] nettle i686-w64-mingw32.static 0 KiB 0m34.772s
[download] gnutls-3.6.5.tar.xz
[build] gnutls i686-w64-mingw32.static
Failed to build package gnutls for target i686-w64-mingw32.static!
------------------------------------------------------------
guile/src/Makefile.am:117: warning: '%'-style pattern rules are a GNU make extension
configure: WARNING: unrecognized options: --enable-gtk-doc, --enable-gtk-doc-html, --enable-gtk-doc-pdf, --with-html-dir, --disable-doxygen
configure: error: pwd does not report name of working directory
Makefile:796: recipe for target 'build-only-gnutls_i686-w64-mingw32.static' failed
make[1]: *** [build-only-gnutls_i686-w64-mingw32.static] Error 1
make[1]: Leaving directory '/media/psf/Home/gnu/github/exiv2/exiv2/build.win32'
real 0m50.163s
user 0m32.980s
sys 0m6.118s
------------------------------------------------------------
[log] /media/psf/Home/gnu/github/exiv2/exiv2/build.win32/log/gnutls_i686-w64-mingw32.static
Makefile:796: recipe for target '/media/psf/Home/gnu/github/exiv2/exiv2/build.win32/usr/i686-w64-mingw32.static/installed/gnutls' failed
make: *** [/media/psf/Home/gnu/github/exiv2/exiv2/build.win32/usr/i686-w64-mingw32.static/installed/gnutls] Error 1
rmills@rmillsmm-ubuntu:/media/psf/Home/gnu/github/exiv2/exiv2/build.win32$
I don't intend to spend further time on this issue. The supported method of building Exiv2 for MinGW is to use msys2 as documented in README.md.
@kamgha I've been able to get onto your ssh server. That's very helpful. I'm going to have my breakfast (it's 09:15 in England) and then work on your server.
@cgilles is a very helpful and frequently contributes to Exiv2. He's a very productive and effective engineer. I have no doubt that MXE delivers happiness for him. I'm having a different and very frustrating experience.
...and i don't understand why... you arrive to this conclusion... With the 2 scripts that provide, you just run
That all. It's simple and fast. no more to do, excepted to run make in build directory crated by cmake and enjoy the compilation bug, if one exists.
I don't understand why you try to re-invent the wheel each time...
Voilà. I use MXE on a huge collection of codes and projects (open source or not), all configured with Cmake, and it's work as expected. Of course, i will discover some dysfunctions when i update some components to a major version, but nothing really complex to solve.
For me cross compiling is the ultimate solution, especially for Windows. I don't want to use the Windows stuff to compile and link, and particuliary the M$ compiler. It's THE waste of time for me. All is hosted on the same computer running Linux. No Windows, expected one to check install and runtime to to capture backtraces with DrMinGW. If i want to hack, i use QtCreator and the GDB provided inside. If i want to quickly fix a bug and test : I share the build directory between the Windows (running in virtual box) and the Linux host where i cross compile. I fix the code under Linux, i cross compile, and i run finaly the executable shared by Linux under the Windows target.
As 80% of 1.5M of C++ code from digiKam is based on Qt, the code is mostly the same for all platforms. No need to recreate the background implementation for each platform. It's a waste of time and already done with Qt5 framework. This speedup development and limit the low level bugs. I can concentrate on real application fixes and forget all the rest.
Gilles Caulier
@cgilles Our new friend @kamgha has provided me with SSH access to a Linux machine and I've reproduced his troubles with src/bascio.cpp and src/futils.cpp I'm optimistic that we'll get this fixed shortly.
I know you like MXE, CMake and other cross-platform tools. I'm doing my best to support you. We'll get there. We always do! You do things your way, and so do I. It's my sincere objective to get everything working for everybody!
I've had several emails and Skype discussions with @kamgha about this. I've found his build.sh
script on his ssh server to be very useful and easy to understand. I've crafted my own version of his script which I've included in a tar-ball along with the 64 bit DLLs required to enable the build run on wine. I've also included a patch for src/futils.cpp. These files should be added as the directory contrib/mingw-cross
. There is no need for a toolchain file.
My goal is to ensure that cross-compiling on Linux for MinGW works and will be supported in v0.27.1. I hope to build/publish such builds from Jenkins.
The preferred alternative to the script is to build dependencies with conan. I haven't investigate that yet. So, I'm posting the script (and dlls and patch) as a work in progress effort. This matter will receive more attention before Exiv2 v0.27.1 which is scheduled for 31 March 2019.
@cgilles I appreciate your enthusiasm for MXE. Regrettably, I found it frustrating and did not work. However I believe MXE is a superset of the prerequisites I have documented in build.sh
in the attached archive. So, you have a different way to drive the MinGW-crossplatform tools. However we share the destination and are using identical tools to reach our goal.
I am very appreciative of the time put into this issue by @kamgha. For sure there will be a "proper" fix for futils.cpp in Exiv2 v0.27.1. I'm puzzled that the issue reported by both you and Gilles concerning basicio.cpp
has not surfaced on my machines. When it does, I am confident we will cooperate to solve and fix the issue. Thank You for your help.
mingw-cross.tar.gz
Very pleased to say that using conan to build the dependencies caused no pain at all.
I've written this script conan-build.sh
to work with the archive above.
We'll need to on the "proper" fix for futils.cpp which is currently broken for other reasons (#615). I'll get this totally fixed and documented for v0.27.1
#!/usr/bin/env bash
echo ------------------------------
echo PWD = $PWD
echo this = $0
EXIV2=$(realpath ../..)
if [ ! -e $EXIV2/CMakeLists.txt ]; then
echo "***" file $EXIV2/CMakeLists.txt does not exist "***"
exit 1
fi
# Save the profile in a file
cat - > conan-build.profile <<EOF
\$toolchain=/usr/bin
target_host=x86_64-w64-mingw32
cc_compiler=gcc
cxx_compiler=g++
[env]
CONAN_CMAKE_FIND_ROOT_PATH=$toolchain
CHOST=\$target_host
AR=\$target_host-ar
AS=\$target_host-as
RANLIB=\$target_host-ranlib
CC=\$target_host-$cc_compiler
CXX=\$target_host-$cxx_compiler
STRIP=\$target_host-strip
RC=\$target_host-windres
[settings]
# We are building in Ubuntu Linux
os_build=Linux
arch_build=x86_64
# We are cross building to Windows
os=Windows
arch=x86_64
compiler=gcc
# Adjust to the gcc version of your MinGW package
compiler.version=7.3
compiler.libcxx=libstdc++11
build_type=Release
EOF
# request conan to build/download/install dependencies
conan install ../.. --build missing --profile conan-build.profile
# set up CMake cross compiler (see build.sh)
COMPILER_PREFIX="x86_64-w64-mingw32"
CM_GENERAL="-DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_C_COMPILER=$(which ${COMPILER_PREFIX}-gcc) \
-DCMAKE_CXX_COMPILER=$(which ${COMPILER_PREFIX}-g++) \
-DCMAKE_RC_COMPILER=$(which ${COMPILER_PREFIX}-windres) \
-DCMAKE_MAKE_PROGRAM=$(which make) \
-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
-DCMAKE_BUILD_TYPE=Release"
# -DCMAKE_FIND_ROOT_PATH="/usr/${COMPILER_PREFIX}" \
# build exiv2
echo ---- building exiv2 in $PWD -------------
cmake ../.. $CM_GENERAL \
-DBUILD_SHARED_LIBS=0 \
-DEXIV2_ENABLE_DYNAMIC_RUNTIME=Off \
-DCMAKE_INSTALL_PREFIX=$PWD
cmake --build . --config Release
cp gcc64/*.dll bin/
wine bin/exiv2 -vV
# That's all Folks!
##
compilation trace :
/mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/futils.cpp: In function 'std::cxx11::string Exiv2::getProcessPath()': /mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/futils.cpp:467:9: error: 'HANDLE' was not declared in this scope HANDLE processHandle = NULL; ^ /mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/futils.cpp:468:9: error: 'processHandle' was not declared in this scope processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId()); ^ /mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/futils.cpp:468:37: error: 'PROCESS_QUERY_INFORMATION' was not declared in this scope processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId()); ^ /mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/futils.cpp:468:65: error: 'PROCESS_VM_READ' was not declared in this scope processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId()); ^ /mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/futils.cpp:468:82: error: 'FALSE' was not declared in this scope processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId()); ^ /mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/futils.cpp:468:109: error: 'GetCurrentProcessId' was not declared in this scope processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId()); ^ /mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/futils.cpp:468:110: error: 'OpenProcess' was not declared in this scope processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId()); ^ /mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/futils.cpp:470:13: error: 'TCHAR' was not declared in this scope TCHAR filename[MAX_PATH]; ^ /mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/futils.cpp:471:58: error: 'filename' was not declared in this scope if (GetModuleFileNameEx(processHandle, NULL, filename, MAX_PATH) != 0) { ^ /mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/futils.cpp:471:68: error: 'MAX_PATH' was not declared in this scope if (GetModuleFileNameEx(processHandle, NULL, filename, MAX_PATH) != 0) { ^ /mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/futils.cpp:471:76: error: 'GetModuleFileNameEx' was not declared in this scope if (GetModuleFileNameEx(processHandle, NULL, filename, MAX_PATH) != 0) { ^ /mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/futils.cpp:474:38: error: 'CloseHandle' was not declared in this scope CloseHandle(processHandle); ^ src/CMakeFiles/exiv2lib.dir/build.make:363 : la recette pour la cible « src/CMakeFiles/exiv2lib.dir/futils.cpp.obj » a échouée gmake[6]: [src/CMakeFiles/exiv2lib.dir/futils.cpp.obj] Erreur 1 gmake[6]: Attente des tâches non terminées.... /mnt/devel/GIT/6.x/project/bundles/mxe/temp.build/ext_exiv2/ext_exiv2-prefix/src/ext_exiv2/src/convert.cpp:1510:10: warning: 'bool {anonymous}::convertStringCharsetWindows(std::cxx11::string&, const char, const char)' defined but not used [-Wunused-function] bool convertStringCharsetWindows(std::string& str, const char from, const char to) ^ CMakeFiles/Makefile2:212 : la recette pour la cible « src/CMakeFiles/exiv2lib.dir/all » a échouée gmake[5]: [src/CMakeFiles/exiv2lib.dir/all] Erreur 2 Makefile:129 : la recette pour la cible « all » a échouée gmake[4]: [all] Erreur 2 ext_exiv2/CMakeFiles/ext_exiv2.dir/build.make:112 : la recette pour la cible « ext_exiv2/ext_exiv2-prefix/src/ext_exiv2-stamp/ext_exiv2-build » a échouée gmake[3]: [ext_exiv2/ext_exiv2-prefix/src/ext_exiv2-stamp/ext_exiv2-build] Erreur 2 CMakeFiles/Makefile2:415 : la recette pour la cible « ext_exiv2/CMakeFiles/ext_exiv2.dir/all » a échouée gmake[2]: [ext_exiv2/CMakeFiles/ext_exiv2.dir/all] Erreur 2 CMakeFiles/Makefile2:427 : la recette pour la cible « ext_exiv2/CMakeFiles/ext_exiv2.dir/rule » a échouée gmake[1]: [ext_exiv2/CMakeFiles/ext_exiv2.dir/rule] Erreur 2 Makefile:196 : la recette pour la cible « ext_exiv2 » a échouée gmake: [ext_exiv2] Erreur 2 FAILED COMMAND: ${MXE_BUILD_TARGETS}-cmake --build . --config RelWithDebInfo --target ext_exiv2 -- -j$CPU_CORES
[gilles@localhost mxe]$
In fact, in futils.cpp there are 2 problems in getProcessPath() :
// ---------------------------------------
I take a look under Qt5 code which is fully portable and support very well MinGW, the readlink() call is wrapped with access()
Gilles Caulier