Opened 5 years ago

Closed 5 years ago

#58450 closed defect (fixed)

MacPorts installed cmake gives incoherent results

Reported by: sandym (Sandy Martel) Owned by: michaelld (Michael Dickens)
Priority: Normal Milestone:
Component: ports Version:
Keywords: Cc:
Port: cmake

Description

use the following CMakeLists.txt:

cmake_minimum_required(VERSION 3.12)

find_path(ICONV_HEADER NAMES "iconv.h")
message("ICONV_HEADER = ${ICONV_HEADER}")
find_library(ICONV_LIB NAMES "iconv" "libiconv")
message("ICONV_LIB = ${ICONV_LIB}")

add_executable(main main.cpp)

using macports' cmake it will output:

ICONV_HEADER = /opt/local/include
ICONV_LIB = /usr/lib/libiconv.dylib

using cmake downloaded from cmake.org:

ICONV_HEADER = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include
ICONV_LIB = /usr/lib/libiconv.dylib

MacPorts one gives the project an inconsistent header / library pair (that will fail to link in the iconv case).

Attachments (2)

CMakeLists.txt (244 bytes) - added by sandym (Sandy Martel) 5 years ago.
patch-fix-cmake-prefix-path.diff (661 bytes) - added by michaelld (Michael Dickens) 5 years ago.

Download all attachments as: .zip

Change History (17)

Changed 5 years ago by sandym (Sandy Martel)

Attachment: CMakeLists.txt added

comment:1 Changed 5 years ago by mf2k (Frank Schima)

In the future, please add the port maintainer(s) to Cc (port info --maintainers cmake), if any.

comment:2 Changed 5 years ago by mf2k (Frank Schima)

Keywords: cmake removed
Owner: set to michaelld
Status: newassigned

comment:3 in reply to:  description Changed 5 years ago by sandym (Sandy Martel)

Note that this causes call to:

find_package(Iconv REQUIRED)

to return the wrong results. The FindIconv module simply uses find_path and find_library.

comment:4 Changed 5 years ago by michaelld (Michael Dickens)

Hmm ... seems like we've probably set a default search path for headers to include the MacPorts' ${prefix}/include but didn't set a default search path for libraries to include ${prefix}/lib ... That would indeed be useful and appropriate. Do you have the skills to look into this issue? If not, I'll add it to my every-growing queue & we can all hope I get there this year. Luckily it's simple enough to issue the following command to find iconv or just about any other project; you just have to know the correct defines ...

cmake -DIconv_INCLUDE_DIRS=${prefix}/include --DIconv_LIBRARIES=${prefix}/lib/libiconv.dylib [PATH]

comment:5 Changed 5 years ago by sandym (Sandy Martel)

Should macports' prefix to have priority over the OS/Xcode one ? I guess it's yes ?

comment:6 Changed 5 years ago by michaelld (Michael Dickens)

Yes

comment:7 Changed 5 years ago by kencu (Ken)

Are you just trying to use cmake in your own project, outside of MacPorts? If so, I get this with your CMakeLists.txt:

$ which cmake
/opt/local/bin/cmake

$ cmake ../
-- The C compiler identification is Clang 5.0.2
-- The CXX compiler identification is Clang 5.0.2
-- Check for working C compiler: /opt/local/bin/cc
-- Check for working C compiler: /opt/local/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /opt/local/bin/clang++
-- Check for working CXX compiler: /opt/local/bin/clang++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
ICONV_HEADER = /usr/include
ICONV_LIB = /usr/lib/libiconv.dylib
-- Configuring done
-- Generating done

However, inside of a MacPorts' build (using cmake 1.1 PG), it looks fine:

-- The C compiler identification is Clang 5.0.2
-- The CXX compiler identification is Clang 5.0.2
-- Check for working C compiler: /opt/local/bin/clang-mp-5.0
-- Check for working C compiler: /opt/local/bin/clang-mp-5.0 -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /opt/local/bin/clang++-mp-5.0
-- Check for working CXX compiler: /opt/local/bin/clang++-mp-5.0 -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
ICONV_HEADER = /opt/local/include
ICONV_LIB = /opt/local/lib/libiconv.dylib

comment:8 Changed 5 years ago by michaelld (Michael Dickens)

Does the same happen with TCL / TK? I've seen this happen before where one find returns info from one install and the other find returns info from some other install. We try to keep these results coherent, but it's impossible to check and verify every single possible find; the best we can reasonably hope for is that those provided by CMake actually work coherently. I do run "make test" to make sure all of the critical CMake functionality is working as desired & it does -- whether using MacPorts or not (as Ken notes). It is certainly possible that with the correct environment settings the finds will return non-coherent results.

comment:9 Changed 5 years ago by sandym (Sandy Martel)

What is "cmake 1.1 PG" ? I'm trying to understand how you got

ICONV_HEADER = /opt/local/include
ICONV_LIB = /opt/local/lib/libiconv.dylib

?

As for getting

ICONV_HEADER = /usr/include
ICONV_LIB = /usr/lib/libiconv.dylib

you probably have an extra Xcode package installed as /usr/include does not exists on any of my machines nor is a default install by Xcode anymore. All headers are in Xcode SDKs folder. The library do exists in /usr of course.

So it seems to come down to the value of CMAKE_SYSTEM_PREFIX_PATH. For cmake downloaded from cmake.org, I get:

CMAKE_SYSTEM_PREFIX_PATH =
	/usr/local
	/usr  <-- have the lib but not the header
	/
	/Applications/CMake.app/Contents <-- cmake install root, no header
	/usr/local
	/usr/X11R6
	/usr/pkg
	/opt
	/.../SDKs/MacOSX10.14.sdk/usr  <-- have the lib and header
	/sw
	/opt/local
ICONV_HEADER = /.../SDKs/MacOSX10.14.sdk/usr/include
ICONV_LIB = /usr/lib/libiconv.dylib

For macports' cmake:

CMAKE_SYSTEM_PREFIX_PATH =
	/usr/local
	/usr  <-- have the lib but not the header
	/
	/opt/local <-- cmake install root , have the lib and header
	/usr/local
	/usr/X11R6
	/usr/pkg
	/opt
	/.../SDKs/MacOSX10.14.sdk/usr  <-- have the lib and header
	/sw
	/opt/local
ICONV_HEADER = /opt/local/include
ICONV_LIB = /usr/lib/libiconv.dylib

Not sure there anything to do about this. It seems that even the cmake downloaded from cmake.org works by accident: what if I use a different SDK ? I still get the lib from /usr but a different header!

For now, I can either install the package to get the header in /usr/include or manipulate CMAKE_SYSTEM_PREFIX_PATH in my build script.

list(REMOVE_ITEM CMAKE_SYSTEM_PREFIX_PATH /usr) # skip /usr, get from macports

list(REMOVE_ITEM CMAKE_SYSTEM_PREFIX_PATH /opt/local) # or skip MacPorts
Last edited 5 years ago by sandym (Sandy Martel) (previous) (diff)

comment:10 Changed 5 years ago by sandym (Sandy Martel)

comment:11 Changed 5 years ago by michaelld (Michael Dickens)

(see second answer)

comment:12 Changed 5 years ago by michaelld (Michael Dickens)

If you edit the MacPorts-installed file $[prefix}/share/cmake-*/Modules/Platform/Darwin.cmake with the attached patch (-p0), you should see the MacPorts ${prefix} as the first entry barring your local CMake scripts changing it.

Changed 5 years ago by michaelld (Michael Dickens)

comment:13 Changed 5 years ago by michaelld (Michael Dickens)

This is a simple patch to add to the cmake ports if it works for others.

You shouldn't need /usr/include to exist. Modern build system can take -isysroot with the SDK, or set the CPATH or other ways to get the same effect.

comment:14 Changed 5 years ago by michaelld (Michael Dickens)

In 07d13e6e20368e83d958fefb0b9b9bb1fa663783/macports-ports (master):

cmake: add patch to fix CMAKE_SYSTEM_PREFIX_PATH

Make MacPorts' ${prefix} come first in the list excepting whatever the project sets a priori.

Should Address: #58450

comment:15 Changed 5 years ago by michaelld (Michael Dickens)

Resolution: fixed
Status: assignedclosed

Ok folks here: please update your dports tree & see if my commit takes care of this issue. TBH I haven't tried your CMakeLists.txt script; I just verified that my changes here remove /usr/local/ and /sw, test for duplicates for various variables and append them only if not already found, and, most importantly, puts the MacPorts ${prefix} first in the list for searching -- barring the project setting this variable to something & hence those settings coming first.

If having the MP ${prefix} first doesn't do the trick, I don't know what will!

I'm going to go ahead and close this ticket as fixed. If anyone truly believes otherwise, go ahead and reopen it & explain what's going on & I'll try to fix that too.

Note: See TracTickets for help on using tickets.