Build error on MacOS, macports... with unctrl.h / ncurses.h

Dear All,

I am having problems building ROOT 6.22.00 from source on macOS.

Note, my (ultimate) aim here is to update the build within MacPorts, so I am building with a number of dependencies required by that build installed in the usual MacPorts prefix, /opt/local. The build errors however can be reproduced outside MacPorts using a simple cmake build i.e.

git clone git@github.com:root-project/root.git
cd root
git checkout v6-22-00-patches
cd ..
mkdir build
cd build
cmake ../root
cmake --build . -- -j8

With the above, the build fails with

/opt/local/include/unctrl.h:61:38: error: cannot initialize a variable of type 'char *' with an lvalue of type 'char *(chtype)' (aka 'char *(unsigned int)')
NCURSES_EXPORT(NCURSES_CONST char *) NCURSES_SP_NAME(unctrl) (SCREEN*, chtype);
                                     ^               ~~~~~~
/opt/local/include/unctrl.h:61:61: error: expected ';' after top level declarator
NCURSES_EXPORT(NCURSES_CONST char *) NCURSES_SP_NAME(unctrl) (SCREEN*, chtype);
                                                            ^
While building module 'Core':
While building module 'std' imported from input_line_1:1:
In file included from <module-includes>:2:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/ctype.h:38:15: fatal error: could not build module 'Darwin'
#include_next <ctype.h>
 ~~~~~~~~~~~~~^
input_line_1:1:10: fatal error: could not build module 'std'
#include <new>

Full configure and build log is attached.

Note, if I repeat the above, instead using the git tag for the v6.20.06 release, the build is fine. log also attached.

It appears from the above logs the build is mixing up two different versions of headers for nurses. One from Xcode and MacPorts own installation, leading to an incompatibility error ?

cheers Chris

v6.20.06.log.bz2 (57.1 KB) v6.22.00-patches.log.bz2 (46.1 KB)

ROOT Version: v6.22.00
Platform: Mac OS 10.15
Compiler: Xcode 11.5

@oshadura or @Axel, can you help?

@vvassilev I remeber you were investigating such problem do you know how it could be fixed?

@chrisburr should be able to give a better explanation I think.

As you’ve realised, the confusion comes from mixing up ncurses 5 from the macOS SDK and ncurses 6 from another source (MacPorts/conda/whatever).

The include is coming from rootcling parsing $SDKROOT/usr/include/module.modulemap which contains:

 explicit module ncurses {
  header "ncurses.h" // note: same as curses.h
  export *

  explicit module dll {
   header "ncurses_dll.h"
   export *
  }

  explicit module unctrl {
   textual header "unctrl.h"
  }
 }

For some reason (which Vasil thinks is a clang 5 bug) ncurses.h is being taken from $SDKROOT/usr/include/ncurses.h while unctrl.h comes from other ncurses installation (in this case /opt/local/include/unctrl.h).

My horrible hack in conda-forge for this is to use sed to edit the SDK and modify header "ncurses.h" to be header "/path/to/conda/prefix/include/ncurses.h". I do not recommend it but it’s a good enough temporary hack for conda-forge as VM is destroyed after each build but it’s probably not an option for anyone else.

Alternatively, it’s possible to avoid this issue by modifying ROOT’s CMake configuration to avoid adding unneeded include paths in the call to rootcling when linking G__Core. These aren’t needed and come from here and will (in the case of MacPorts) result in -I/opt/local/include/ being added to the rootcling_stage1 command up to 4 times. Manually editing the text file to remove these includes avoids the bug I haven’t tried to get CMake to generate the command correctly.

Thanks for the info. Hacking the macOS SDK is absolutely not an approach I am going to go down though… I’ll take a look at fixing ROOT Cmake build to see if that works…

A workaround is to build with -Druntime_cxxmodules=OFF.

what else does that remove (cripple) though ?

@chrisburr Your suggesting to hack the ROOT Cmake file to remove the lines that link Core against some external libraries is I think not going to work for the MacPorts builds, as I want to use a number of externals from macports, e.g. PCRE, libz, zstd etc. So removing these from

Is I guess going to break this ?

@jonesc I’m also using external builds of everything. What is needed is to somehow remove the includes from the call to rootcling_stage1 (where they aren’t needed) while still including/linking them everywhere else.

If I remember correctly, editing the text file generated by CMake works but I didn’t figure out how to make it generate it correctly.

OK, I see thanks. I don’t really have time to look into this myself so I am going to see if just turning off the cxx runtime modules works around this ROOT issue for now.

That option makes ROOT use dictionaries instead of the new replacement based on runtime C++ modules. You could enable this before, but in this release it has become the default (i.e. in ROOT 6.18 and below it was there, but was disabled by default). Same thing for PyROOT, before there was pyroot_experimental=ON, which became just pyroot=ON, and now there is pyroot_legacy=ON option to revert to the classic PyROOT.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.

Dear All

I am still seeing the same build error as reported in

with 6.22.04.

Is anyone from the ROOT team looking into this ? The workaround to disable the modules still seems OK, but it would be better to not have to do this.

Chris


Please read tips for efficient and successful posting and posting code

ROOT Version: Not Provided
Platform: Not Provided
Compiler: Not Provided


Hi Chris,

Happy to fix something, but I don’t know what. Linking against foo, we need to export the include path to foo to rootcling. If that exposes conflicting headers then I guess we need to tweak the relative priorities of the -Is, with the sysroot coming last, so others can overwrite these headers. Would you be able to share the invocation of rootcling that triggers the error message?

Also: @vvassilev might still have an idea.

Cheers, Axel.

Hi Axel,

I posted a full build log in the original topic. If you cannot find what you need there I will need instructions on how to trigger it as part of a regular build.

cheers Chris

Hi Chris,

Can you share, after the build error occurs, the output of cmake --build . --target G__Core -- VERBOSE=1 (assuming GNU Makefiles)?

Cheers, Axel.

The builds are using ninja, not GNU make, in order to work around another issue. Do you still want the above with this ?

Then it’s ninja -v G__Core.