@@ -508,6 +508,85 @@ fn main() {
508508 }
509509 }
510510
511+ // extract the target-cpu config value, if specified
512+ let target_cpu = std:: env:: var ( "CARGO_ENCODED_RUSTFLAGS" )
513+ . ok ( )
514+ . and_then ( |rustflags| {
515+ rustflags
516+ . split ( '\x1f' )
517+ . find ( |f| f. contains ( "target-cpu=" ) )
518+ . and_then ( |f| f. split ( "target-cpu=" ) . nth ( 1 ) )
519+ . map ( |s| s. to_string ( ) )
520+ } ) ;
521+
522+ if target_cpu == Some ( "native" . into ( ) ) {
523+ debug_log ! ( "Detected target-cpu=native, compiling with GGML_NATIVE" ) ;
524+ config. define ( "GGML_NATIVE" , "ON" ) ;
525+ }
526+ // if native isn't specified, enable specific features for ggml instead
527+ else {
528+ // rust code isn't using `target-cpu=native`, so llama.cpp shouldn't use GGML_NATIVE either
529+ config. define ( "GGML_NATIVE" , "OFF" ) ;
530+
531+ // if `target-cpu` is set set, also set -march for llama.cpp to the same value
532+ if let Some ( ref cpu) = target_cpu {
533+ debug_log ! ( "Setting baseline architecture: -march={}" , cpu) ;
534+ config. cflag ( & format ! ( "-march={}" , cpu) ) ;
535+ config. cxxflag ( & format ! ( "-march={}" , cpu) ) ;
536+ }
537+
538+ // I expect this env var to always be present
539+ let features = std:: env:: var ( "CARGO_CFG_TARGET_FEATURE" )
540+ . expect ( "Env var CARGO_CFG_TARGET_FEATURE not found." ) ;
541+ debug_log ! ( "Compiling with target features: {}" , features) ;
542+
543+ // list of rust target_features here:
544+ // https://doc.rust-lang.org/reference/attributes/codegen.html#the-target_feature-attribute
545+ // GGML config flags have been found by looking at:
546+ // llama.cpp/ggml/src/ggml-cpu/CMakeLists.txt
547+ for feature in features. split ( ',' ) {
548+ match feature {
549+ "avx" => {
550+ config. define ( "GGML_AVX" , "ON" ) ;
551+ }
552+ "avx2" => {
553+ config. define ( "GGML_AVX2" , "ON" ) ;
554+ }
555+ "avx512bf16" => {
556+ config. define ( "GGML_AVX512_BF16" , "ON" ) ;
557+ }
558+ "avx512vbmi" => {
559+ config. define ( "GGML_AVX512_VBMI" , "ON" ) ;
560+ }
561+ "avx512vnni" => {
562+ config. define ( "GGML_AVX512_VNNI" , "ON" ) ;
563+ }
564+ "avxvnni" => {
565+ config. define ( "GGML_AVX_VNNI" , "ON" ) ;
566+ }
567+ "bmi2" => {
568+ config. define ( "GGML_BMI2" , "ON" ) ;
569+ }
570+ "f16c" => {
571+ config. define ( "GGML_F16C" , "ON" ) ;
572+ }
573+ "fma" => {
574+ config. define ( "GGML_FMA" , "ON" ) ;
575+ }
576+ "sse4.2" => {
577+ config. define ( "GGML_SSE42" , "ON" ) ;
578+ }
579+ _ => {
580+ debug_log ! (
581+ "Unrecognized cpu feature: '{}' - skipping GGML config for it." ,
582+ feature
583+ ) ;
584+ continue ;
585+ }
586+ } ;
587+ }
588+ }
589+
511590 config. define (
512591 "BUILD_SHARED_LIBS" ,
513592 if build_shared_libs { "ON" } else { "OFF" } ,
@@ -627,9 +706,9 @@ fn main() {
627706
628707 if matches ! ( target_os, TargetOs :: Linux )
629708 && target_triple. contains ( "aarch64" )
630- && env :: var ( format ! ( "CARGO_FEATURE_{}" , " native". to_uppercase ( ) ) ) . is_err ( )
709+ && target_cpu != Some ( " native". into ( ) )
631710 {
632- // If the native feature is not enabled , we take off the native ARM64 support.
711+ // If the target-cpu is not specified as native , we take off the native ARM64 support.
633712 // It is useful in docker environments where the native feature is not enabled.
634713 config. define ( "GGML_NATIVE" , "OFF" ) ;
635714 config. define ( "GGML_CPU_ARM_ARCH" , "armv8-a" ) ;
0 commit comments