forked from Rdatatable/data.table
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cc.R
91 lines (82 loc) · 2.93 KB
/
cc.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# For data.table dev
#
# In ~/.Rprofile add 2 lines :
# Sys.setenv(CC_DIR=path.expand("~/git/data.table"))
# source(file.path(Sys.getenv("CC_DIR"), "cc.R"))
#
# Normal usage :
# $ R
# > cc()
# # change some files
# > cc()
# # compile, reload but not test
# > cc(F)
# # clean, compile, reload but not test
# > cc(F, T)
# # clean, compile using specific version, reload but not test
# > cc(F, T, CC="gcc-8")
#
# To debug C level :
# $ R -d gdb
# run
# dd()
# Ctrl-C
# break file.c:line
# c
# test and step between R and C
options(datatable.print.class = TRUE)
sourceDir <- function(path=getwd(), trace = TRUE, ...) {
# copied verbatim from example(source) in base R
for (nm in list.files(path, pattern = "\\.[RrSsQq]$")) {
if(trace) cat(nm," ")
source(file.path(path, nm), ...)
}
if(trace) cat("\n")
}
cc = function(test=TRUE, clean=FALSE, debug=FALSE, omp=!debug, cc_dir=Sys.getenv("CC_DIR"), CC="gcc") {
stopifnot(is.character(CC), length(CC)==1L, !is.na(CC), nzchar(CC))
gc()
xx = try(getDLLRegisteredRoutines("datatable",TRUE), silent=TRUE)
if (!inherits(xx, "try-error")) {
remove(list=sapply(xx$.Call,'[[',"name"), pos=.GlobalEnv)
remove(list=sapply(xx$.External,'[[',"name"), pos=.GlobalEnv)
# if these objects aren't there to remove it's correctly an error (should always be there)
}
# Make sure library .so is not loaded (neither installed package nor from dev)
dll = unlist(do.call("rbind",getLoadedDLLs())[,"path"])
dll = grep("datatable.so",dll,value=TRUE)
sapply(dll, dyn.unload)
gc()
old = getwd()
on.exit(setwd(old))
setwd(file.path(cc_dir,"src"))
cat(getwd(),"\n")
if (clean) system("rm *.o *.so")
OMP = if (omp) "" else "no-"
if (debug) {
ret = system(sprintf("MAKEFLAGS='-j CC=%s PKG_CFLAGS=-f%sopenmp CFLAGS=-std=c99\\ -O0\\ -ggdb\\ -pedantic' R CMD SHLIB -d -o data.table.so *.c", CC, OMP))
} else {
ret = system(sprintf("MAKEFLAGS='-j CC=%s CFLAGS=-f%sopenmp\\ -std=c99\\ -O3\\ -pipe\\ -Wall\\ -pedantic' R CMD SHLIB -o data.table.so *.c", CC, OMP))
# TODO add -Wextra too?
}
if (ret) return()
# clang -Weverything includes -pedantic and issues many more warnings than gcc
# system("R CMD SHLIB -o data.table.so *.c")
if (any(sapply(objects(envir=.GlobalEnv),function(x){inherits(get(x,.GlobalEnv),"data.table")}))) {
cat("ABOUT TO RELOAD .SO BUT THERE ARE DATA.TABLE OBJECTS IN .GLOBALENV SO FINALIZER MIGHT CRASH\n")
}
dyn.load("datatable.so")
setwd(old)
xx = getDLLRegisteredRoutines("datatable",TRUE)
for (i in seq_along(xx$.Call))
assign(xx$.Call[[i]]$name, xx$.Call[[i]]$address, env=.GlobalEnv)
for (i in seq_along(xx$.External))
assign(xx$.External[[i]]$name, xx$.External[[i]]$address, env=.GlobalEnv)
sourceDir(paste0(cc_dir,"/R"))
assign("testDir", function(x)paste0(cc_dir,"/inst/tests/",x), envir=.GlobalEnv)
.onLoad()
if (test) test.data.table()
gc()
invisible()
}
dd = function(omp=FALSE)cc(FALSE,debug=TRUE,omp=omp,clean=TRUE)