CMake compilation issue on MacOS-X 4.5.1/Mountain Lion
There's a strange compilation warning with CMake/Makefiles on Mountain Lion. exiv2 built this way passes the test suite. So the issue is ugly and benign.
162 rmills@clanmills:~/gnu/exiv2/testbuild $ xcodebuild -version Xcode 4.5.1 Build version 4G1004 163 rmills@clanmills:~/gnu/exiv2/testbuild $ sw_vers ProductName: Mac OS X ProductVersion: 10.8.2 BuildVersion: 12C60 164 rmills@clanmills:~/gnu/exiv2/testbuild $
$ cd <exiv2> $ mkdir build ; cd build; cmake .. ; make ... rattle'n'roll [ 1%] Building CXX object xmpsdk/CMakeFiles/xmp.dir/src/ExpatAdapter.cpp.o [ 2%] Building CXX object xmpsdk/CMakeFiles/xmp.dir/src/MD5.cpp.o /Users/rmills/gnu/exiv2/testbuild/xmpsdk/src/MD5.cpp:133:24: warning: 'memset' call operates on objects of type 'struct MD5_CTX' while the size is based on a different type 'struct MD5_CTX *' [-Wsizeof-pointer-memaccess] memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ ~~~ ^~~ /Users/rmills/gnu/exiv2/testbuild/xmpsdk/src/MD5.cpp:133:24: note: did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)? memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ ^~~ 1 warning generated.
Oddly this doesn't appear with the autotools build. $ make config ; ./configure ; make
There must be something different about the compilation options/search path generated by CMake. The command $ make VERBOSE=1 will echo the commands being executed by CMake builds.
Fix: Bug #857. Get CMake to compile with g++ instead of c++ (clang) compiler to eliminate warnings.
Updated by Robin Mills almost 9 years ago
- Status changed from Assigned to Resolved
- % Done changed from 0 to 90
Fix submitted: SV#2904.
I couldn't find compiler flags to eliminate the compiler warnings on the CMake build.
However, I discovered that the ./configure build uses /usr/bin/g++ and was happy. CMake uses /usr/bin/c++ and gives warnings. Here are the paths in the file system to the compilers.
528 rmills@rmills-imac:~/gnu/exiv2/exiv2.master $ which g++ ; which c++
529 rmills@rmills-imac:~/gnu/exiv2/exiv2.master $ ls -alt $(pathname $(which g++))
-rwxr-xr-x 1 root wheel 117168 Oct 12 22:35 /usr/llvm-gcc-4.2/bin/llvm-g++-4.2
530 rmills@rmills-imac:~/gnu/exiv2/exiv2.master $ ls -alt $(pathname $(which c++))
-rwxr-xr-x 1 root wheel 21622640 Oct 12 22:35 /usr/bin/clang
531 rmills@rmills-imac:~/gnu/exiv2/exiv2.master $
I modified CMakeLists.txt (in the project's root) to get CMake to use g++. I've successfully built and run the test suite.
Presumably there are important differences between clang and llvm-g++. If the user wishes to compile with clang, CMakeLists.txt can be modified and the resulting executables will pass the test suite. TAKE CARE: make CC=/usr/bin/c++ does not change the compiler for a CMake generated Makefile. To change the compiler, it is necessary to change CMakeLists.txt and regenerate the Makefile. CMake uses the compiler to generate the Makefile and "bakes" the compiler path into the Makefile.
I feel confident about marking this issue as resolved (until someone says otherwise!).
Updated by Andreas Huggel almost 9 years ago
r2904: I'd rather have the warning than change the default compiler just because we don't understand the warning. Sooner or later someone will tell us what's really wrong.
On the other hand, this compiler generates refreshingly verbose and clever warnings: Try change the sizeof(ctx) to sizeof(*ctx) and I'm confident it will go away. The compiler found a bug. The intention of this code is to clear memory the size of struct MD5_CTX, not the size of a pointer to that struct, which is what it's currently doing.
Updated by Robin Mills almost 9 years ago
libtool: compile: /usr/bin/c++ -O2 -fvisibility=hidden -fvisibility-inlines-hidden -Wall -Wcast-align -Wpointer-arith -Wformat-security -Wmissing-format-attribute -Woverloaded-virtual -W -MMD -I. -I/usr/local/include -DEXV_LOCALEDIR=\"/usr/local/share/locale\" -I../xmpsdk/include -c -DEXV_BUILDING_LIB=1 asfvideo.cpp -fno-common -DPIC -o .libs/asfvideo.o
asfvideo.cpp:30:1: warning: variable 'rcsId' is uninitialized when used within its own initialization [-Wuninitialized]
./rcsid_int.hpp:59:38: note: expanded from macro 'EXIV2_RCSID'
const char* rcsId = getRcsId(rcsId); \