RcppCore / Rcpp

Seamless R and C++ Integration
https://www.rcpp.org
GNU General Public License v2.0
730 stars 210 forks source link

`Rcpp:::LdFlags()` does not work correctly with R 4.4.0, pulling in warnings from `R` as if they were objects for the linker #1302

Closed barracuda156 closed 4 months ago

barracuda156 commented 4 months ago

@eddelbuettel Could you please help a bit here? I am not sure it is a bug in Rcpp itself, since this issue arose with R 4.4.0. Specifically, $(R_HOME)/bin/Rscript -e "Rcpp:::LdFlags()" does not work correctly, and adds parts of R textual warnings as arguments for the linker, which obviously cannot work. So now packages which rely on Rcpp:::LdFlags fail to build.

With gcc:

/opt/local/bin/g++-mp-13 -std=gnu++17 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/opt/local/Library/Frameworks/R.framework/Resources/lib -Wl,-headerpad_max_install_names -L/opt/local/lib -lMacportsLegacySupport -Wl,-rpath,/opt/local/lib/libgcc -arch ppc -o minqa.so altmov.o bigden.o biglag.o bobyqa.o bobyqb.o lagmax.o minqa.o newuoa.o newuob.o prelim.o rescue.o trsapp.o trsbox.o trstep.o uobyqa.o uobyqb.o update.o updatebobyqa.o WARNING: too small maximum for v(ector heap)size '0' ignored, the current usage 64M is already larger WARNING: too small maximum for v(ector heap)size '0' ignored, the current usage 64M is already larger -lMacportsLegacySupport -lgfortran -lef_ppc -F/opt/local/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
ld: file not found: WARNING:
collect2: error: ld returned 1 exit status
make: *** [minqa.so] Error 1

With clang:

/opt/local/bin/clang++-mp-11 -std=gnu++17 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/opt/local/Library/Frameworks/R.framework/Resources/lib -Wl,-headerpad_max_install_names -L/opt/local/lib -lMacportsLegacySupport -Wl,-rpath,/opt/local/lib/libgcc -arch i386 -o minqa.so altmov.o bigden.o biglag.o bobyqa.o bobyqb.o lagmax.o minqa.o newuoa.o newuob.o prelim.o rescue.o trsapp.o trsbox.o trstep.o uobyqa.o uobyqb.o update.o updatebobyqa.o WARNING: too small maximum for v(ector heap)size '0' ignored, the current usage 64M is already larger WARNING: too small maximum for v(ector heap)size '0' ignored, the current usage 64M is already larger -L/opt/local/lib/gcc13/gcc/i386-apple-darwin10/13.2.0 -L/opt/local/lib/gcc13 -lMacportsLegacySupport -lgfortran -ld10-uwfef -lquadmath -F/opt/local/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
clang: error: no such file or directory: 'WARNING:'
clang: error: no such file or directory: 'too'
clang: error: no such file or directory: 'small'
clang: error: no such file or directory: 'maximum'
clang: error: no such file or directory: 'for'
clang: error: no such file or directory: 'v(ector'
clang: error: no such file or directory: 'heap)size'
clang: error: no such file or directory: ''0''
clang: error: no such file or directory: 'ignored,'
clang: error: no such file or directory: 'the'
clang: error: no such file or directory: 'current'
clang: error: no such file or directory: 'usage'
clang: error: no such file or directory: '64M'
clang: error: no such file or directory: 'is'
clang: error: no such file or directory: 'already'
clang: error: no such file or directory: 'larger'
clang: error: no such file or directory: 'WARNING:'
clang: error: no such file or directory: 'too'
clang: error: no such file or directory: 'small'
clang: error: no such file or directory: 'maximum'
clang: error: no such file or directory: 'for'
clang: error: no such file or directory: 'v(ector'
clang: error: no such file or directory: 'heap)size'
clang: error: no such file or directory: ''0''
clang: error: no such file or directory: 'ignored,'
clang: error: no such file or directory: 'the'
clang: error: no such file or directory: 'current'
clang: error: no such file or directory: 'usage'
clang: error: no such file or directory: '64M'
clang: error: no such file or directory: 'is'
clang: error: no such file or directory: 'already'
clang: error: no such file or directory: 'larger'
make: *** [minqa.so] Error 1
ERROR: compilation failed for package ‘minqa’

I tried both Rcpp 1.0.12 and 1.0.11, no change, so it is not introduced recently for sure. However, what changed from R side is an introduction of these warnings:

WARNING: too small maximum for v(ector heap)size '0' ignored, the current usage 64M is already larger

While the issue is seen only on 32-bit archs, I think the error has nothing to do with bitness as such, it is just Rdoes not generate those warnings on 64-bit. What I do not know is whether it was an implicit issue with Rcpp which never shown up until this change, or a bug in the new release of R.

Any suggestions are greatly appreciated, I can test on my end. See also: https://trac.macports.org/ticket/69849

eddelbuettel commented 4 months ago

One has not needed Rcpp:::LdFlags() for at least a decade and we deprecated it a long time ago (git blame says 2018 for this):

https://github.com/RcppCore/Rcpp/blob/03fd09a1bd0b4dce5be262dd95f779d9a855e097/man/Rcpp-deprecated.Rd#L13-L15

You can easily find other references for the deprecation. You should report and/or fix packages that still use it (such as minqa). They don't need to, and have not for a decade+. I plan to close this.

Also:

https://github.com/RcppCore/Rcpp/blob/03fd09a1bd0b4dce5be262dd95f779d9a855e097/man/RcppLdFlags.Rd#L1-L12

barracuda156 commented 4 months ago

Ok, thank you, this is helpful. We can get rid of these locally in the worst case. Let's close the issue, since it must be fixed of packages' side.

eddelbuettel commented 4 months ago

Also note that the woes appear to be local to your builds so this may by an X-Y problem in hiding. Under Ubuntu:

edd@rob:~$ Rscript -e 'print(Rcpp:::LdFlags())'
NULL
edd@rob:~$ Rscript --version
Rscript (R) version 4.4.0 (2024-04-24)
edd@rob:~$ 

Trust me that we would have heard from CRAN if we broke stuff systematically.

barracuda156 commented 4 months ago

@eddelbuettel It returns this for me:

36-170% Rscript -e 'print(Rcpp:::LdFlags())'
WARNING: too small maximum for v(ector heap)size '0' ignored, the current usage 64M is already larger

WARNING: too small maximum for v(ector heap)size '0' ignored, the current usage 64M is already larger

NULL

But this just appeared in R 4.4.0. So pretty likely it is a bug in R itself. (Of course it is not something we would add from Macports side.)

eddelbuettel commented 4 months ago

You may want to look into file R/RcppLdPath.R and debug a little.

## Provide linker flags -- i.e. -L/path/to/libRcpp -- as well as an
## optional rpath call needed to tell the Linux dynamic linker about the
## location.  This is not needed on OS X where we encode this as library
## built time (see src/Makevars) or Windows where we use a static library
## Updated Jan 2010:  We now default to static linking but allow the use
##                    of rpath on Linux if static==FALSE has been chosen
##                    Note that this is probably being called from LdFlags()
## Updated Nov 2013:  We no longer build a library. This should be deprecated.
RcppLdFlags <- function() {
    #.Deprecated(msg=paste("This function is now deprecated as it has not",
    #                      "been needed since 2013."))
    ""
}

#... stuff omitted ...

## LdFlags defaults to static linking on the non-Linux platforms Windows and OS X
LdFlags <- function() {
    cat(RcppLdFlags())
}

If these function calls fail you may have other problems. And you don't have to feel obliged to keep me in the loop here.

barracuda156 commented 4 months ago

The warnings originate from here in R-4.4.0/src/main/startup.c:

static void SetSize(R_size_t vsize, R_size_t nsize)
{
    char msg[1024];
    Rboolean sml;
    /* vsize > 0 to catch long->int overflow */
    if (vsize < 1000 && vsize > 0) {
    R_ShowMessage("WARNING: vsize ridiculously low, Megabytes assumed\n");
    vsize *= (R_size_t) Mega;
    }
    if((sml = vsize < Min_Vsize) || vsize > Max_Vsize) {
    snprintf(msg, 1024,
         "WARNING: %s v(ector heap)size '%lu' ignored,"
         " using default = %gM\n",
         sml ? "too small" : "too large",
         (unsigned long) vsize, R_VSIZE / Mega);
    R_ShowMessage(msg);
    R_VSize = R_VSIZE;
    } else
    R_VSize = vsize;
    if((sml = nsize < Min_Nsize) || nsize > Max_Nsize) {
    snprintf(msg, 1024,
         "WARNING: %s language heap (n)size '%lu' ignored,"
         " using default = %ld\n",
         sml ? "too small" : "too large", (unsigned long) nsize, R_NSIZE);
    R_ShowMessage(msg);
    R_NSize = R_NSIZE;
    } else
    R_NSize = nsize;
}

static void SetMaxSize(R_size_t vsize, R_size_t nsize)
{
    char msg[1024];

    if (!R_SetMaxVSize(vsize)) {
    /* vsfac is still 1 */
    snprintf(msg, 1024,
         "WARNING: too small maximum for v(ector heap)size '%lu' ignored,"
         " the current usage %gM is already larger\n",
         (unsigned long) vsize, R_VSize / Mega);
    R_ShowMessage(msg);
    }

    if (!R_SetMaxNSize(nsize)) {
    snprintf(msg, 1024,
         "WARNING: too small maximum for language heap (n)size '%lu' ignored,"
         " the current usage '%lu' is already larger\n",
         (unsigned long) nsize, (unsigned long) R_NSize);
    R_ShowMessage(msg);
    }
}

f these function calls fail you may have other problems. And you don't have to feel obliged to keep me in the loop here.

Got it. Thank you, your help is appreciated, and I am not commenting here further. We can handle it.