Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sourceCpp compile error stderr cannot be caught/suppressed #1257

Closed
andrjohns opened this issue Mar 24, 2023 · 10 comments · Fixed by #1259
Closed

sourceCpp compile error stderr cannot be caught/suppressed #1257

andrjohns opened this issue Mar 24, 2023 · 10 comments · Fixed by #1259

Comments

@andrjohns
Copy link
Contributor

When writing a try() function to check for compile errors from sourceCpp the compilation error is always printed to the console, regardless of whichever combinations of try(), suppressMessages(), suppressWarnings() or sink are used.

Reprex:

dcode <- "//[[Rcpp::export]]\n int fun(int x) { const int y; return x; }"
status <- suppressWarnings(suppressMessages(
  output <- capture.output(
    try(Rcpp::sourceCpp(code = dcode, verbose=FALSE, echo=FALSE),
                 silent = TRUE))
))

Created on 2023-03-24 with reprex v2.0.2

Standard output and standard error
fileeed07e197428.cpp:2:29: error: default initialization of an object of const type 'const int'
 int fun(int x) { const int y; return x; }
                            ^
                              = 0
1 error generated.
make: *** [fileeed07e197428.o] Error 1
@eddelbuettel
Copy link
Member

Hm, I think that's the way it is and likely will be -- Rcpp::sourceCpp() and friends call functions calling commands like R CMD COMPILE and R CMD SHLIB so the output suppression you desire happens at the operating system command level and R's own output suppressers (working on R's own output streams) have nothing for them.

Not really an Rcpp issue.

@andrjohns
Copy link
Contributor Author

sourceCpp calls system(), and this can be handled with system():

cat("int fun(int x) { const int y; return x; }", file="foo.cpp")
system("R CMD SHLIB foo.cpp", ignore.stderr = TRUE, ignore.stdout = TRUE)

Could verbose/showOutput/echo be passed to these?

@eddelbuettel
Copy link
Member

If you believe strongly that this is warranted, maybe you could sketch a change proposal in this issue, and ideally test it? One of us may take a look.

@andrjohns
Copy link
Contributor Author

Another perspective, it also means that the verbose flag is only respected if the compilation succeeds. Since the following:

gooddcode <- "//[[Rcpp::export]]\n int fun(int x) { return x; }"
Rcpp::sourceCpp(code = gooddcode, verbose=FALSE, rebuild = TRUE)

Does not print the compilation call, but it does get printed if the compilation fails

@Enchufa2
Copy link
Member

I think it's a reasonable request. I'll take a look, I have some experience with this kind of stuff with bspm.

@eddelbuettel
Copy link
Member

We could also think about a new helper package that revisits the issue from a different angle but leaves the existing functions evalCpp(), cppFunction(), and sourceCpp() --- which were after all all meant for quick interactive work -- alone.

We now have system2() which if memory serves wasn't around when the existing helpers were written.

Just a suggestion.

@eddelbuettel
Copy link
Member

@andrjohns Can you do us a favour and build of the branch @Enchufa2 submitted as part of his PR #1259 ? It now uses system2() and should be able to accomodate you.

@eddelbuettel
Copy link
Member

@andrjohns I am going to merge this now, assuming it will indeed address the issue you pointed out to us. Should it still be an issue for you please feel free to reopen this and append any additional detail you can think of.

@andrjohns
Copy link
Contributor Author

Thanks @Enchufa2 for sorting this so quickly and sorry for not testing earlier! It looks like this has almost fixed it - both stderr and stdout still always print to the console on failure, but they can now be captured by capture.output():

> dcode <- "//[[Rcpp::export]]\n int fun(int x) { const int y; return x; }"
> status <- suppressWarnings(suppressMessages(
+         try(Rcpp::sourceCpp(code = dcode, verbose=FALSE, echo=FALSE, showOutput = FALSE),
+             silent = TRUE)
+ ))
clang++ -arch arm64 -std=gnu++14 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG   -I"/Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/library/Rcpp/include" -I"/private/var/folders/1d/rjvd0h_n0yq20j13h4gdfytw0000gn/T/RtmpKtrHhf/sourceCpp-aarch64-apple-darwin20-1.0.10.4" -I/opt/R/arm64/include   -fPIC  -falign-functions=64 -Wall -g -O2  -Wno-unknown-warning-option -Wno-enum-compare -Wno-ignored-attributes -Wno-unused-local-typedef -Wno-sign-compare -Wno-unneeded-internal-declaration -Wno-unused-function -Wno-unused-but-set-variable -Wno-unused-variable -Wno-infinite-recursion -Wno-unknown-pragmas -Wno-unused-lambda-capture -Wno-deprecated-declarations -Wno-deprecated-builtins -Wno-unused-but-set-variables -ftemplate-backtrace-limit=0 -I/opt/homebrew/opt/libomp/include -c file4234702a2e8.cpp -o file4234702a2e8.o
file4234702a2e8.cpp:2:29: error: default initialization of an object of const type 'const int'
 int fun(int x) { const int y; return x; }
                            ^
                              = 0
1 error generated.
make: *** [file4234702a2e8.o] Error 1

Shows nothing:

dcode <- "//[[Rcpp::export]]\n int fun(int x) { const int y; return x; }"
status <- suppressWarnings(suppressMessages(
    output <- capture.output(
        try(Rcpp::sourceCpp(code = dcode, verbose=FALSE, echo=FALSE),
            silent = TRUE))
))

It would be great if the output could be suppressed by verbose=FALSE, but that's also easy enough to workaround now if not

@eddelbuettel
Copy link
Member

Can you look into a PR accomplishing what you desire exactly as you desire? We would be happy to review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants