@@ -237,14 +237,28 @@ def checkBuildTools() {
237237 }
238238
239239 // Check for autotools (needed for building secp256k1)
240- def hasAutotools = false
241- try {
242- exec { commandLine ' sh' , ' -c' , ' command -v autoconf && command -v automake && command -v libtool' ; standardOutput = new ByteArrayOutputStream (); ignoreExitValue = true }
243- hasAutotools = true
244- } catch (Exception e) {
245- println " [secp] Warning: autotools not fully available"
240+ // aclocal is part of automake and is required by autogen.sh
241+ def autotoolsRequired = [' autoconf' , ' automake' , ' libtool' , ' aclocal' ]
242+ def autotoolsMissing = []
243+
244+ autotoolsRequired. each { tool ->
245+ def toolCheck = new ByteArrayOutputStream ()
246+ try {
247+ exec {
248+ commandLine ' sh' , ' -c' , " command -v ${ tool} "
249+ standardOutput = toolCheck
250+ ignoreExitValue = true
251+ }
252+ if (! toolCheck. toString(). trim()) {
253+ autotoolsMissing << tool
254+ }
255+ } catch (Exception e) {
256+ autotoolsMissing << tool
257+ }
246258 }
247259
260+ def hasAutotools = autotoolsMissing. isEmpty()
261+
248262 if (! hasCurl || ! hasTar) {
249263 throw new GradleException ("""
250264 Missing required build tools: ${ requiredTools.join(', ')}
@@ -264,8 +278,23 @@ def checkBuildTools() {
264278 }
265279
266280 if (! hasAutotools) {
267- println " [secp] WARNING: autotools may not be fully installed. Build might fail."
268- println " [secp] Install with: sudo apt-get install -y build-essential autoconf automake libtool"
281+ throw new GradleException ("""
282+ Missing required autotools: ${ autotoolsMissing.join(', ')}
283+
284+ For Bitrise, add this step before gradle build:
285+
286+ - script:
287+ title: Install build dependencies
288+ inputs:
289+ - content: |
290+ #!/bin/bash
291+ set -ex
292+ # Ubuntu/Debian
293+ sudo apt-get update
294+ sudo apt-get install -y build-essential autoconf automake libtool curl tar git
295+
296+ Note: aclocal is part of automake package and is required for autogen.sh
297+ """ )
269298 }
270299
271300 return [hasGit : hasGit, hasCurl : hasCurl, hasTar : hasTar, hasAutotools : hasAutotools]
@@ -352,9 +381,10 @@ def abis = ['armeabi-v7a','arm64-v8a']
352381abis. each { abi ->
353382 def meta = abiMatrix[abi]
354383 def ccTrip = " ${ meta.target}${ meta.api} -clang"
355- def arTool = " ${ meta.host} -ar"
356- def ranlibTool = " ${ meta.host} -ranlib"
357- def stripTool = " ${ meta.host} -strip"
384+ // Use LLVM tools for consistency (NDK r25+)
385+ def arTool = ' llvm-ar'
386+ def ranlibTool = ' llvm-ranlib'
387+ def stripTool = ' llvm-strip'
358388
359389 def installDir = file(" ${ installRoot} /${ abi} " )
360390 def stagedLib = file(" ${ outputsRoot} /${ abi} /lib/libsecp256k1.so" )
@@ -382,7 +412,19 @@ abis.each { abi ->
382412 libDirOut. mkdirs()
383413 file(" ${ buildDir} /stamps" ). mkdirs()
384414
385- exec { workingDir workDir; commandLine ' bash' , ' -lc' , ' ./autogen.sh' }
415+ // Run autogen.sh if configure script doesn't exist
416+ def configureScript = new File (workDir, ' configure' )
417+ if (! configureScript. exists()) {
418+ println " [secp:${ abi} ] Running autogen.sh to generate configure script..."
419+ exec {
420+ workingDir workDir
421+ commandLine ' bash' , ' -c' , ' ./autogen.sh'
422+ // Ensure PATH includes standard locations for autotools
423+ environment ' PATH' , System . getenv(' PATH' )
424+ }
425+ } else {
426+ println " [secp:${ abi} ] Configure script already exists, skipping autogen.sh"
427+ }
386428
387429 println " [secp:${ abi} ] Using API level ${ meta.api} (unified)"
388430
@@ -413,9 +455,9 @@ abis.each { abi ->
413455 workingDir workDir
414456 environment ' CC' , new File (toolBin, ccTrip). absolutePath
415457 // Use LLVM binutils with libtool-friendly flags (NDK r25+)
416- environment ' AR' , new File (toolBin, ' llvm-ar ' ). absolutePath
458+ environment ' AR' , new File (toolBin, arTool ). absolutePath
417459 environment ' ARFLAGS' , ' crs'
418- environment ' RANLIB' , new File (toolBin, ' llvm-ranlib ' ). absolutePath
460+ environment ' RANLIB' , new File (toolBin, ranlibTool ). absolutePath
419461 environment ' NM' , new File (toolBin, ' llvm-nm' ). absolutePath
420462 environment ' STRIP' , new File (toolBin, stripTool). absolutePath
421463 // Architecture-appropriate CFLAGS
@@ -472,30 +514,33 @@ abis.each { abi ->
472514
473515 doLast {
474516 def jobs = project. findProperty(' jobs' ) ?: Runtime . runtime. availableProcessors()
475- // Platform-specific libtool
517+ def buildOutput = new ByteArrayOutputStream ()
518+ def buildError = new ByteArrayOutputStream ()
519+
520+ // Platform-specific libtool
476521 def libtoolize = isMac() ? ' glibtoolize' : ' libtoolize'
477522 def libtool = isMac() ? ' glibtool' : ' libtool'
523+
478524 exec {
479- workingDir workDir
480- environment ' LIBS' , ' -llog'
481- commandLine ' bash' , ' -lc' , " make -j${ jobs} && make install"
482- }
483-
484- exec {
485525 workingDir workDir
486526 environment ' LIBS' , ' -llog'
487527 environment ' LIBTOOLIZE' , libtoolize
488- environment ' LIBTOOL' , libtool
528+ environment ' LIBTOOL' , libtool
489529 // Don't use login shell
490530 commandLine ' bash' , ' -c' , " make -j${ jobs} && make install"
491-
492- // Capture output
493- standardOutput = new ByteArrayOutputStream ()
494- errorOutput = new ByteArrayOutputStream ()
495- println " [secp:${ abi} ] build output (last 50 lines): ${ standardOutput.toString().readLines().takeRight(50).join('\n')} "
496- if (errorOutput. toString()) {
497- println " [secp:${ abi} ] build errors: ${ errorOutput.toString()} "
498- }
531+ standardOutput = buildOutput
532+ errorOutput = buildError
533+ }
534+
535+ // Print output for debugging
536+ def outputLines = buildOutput. toString(). readLines()
537+ if (outputLines. size() > 50 ) {
538+ println " [secp:${ abi} ] build output (last 50 lines): ${ outputLines.takeRight(50).join('\n')} "
539+ } else {
540+ println " [secp:${ abi} ] build output: ${ buildOutput.toString()} "
541+ }
542+ if (buildError. toString()) {
543+ println " [secp:${ abi} ] build errors: ${ buildError.toString()} "
499544 }
500545
501546 copy {
0 commit comments