blob: b8ffc0c95496aef80df2c814bbb717efc3f319d5 (
plain) (
blame)
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
|
# This port opens too many files during build, more than the default setting.
# Its build is known to succeed with MAX_FILES_RStudio=4096 in poudriere.conf
PORTNAME= RStudio
DISTVERSIONPREFIX= v
DISTVERSION= 2025.09.2+418
PORTREVISION= 5
CATEGORIES= devel math java
MASTER_SITES= https://s3.amazonaws.com/rstudio-buildtools/dictionaries/:dictionaries \
https://rstudio-buildtools.s3.amazonaws.com/rstudio-buildtools/:gin \
https://rstudio-buildtools.s3.us-east-1.amazonaws.com/gwt/:gwt \
https://rstudio-buildtools.s3.us-east-1.amazonaws.com/gwt/:mathjax \
https://github.com/quarto-dev/quarto/archive/:quarto_mono
DISTFILES= core-dictionaries.zip:dictionaries \
gin-${GIN_VERSION}.zip:gin \
gwt-${GWT_VERSION}.tar.gz:gwt \
mathjax-27.zip:mathjax \
${QUARTO_MONO_COMMIT}.tar.gz:quarto_mono
MAINTAINER= yuri@FreeBSD.org
COMMENT= Integrated development environment (IDE) for R
WWW= https://www.rstudio.com/ \
https://github.com/rstudio/rstudio
LICENSE= AGPLv3
LICENSE_FILE= ${WRKSRC}/COPYING
BROKEN_i386= fails to resolve 'org.rstudio.studio.client.workbench.views.vcs.common.diff.LineActionButtonRenderer.GrayResources' via deferred binding
BUILD_DEPENDS= ant:devel/apache-ant \
${LOCALBASE}/include/sys/sysinfo.h:devel/libsysinfo \
node:www/node \
pandoc:textproc/hs-pandoc \
R-cran-rstudioapi>0:devel/R-cran-rstudioapi \
${LOCALBASE}/include/gsl/gsl-lite.hpp:devel/gsl-lite \
${LOCALBASE}/include/rapidjson/rapidjson.h:devel/rapidjson \
${LOCALBASE}/include/websocketpp/version.hpp:devel/websocketpp \
${LOCALBASE}/include/tl/expected.hpp:devel/tl-expected
LIB_DEPENDS= libR.so:math/R \
libboost_thread.so:devel/boost-libs \
libinotify.so:devel/libinotify \
libsoci_core.so:databases/soci \
libuuid.so:misc/libuuid \
libyaml-cpp.so:devel/yaml-cpp \
libfmt.so:devel/libfmt \
libhunspell-1.7.so:textproc/hunspell
BUILD_DEPENDS+= quarto:textproc/quarto
RUN_DEPENDS= quarto:textproc/quarto
FLAVORS= desktop server
FLAVOR?= ${FLAVORS:[1]}
server_PKGNAMESUFFIX= -server
server_BROKEN= does not build with the latest RStudio version, needs to be fixed
USES= cmake fortran java:build localbase:ldflags pgsql pkgconfig sqlite ssl
JAVA_VERSION= 17 # Build requires Java 17 target
USE_GITHUB= yes
GH_PROJECT= ${PORTNAME:tl}
GH_TUPLE= rstudio:r2d3:v0.2.0:r2d3/dependencies/common/r2d3 \
rstudio:rmarkdown:aed26ac:rmarkdown/dependencies/common/rmarkdown \
rstudio:rsconnect:03c379b:rsconnect/dependencies/common/rsconnect \
trestletech:plumber:v0.4.6:plumber/dependencies/common/plumber
CMAKE_ARGS= -DFREEBSD_RSTUDIO_VERSION:STRING=${PORTVERSION} \
-DFREEBSD_LIBDIR:STRING=${PREFIX}/lib \
-DRSTUDIO_DEPENDENCIES_QUARTO_DIR:STRING=${LOCALBASE}/share/quarto
CMAKE_ARGS+= -DQT_QMAKE_EXECUTABLE:STRING=${QMAKE}
CMAKE_ARGS+= -DRSTUDIO_BOOST_SIGNALS_VERSION=2
CMAKE_ARGS+= -DFREEBSD_PORT_VERSION:STRING=${DISTVERSION}
CMAKE_ARGS+= -DFREEBSD_LOCALBASE:STRING=${LOCALBASE} # SOCI package is looked up here, see patch patch-src_cpp_CMakeLists.txt
#CMAKE_ON= RSTUDIO_USE_SYSTEM_DEPENDENCIES
CMAKE_ON= RSTUDIO_USE_SYSTEM_YAML_CPP \
RSTUDIO_USE_SYSTEM_BOOST \
RSTUDIO_USE_SYSTEM_HUNSPELL \
RSTUDIO_USE_SYSTEM_SOCI \
RSTUDIO_USE_SYSTEM_FMT \
RSTUDIO_USE_SYSTEM_GSL_LITE \
RSTUDIO_USE_SYSTEM_RAPIDJSON \
RSTUDIO_USE_SYSTEM_WEBSOCKETPP \
RSTUDIO_USE_SYSTEM_TL_EXPECTED \
RSTUDIO_INSTALL_FREEDESKTOP
CMAKE_OFF= BUILD_TESTING \
RSTUDIO_UNIT_TESTS_ENABLED
MAKE_ENV= HOME=${WRKDIR} \
JAVA_HOME=${JAVA_HOME} \
PATH=${JAVA_HOME}/bin:${PATH} \
ANT_OPTS="-Duser.home=${WRKDIR}"
LDFLAGS+= -lexecinfo
GWT_VERSION= 2.12.2 # GWT_VER in src/gwt/tools/build-gwt
GIN_VERSION= 2.1.2
QUARTO_VERSION= 1.7.32 # Version expected by RStudio for panmirror build
QUARTO_MONO_COMMIT= 591b3520eafbb4da7b26b9f31aac6948801f19d8 # Commit from quarto monorepo with panmirror
.if ${FLAVOR:U} == desktop
COMMENT+= (desktop UI version)
USES+= desktop-file-utils shared-mime-info
FETCH_DEPENDS+= npm:www/npm \
yarn:www/yarn
BUILD_DEPENDS+= npm:www/npm \
yarn:www/yarn \
electron37:devel/electron37 \
zip:archivers/zip
RUN_DEPENDS+= electron37:devel/electron37
CMAKE_ARGS+= -DRSTUDIO_TARGET=Electron
MAKE_ENV+= ELECTRON_SKIP_BINARY_DOWNLOAD=1 \
npm_config_nodedir=${WRKDIR}/.electron-headers \
ELECTRON_ZIP_DIR=${WRKDIR}/.electron-zip
LDFLAGS+= -linotify
INSTALL_SUBDIR= ${PORTNAME:tl}
EXECUTABLE= ${PORTNAME:tl}
# npm dependencies are pre-fetched during post-fetch phase
NPM_DISTDIR= ${DISTDIR}/${PORTNAME}
NPM_TARBALL= ${PORTNAME}-desktop-node_modules-${DISTVERSION}${EXTRACT_SUFX}
# quarto/panmirror dependencies (uses yarn workspaces)
QUARTO_TARBALL= ${PORTNAME}-quarto-node_modules-${DISTVERSION}${EXTRACT_SUFX}
# Add npm tarballs to DISTFILES for checksum verification
#DISTFILES+= ${PORTNAME}/${NPM_TARBALL}:prefetch \
${PORTNAME}/${QUARTO_TARBALL}:prefetch
.endif
.if ${FLAVOR:U} == server
COMMENT+= (web UI version)
CMAKE_ARGS+= -DRSTUDIO_TARGET=Server
LDFLAGS+= -linotify
INSTALL_SUBDIR= ${PORTNAME:tl}-server
EXECUTABLE= rserver
USER= nobody
SUB_LIST= USER=${USER}
USE_RC_SUBR= ${PORTNAME:tl}-server
.endif
OPTIONS_DEFINE= COPILOT WITH_QUARTO
OPTIONS_DEFAULT= COPILOT WITH_QUARTO
COPILOT_DESC= Build with Copilot support
COPILOT_CMAKE_BOOL= RSTUDIO_ENABLE_COPILOT
COPILOT_RUN_DEPENDS= copilot-language-server:misc/github-copilot-language-server
WITH_QUARTO_DESC= Build with support for Quarto
WITH_QUARTO_CMAKE_BOOL= QUARTO_ENABLED
# Custom fetch for desktop npm dependencies
.if ${FLAVOR:U} == desktop
post-fetch:
@if ! [ -f ${NPM_DISTDIR}/${NPM_TARBALL} ]; then \
${MKDIR} ${NPM_DISTDIR} && \
${ECHO_MSG} "====> Fetching npm dependencies for desktop into the tarball ${NPM_DISTDIR}/${NPM_TARBALL} ..." && \
${MKDIR} ${WRKDIR}/tmp/rstudio-npm-fetch && \
${FETCH_CMD} -q "https://raw.githubusercontent.com/rstudio/rstudio/v${DISTVERSION}/src/node/desktop/package.json" -o ${WRKDIR}/tmp/rstudio-npm-fetch/package.json && \
cd ${WRKDIR}/tmp/rstudio-npm-fetch && \
HOME=${WRKDIR}/tmp/rstudio-npm-fetch npm install --ignore-scripts && \
${FIND} node_modules -exec ${TOUCH} -h -d 1970-01-01T00:00:00Z {} \; 2>/dev/null; \
${TAR} -czf ${NPM_DISTDIR}/${NPM_TARBALL} node_modules && \
${RM} -rf ${WRKDIR}/tmp/rstudio-npm-fetch && \
${ECHO_MSG} "====> Created npm dependencies tarball ${NPM_DISTDIR}/${NPM_TARBALL}"; \
else \
${ECHO_MSG} "====> Using previously fetched npm dependencies tarball ${NPM_DISTDIR}/${NPM_TARBALL}"; \
fi
@if ! [ -f ${NPM_DISTDIR}/${QUARTO_TARBALL} ]; then \
${MKDIR} ${NPM_DISTDIR} && \
${ECHO_MSG} "====> Fetching quarto/panmirror npm dependencies into the tarball ${NPM_DISTDIR}/${QUARTO_TARBALL} ..." && \
${MKDIR} ${WRKDIR}/tmp/rstudio-quarto-fetch && \
cd ${WRKDIR}/tmp/rstudio-quarto-fetch && \
${FETCH_CMD} -q "https://github.com/quarto-dev/quarto/archive/${QUARTO_MONO_COMMIT}.tar.gz" -o quarto.tar.gz && \
${TAR} -xzf quarto.tar.gz && \
cd quarto-${QUARTO_MONO_COMMIT} && \
HOME=${WRKDIR}/tmp/rstudio-quarto-fetch yarn install --ignore-scripts --network-timeout 240000 && \
cd apps/panmirror && PANMIRROR_OUTDIR=dist-rstudio yarn build --minify true --sourcemap true && cd ../.. && \
${FIND} node_modules apps/*/node_modules packages/*/node_modules apps/panmirror/dist-rstudio -exec ${TOUCH} -h -d 1970-01-01T00:00:00Z {} \; 2>/dev/null; \
${TAR} -czf ${NPM_DISTDIR}/${QUARTO_TARBALL} node_modules apps/*/node_modules packages/*/node_modules apps/panmirror/dist-rstudio && \
${RM} -rf ${WRKDIR}/tmp/rstudio-quarto-fetch && \
${ECHO_MSG} "====> Created quarto npm dependencies tarball ${NPM_DISTDIR}/${NPM_TARBALL}"; \
else \
${ECHO_MSG} "====> Using previously fetched quarto npm dependencies tarball ${NPM_DISTDIR}/${QUARTO_TARBALL}"; \
fi
.endif
post-extract:
@${MKDIR} ${WRKSRC}/dependencies/dictionaries && ${MV} ${WRKDIR}/en_* ${WRKSRC}/dependencies/dictionaries/
@${MV} ${WRKDIR}/mathjax-* ${WRKSRC}/dependencies/
# GWT libraries go into dependencies/common/gwtproject
@${MKDIR} ${WRKSRC}/dependencies/common/gwtproject/gwt && ${MV} ${WRKDIR}/gwt/gwt-rstudio ${WRKSRC}/dependencies/common/gwtproject/gwt/
@${MKDIR} ${WRKSRC}/dependencies/common/gwtproject/gin/${GIN_VERSION}
@${MV} ${WRKDIR}/gin-${GIN_VERSION}.jar ${WRKSRC}/dependencies/common/gwtproject/gin/${GIN_VERSION}/
@${MV} ${WRKDIR}/aopalliance.jar ${WRKSRC}/dependencies/common/gwtproject/gin/${GIN_VERSION}/
@${MV} ${WRKDIR}/guice-*.jar ${WRKSRC}/dependencies/common/gwtproject/gin/${GIN_VERSION}/
@${MV} ${WRKDIR}/javax.inject.jar ${WRKSRC}/dependencies/common/gwtproject/gin/${GIN_VERSION}/
# Copy other gwtproject dependencies from extracted gwt tarball
@${MV} ${WRKDIR}/elemental2 ${WRKSRC}/dependencies/common/gwtproject/
@${MV} ${WRKDIR}/jsinterop ${WRKSRC}/dependencies/common/gwtproject/
@${MV} ${WRKDIR}/jspecify ${WRKSRC}/dependencies/common/gwtproject/
# Setup quarto monorepo for panmirror build
# Copy entire quarto monorepo structure (needed for yarn workspaces)
@${MV} ${WRKDIR}/quarto-${QUARTO_MONO_COMMIT} ${WRKSRC}/src/gwt/lib/quarto
# add hunspell discovery module
@${CP} ${FILESDIR}/Findhunspell.cmake ${WRKSRC}/cmake/modules
.if ${FLAVOR:U} == desktop
# Extract pre-fetched npm node_modules for desktop electron build
@${ECHO_MSG} "====> Extracting pre-fetched npm dependencies..."
@cd ${WRKSRC}/src/node/desktop && ${TAR} -xzf ${NPM_DISTDIR}/${NPM_TARBALL}
# Extract pre-fetched quarto/panmirror npm dependencies
@${ECHO_MSG} "====> Extracting pre-fetched quarto npm dependencies..."
@cd ${WRKSRC}/src/gwt/lib/quarto && ${TAR} -xzf ${NPM_DISTDIR}/${QUARTO_TARBALL}
# Patch native modules binding.gyp to support FreeBSD (treat as Linux)
@${REINPLACE_CMD} "s/'OS==\"linux\"'/'OS==\"linux\" or OS==\"freebsd\"'/" \
${WRKSRC}/src/node/desktop/node_modules/node-system-fonts/binding.gyp
# For msgpackr-extract: add FreeBSD support and set compiler to cc
@${REINPLACE_CMD} -e "s/\"OS=='linux'\"/\"OS=='linux' or OS=='freebsd'\"/" \
-e 's/"os_linux_compiler%": "gcc"/"os_linux_compiler%": "cc"/' \
${WRKSRC}/src/node/desktop/node_modules/msgpackr-extract/binding.gyp
.endif
post-patch:
# quarto node_modules are pre-fetched and extracted
# Add Java 17+ compatibility args for GWT/Guice reflection
@${REINPLACE_CMD} -e ' \
s|</java>|<jvmarg value="-Duser.home=${WRKDIR}"/><jvmarg value="--add-opens=java.base/java.lang=ALL-UNNAMED"/></java>|' \
${WRKSRC}/src/gwt/build.xml
@${REINPLACE_CMD} -e ' \
s|rHomePaths.push_back|//rHomePaths.push_back|; \
s|//rHomePaths.push_back(FilePath("/usr/local/lib/|rHomePaths.push_back(FilePath("${PREFIX}/lib/|' \
${WRKSRC}/src/cpp/core/r_util/RVersionsPosix.cpp
@${REINPLACE_CMD} -e ' \
s|<condition property="node.bin" value="../../../$${node.dir}/bin/node">|<condition property="node.bin" value="${LOCALBASE}/bin/node">|' \
${WRKSRC}/src/gwt/build.xml
# quarto dependency
${LN} -s ${LOCALBASE}/share/quarto ${WRKSRC}/dependencies/quarto
# add $PREFIX/bin to PATH for the server daemon
.if ${FLAVOR:U} == server
@${REINPLACE_CMD} -e 's|%%PREFIX%%|${PREFIX}|' ${WRKSRC}/src/cpp/session/modules/SessionGit.cpp
.endif
# substitute LOCALBASE for copilot-language-server path
@${REINPLACE_CMD} -e 's|%%LOCALBASE%%|${LOCALBASE}|' ${WRKSRC}/src/cpp/session/include/session/SessionConstants.hpp
# correct for boost-1.87+ class replacement
@${FIND} ${WRKSRC} -name "*.cpp" -o -name "*.hpp" | ${XARGS} ${REINPLACE_CMD} -i "" -e 's/io_service/io_context/g'
pre-build:
#@${CP} ${FILESDIR}/global-setenv.h ${WRKSRC}/src/cpp/desktop/
#@${REINPLACE_CMD} -e 's|%%PREFIX%%|${PREFIX}|g' ${WRKSRC}/src/cpp/desktop/global-setenv.h
.if ${FLAVOR:U} == desktop
# Create proper electron headers structure for node-gyp
# node-gyp expects common.gypi at root and headers at include/node
@${MKDIR} ${WRKDIR}/.electron-headers
@${LN} -sf ${LOCALBASE}/share/electron37/node_headers/include ${WRKDIR}/.electron-headers/include
@${LN} -sf ${LOCALBASE}/share/electron37/node_headers/include/node/common.gypi ${WRKDIR}/.electron-headers/common.gypi
# Create electron ZIP for electron-packager (expects electron-v{VERSION}-linux-x64.zip)
@${MKDIR} ${WRKDIR}/.electron-zip
@cd ${LOCALBASE}/share/electron37 && zip -rq ${WRKDIR}/.electron-zip/electron-v37.6.1-linux-x64.zip \
electron chromedriver *.so *.pak *.bin *.json locales resources version LICENSE LICENSES.chromium.html
.endif
post-install:
.if ${FLAVOR:U} == desktop
# Desktop flavor: create launcher script that uses electron37
@(echo "#!/bin/sh"; \
echo ""; \
echo "if ! [ -d /proc/curproc ]; then"; \
echo " echo \"${PORTNAME} needs /proc to be mounted as procfs\" >&2"; \
echo " exit 1"; \
echo "fi"; \
echo ""; \
echo "# Environment setup"; \
echo "export LD_PRELOAD=${PREFIX}/lib/gcc${GCC_DEFAULT}/libgcc_s.so"; \
echo "export JAVA_HOME=${JAVA_HOME}"; \
echo "export ELECTRON_IS_DEV=0"; \
echo "export ELECTRON_FORCE_IS_PACKAGED=true"; \
echo ""; \
echo "exec ${PREFIX}/bin/electron37 ${PREFIX}/resources/app \"\$$@\"" \
) > ${STAGEDIR}${PREFIX}/bin/${EXECUTABLE}
@${CHMOD} +x ${STAGEDIR}${PREFIX}/bin/${EXECUTABLE}
-${REINPLACE_CMD} -i '' -e 's|^Exec=.*/rstudio|Exec=${PREFIX}/bin/${EXECUTABLE}|' ${STAGEDIR}${PREFIX}/share/applications/${EXECUTABLE}.desktop 2>/dev/null || true
.else
# Server flavor: create launcher script for rserver
@(echo "#!/bin/sh"; \
echo ""; \
echo "if ! [ -d /proc/curproc ]; then"; \
echo " echo \"${PORTNAME} needs /proc to be mounted as procfs\" >&2"; \
echo " exit 1"; \
echo "fi"; \
echo ""; \
echo "# workaround for the problem that RStudio passes /lib with LD_LIBRARY_PATH that causes the /lib/libgcc_s.so.1 conflict with gcc"; \
echo "LD_PRELOAD=${PREFIX}/lib/gcc${GCC_DEFAULT}/libgcc_s.so JAVA_HOME=${JAVA_HOME} ${PREFIX}/lib/${INSTALL_SUBDIR}/bin/${EXECUTABLE} \"\$$@\"" \
) > ${STAGEDIR}${PREFIX}/bin/${EXECUTABLE}
@${CHMOD} +x ${STAGEDIR}${PREFIX}/bin/${EXECUTABLE}
.endif
.if ${FLAVOR:U} == server
${RM} ${STAGEDIR}${LOCALBASE}/lib/${INSTALL_SUBDIR}/bin/rstudio-server # not compatible with FreeBSD
.endif
# Remove quarto files since quarto is installed by the quarto port
${RM} -rf ${STAGEDIR}${PREFIX}/bin/quarto
# Some functions expect the pandoc symlink.
@${MKDIR} ${STAGEDIR}${PREFIX}/lib/${INSTALL_SUBDIR}/bin/pandoc
@cd ${STAGEDIR}${PREFIX}/lib/${INSTALL_SUBDIR}/bin/pandoc && ${LN} -s ../../../../bin/pandoc
# There is a variability in .js file names due to use of random numbers, so we use the automatic plist.
@${SETENV} ${CO_ENV} ${SH} ${SCRIPTSDIR}/check-stagedir.sh makeplist | ${GREP} -v ^\/ | ${SED} -e 's|%%WWWDIR%%|www/rstudio| ; s|%%CMAKE_BUILD_TYPE%%|${CMAKE_BUILD_TYPE:tl}|' > ${TMPPLIST}
DISTINFO_FILE= ${.CURDIR}/distinfo.${FLAVOR}
.include <bsd.port.mk>
|