libzypp: zypp/Arch.cc Source File

libzypp 17.38.6

Arch.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12
13
14extern "C"
15{
16#include <features.h>
17#include <sys/utsname.h>
18#if __GLIBC_PREREQ (2,16)
19#include <sys/auxv.h> // getauxval for PPC64P7 detection
20#endif
21#include <unistd.h>
22}
23
24#include <iostream>
25#include <list>
26#include <fstream>
27
28#include <zypp-core/base/IOStream.h>
29#include <zypp-core/base/Logger.h>
30#include <zypp-core/base/Exception.h>
31#include <zypp-core/base/NonCopyable.h>
32#include <zypp-core/base/Hash.h>
33#include <zypp-core/fs/PathInfo.h>
34#include <zypp/Arch.h>
35#include <zypp/Bit.h>
36
37using std::endl;
38
40namespace zypp
41{
42
43 namespace {
44 // From rpm's lib/rpmrc.c
45# if defined(__linux__) && defined(__x86_64__)
46 inline void cpuid(uint32_t op, uint32_t op2, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
47 {
48 asm volatile (
49 "cpuid\n"
50 : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
51 : "a" (op), "c" (op2));
52 }
53
54 /* From gcc's gcc/config/i386/cpuid.h */
55 /* Features (%eax == 1) */
56 /* %ecx */
57 #define bit_SSE3 (1 << 0)
58 #define bit_SSSE3 (1 << 9)
59 #define bit_FMA (1 << 12)
60 #define bit_CMPXCHG16B (1 << 13)
61 #define bit_SSE4_1 (1 << 19)
62 #define bit_SSE4_2 (1 << 20)
63 #define bit_MOVBE (1 << 22)
64 #define bit_POPCNT (1 << 23)
65 #define bit_OSXSAVE (1 << 27)
66 #define bit_AVX (1 << 28)
67 #define bit_F16C (1 << 29)
68
69 /* Extended Features (%eax == 0x80000001) */
70 /* %ecx */
71 #define bit_LAHF_LM (1 << 0)
72 #define bit_LZCNT (1 << 5)
73
74 /* Extended Features (%eax == 7) */
75 /* %ebx */
76 #define bit_BMI (1 << 3)
77 #define bit_AVX2 (1 << 5)
78 #define bit_BMI2 (1 << 8)
79 #define bit_AVX512F (1 << 16)
80 #define bit_AVX512DQ (1 << 17)
81 #define bit_AVX512CD (1 << 28)
82 #define bit_AVX512BW (1 << 30)
83 #define bit_AVX512VL (1u << 31)
84
85 int get_x86_64_level(void)
86 {
87 int level = 1;
88
89 unsigned int op_1_ecx = 0, op_80000001_ecx = 0, op_7_ebx = 0, unused = 0;
90 cpuid(1, 0, &unused, &unused, &op_1_ecx, &unused);
91 cpuid(0x80000001, 0, &unused, &unused, &op_80000001_ecx, &unused);
92 cpuid(7, 0, &unused, &op_7_ebx, &unused, &unused);
93
94 const unsigned int op_1_ecx_lv2 = bit_SSE3 | bit_SSSE3 | bit_CMPXCHG16B | bit_SSE4_1 | bit_SSE4_2 | bit_POPCNT;
95 if ((op_1_ecx & op_1_ecx_lv2) == op_1_ecx_lv2 && (op_80000001_ecx & bit_LAHF_LM))
96 level = 2;
97
98 const unsigned int op_1_ecx_lv3 = bit_FMA | bit_MOVBE | bit_OSXSAVE | bit_AVX | bit_F16C;
99 const unsigned int op_7_ebx_lv3 = bit_BMI | bit_AVX2 | bit_BMI2;
100 if (level == 2 && (op_1_ecx & op_1_ecx_lv3) == op_1_ecx_lv3 && (op_7_ebx & op_7_ebx_lv3) == op_7_ebx_lv3
101 && (op_80000001_ecx & bit_LZCNT))
102 level = 3;
103
104 const unsigned int op_7_ebx_lv4 = bit_AVX512F | bit_AVX512DQ | bit_AVX512CD | bit_AVX512BW | bit_AVX512VL;
105 if (level == 3 && (op_7_ebx & op_7_ebx_lv4) == op_7_ebx_lv4)
106 level = 4;
107
108 return level;
109 }
110# endif
111
112 Arch _autoDetectSystemArchitecture() {
113 struct ::utsname buf;
114 if ( ::uname( &buf ) < 0 )
115 {
116 ERR << "Can't determine system architecture" << endl;
117 return Arch_noarch;
118 }
119
120 Arch architecture( buf.machine );
121 MIL << "Uname architecture is '" << buf.machine << "'" << endl;
122
123 if ( architecture == Arch_x86_64 )
124 {
125 #if defined(__linux__) && defined(__x86_64__)
126 switch ( get_x86_64_level() )
127 {
128 case 2:
129 architecture = Arch_x86_64_v2;
130 WAR << "CPU has 'x86_64': architecture upgraded to '" << architecture << "'" << endl;
131 break;
132 case 3:
133 architecture = Arch_x86_64_v3;
134 WAR << "CPU has 'x86_64': architecture upgraded to '" << architecture << "'" << endl;
135 break;
136 case 4:
137 architecture = Arch_x86_64_v4;
138 WAR << "CPU has 'x86_64': architecture upgraded to '" << architecture << "'" << endl;
139 break;
140 }
141 # endif
142 }
143 else if ( architecture == Arch_i686 )
144 {
145 // some CPUs report i686 but dont implement cx8 and cmov
146 // check for both flags in /proc/cpuinfo and downgrade
147 // to i586 if either is missing (cf bug #18885)
148 std::ifstream cpuinfo( "/proc/cpuinfo" );
149 if ( cpuinfo )
150 {
151 for( iostr::EachLine in( cpuinfo ); in; in.next() )
152 {
153 if ( str::hasPrefix( *in, "flags" ) )
154 {
155 if ( in->find( "cx8" ) == std::string::npos
156 || in->find( "cmov" ) == std::string::npos )
157 {
158 architecture = Arch_i586;
159 WAR << "CPU lacks 'cx8' or 'cmov': architecture downgraded to '" << architecture << "'" << endl;
160 }
161 break;
162 }
163 }
164 }
165 else
166 {
167 ERR << "Cant open " << PathInfo("/proc/cpuinfo") << endl;
168 }
169 }
170 else if ( architecture == Arch_sparc || architecture == Arch_sparc64 )
171 {
172 // Check for sun4[vum] to get the real arch. (bug #566291)
173 std::ifstream cpuinfo( "/proc/cpuinfo" );
174 if ( cpuinfo )
175 {
176 for( iostr::EachLine in( cpuinfo ); in; in.next() )
177 {
178 if ( str::hasPrefix( *in, "type" ) )
179 {
180 if ( in->find( "sun4v" ) != std::string::npos )
181 {
182 architecture = ( architecture == Arch_sparc64 ? Arch_sparc64v : Arch_sparcv9v );
183 WAR << "CPU has 'sun4v': architecture upgraded to '" << architecture << "'" << endl;
184 }
185 else if ( in->find( "sun4u" ) != std::string::npos )
186 {
187 architecture = ( architecture == Arch_sparc64 ? Arch_sparc64 : Arch_sparcv9 );
188 WAR << "CPU has 'sun4u': architecture upgraded to '" << architecture << "'" << endl;
189 }
190 else if ( in->find( "sun4m" ) != std::string::npos )
191 {
192 architecture = Arch_sparcv8;
193 WAR << "CPU has 'sun4m': architecture upgraded to '" << architecture << "'" << endl;
194 }
195 break;
196 }
197 }
198 }
199 else
200 {
201 ERR << "Cant open " << PathInfo("/proc/cpuinfo") << endl;
202 }
203 }
204 else if ( architecture == Arch_armv8l || architecture == Arch_armv7l || architecture == Arch_armv6l )
205 {
206 std::ifstream platform( "/etc/rpm/platform" );
207 if (platform)
208 {
209 for( iostr::EachLine in( platform ); in; in.next() )
210 {
211 if ( str::hasPrefix( *in, "armv8hl-" ) )
212 {
213 architecture = Arch_armv8hl;
214 WAR << "/etc/rpm/platform contains armv8hl-: architecture upgraded to '" << architecture << "'" << endl;
215 break;
216 }
217 if ( str::hasPrefix( *in, "armv7hl-" ) )
218 {
219 architecture = Arch_armv7hl;
220 WAR << "/etc/rpm/platform contains armv7hl-: architecture upgraded to '" << architecture << "'" << endl;
221 break;
222 }
223 if ( str::hasPrefix( *in, "armv6hl-" ) )
224 {
225 architecture = Arch_armv6hl;
226 WAR << "/etc/rpm/platform contains armv6hl-: architecture upgraded to '" << architecture << "'" << endl;
227 break;
228 }
229 }
230 }
231 }
232 #if __GLIBC_PREREQ (2,16)
233 else if ( architecture == Arch_ppc64 )
234 {
235 const char * platform = (const char *)getauxval( AT_PLATFORM );
236 int powerlvl = 0;
237 if ( platform && sscanf( platform, "power%d", &powerlvl ) == 1 && powerlvl > 6 )
238 architecture = Arch_ppc64p7;
239 }
240 #endif
241 return architecture;
242 }
243
244 }
245
246
247
249 //
250 // CLASS NAME : Arch::CompatEntry
251 //
257 struct Arch::CompatEntry
258 {
263 using CompatBits = bit::BitField<uint64_t>;
264
265 CompatEntry( const std::string & archStr_r,
266 CompatBits::IntT idBit_r = 1 )
267 : _idStr( archStr_r )
268 , _archStr( archStr_r )
269 , _idBit( idBit_r )
270 , _compatBits( idBit_r )
271 {}
272
273 CompatEntry( IdString archStr_r,
274 CompatBits::IntT idBit_r = 1 )
275 : _idStr( archStr_r )
276 , _archStr( archStr_r.asString() )
277 , _idBit( idBit_r )
278 , _compatBits( idBit_r )
279 {}
280
281 void addCompatBit( const CompatBits & idBit_r ) const
282 {
283 if ( idBit_r && ! (_compatBits & idBit_r) )
284 {
285 _compatBits |= idBit_r;
286 }
287 }
288
290 bool compatibleWith( const CompatEntry & targetEntry_r ) const
291 {
292 switch ( _idBit.value() )
293 {
294 case 0:
295 // this is noarch and always comatible
296 return true;
297 break;
298 case 1:
299 // this is a non builtin: self compatible only
300 return _archStr == targetEntry_r._archStr;
301 break;
302 }
303 // This is a builtin: compatible if mentioned in targetEntry_r
304 return bool( targetEntry_r._compatBits & _idBit );
305 }
306
308 int compare( const CompatEntry & rhs ) const
309 {
310 if ( _idBit.value() != rhs. _idBit.value() )
311 return( _idBit.value() < rhs. _idBit.value() ? -1 : 1 );
312 return _archStr.compare( rhs._archStr ); // Id 1: non builtin
313 }
314
315 bool isBuiltIn() const
316 { return( _idBit != CompatBits(1) ); }
317
318 IdString::IdType id() const
319 { return _idStr.id(); }
320
321 IdString _idStr;
322 std::string _archStr; // frequently used by the UI so we keep a reference
323 CompatBits _idBit;
324 mutable CompatBits _compatBits;
325 };
326
327
329 inline std::ostream & operator<<( std::ostream & str, const Arch::CompatEntry & obj )
330 {
331 Arch::CompatEntry::CompatBits bit( obj._idBit );
332 unsigned bitnum = 0;
333 while ( bit )
334 {
335 ++bitnum;
336 bit >>= 1;
337 }
338 return str << str::form( "%-15s ", obj._archStr.c_str() ) << str::numstring(bitnum,2) << ' '
339 << obj._compatBits << ' ' << obj._compatBits.value();
340 }
341
343 inline bool operator==( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs )
344 { return lhs._idStr == rhs._idStr; }
345
346 inline bool operator!=( const Arch::CompatEntry & lhs, const Arch::CompatEntry & rhs )
347 { return ! ( lhs == rhs ); }
348
350} // namespace zypp
352
353 ZYPP_DEFINE_ID_HASHABLE( zypp::Arch::CompatEntry );
354
356namespace zypp
357{
358
359 // Builtin architecture STRING VALUES to be
360 // used in defCompatibleWith below!
361 //
362 // const IdString _foo( "foo" );
363 // const Arch Arch_foo( _foo() );
364 //
365 // NOTE: Builtin CLASS Arch CONSTANTS are defined below.
366 // You have to change them accordingly in Arch.h.
367 //
368 // NOTE: Thake care CompatBits::IntT is able to provide one
369 // bit for each architecture.
370 //
371 #define DEF_BUILTIN(A) \
372 namespace { static inline const IdString & a_##A () { static IdString _str(#A); return _str; } } \
373 const Arch Arch_##A( a_##A() )
374
375 DEF_BUILTIN( noarch );
376
377 DEF_BUILTIN( i386 );
378 DEF_BUILTIN( i486 );
379 DEF_BUILTIN( i586 );
380 DEF_BUILTIN( i686 );
381 DEF_BUILTIN( athlon );
382 DEF_BUILTIN( x86_64 );
383 DEF_BUILTIN( x86_64_v2 );
384 DEF_BUILTIN( x86_64_v3 );
385 DEF_BUILTIN( x86_64_v4 );
386
387 DEF_BUILTIN( pentium3 );
388 DEF_BUILTIN( pentium4 );
389
390 DEF_BUILTIN( s390 );
391 DEF_BUILTIN( s390x );
392
393 DEF_BUILTIN( ppc );
394 DEF_BUILTIN( ppc64 );
395 DEF_BUILTIN( ppc64p7 );
396
397 DEF_BUILTIN( ppc64le );
398
399 DEF_BUILTIN( ia64 );
400
401 DEF_BUILTIN( alphaev67 );
402 DEF_BUILTIN( alphaev6 );
403 DEF_BUILTIN( alphapca56 );
404 DEF_BUILTIN( alphaev56 );
405 DEF_BUILTIN( alphaev5 );
406 DEF_BUILTIN( alpha );
407
408 DEF_BUILTIN( sparc64v );
409 DEF_BUILTIN( sparcv9v );
410 DEF_BUILTIN( sparc64 );
411 DEF_BUILTIN( sparcv9 );
412 DEF_BUILTIN( sparcv8 );
413 DEF_BUILTIN( sparc );
414
415 DEF_BUILTIN( aarch64 );
416
417 DEF_BUILTIN( armv7tnhl ); /* exists? */
418 DEF_BUILTIN( armv7thl ); /* exists? */
419
420 DEF_BUILTIN( armv7hnl ); /* legacy: */DEF_BUILTIN( armv7nhl );
421 DEF_BUILTIN( armv8hl );
422 DEF_BUILTIN( armv7hl );
423 DEF_BUILTIN( armv6hl );
424
425 DEF_BUILTIN( armv8l );
426 DEF_BUILTIN( armv7l );
427 DEF_BUILTIN( armv6l );
428 DEF_BUILTIN( armv5tejl );
429 DEF_BUILTIN( armv5tel );
430 DEF_BUILTIN( armv5tl );
431 DEF_BUILTIN( armv5l );
432 DEF_BUILTIN( armv4tl );
433 DEF_BUILTIN( armv4l );
434 DEF_BUILTIN( armv3l );
435
436 DEF_BUILTIN( riscv64 );
437
438 DEF_BUILTIN( sh3 );
439
440 DEF_BUILTIN( sh4 );
441 DEF_BUILTIN( sh4a );
442
443 DEF_BUILTIN( m68k );
444
445 DEF_BUILTIN( mips );
446 DEF_BUILTIN( mipsel );
447 DEF_BUILTIN( mips64 );
448 DEF_BUILTIN( mips64el );
449
450 DEF_BUILTIN( loong64 );
451#undef DEF_BUILTIN
452
454 namespace
455 {
456
458 //
459 // CLASS NAME : CompatSet
460 //
468 struct ArchCompatSet : private base::NonCopyable
469 {
470 using CompatEntry = Arch::CompatEntry;
471 using CompatBits = CompatEntry::CompatBits;
472
473 using Set = std::unordered_set<CompatEntry>;
474 using iterator = Set::iterator;
475 using const_iterator = Set::const_iterator;
476
478 static ArchCompatSet & instance()
479 {
480 static ArchCompatSet _instance;
481 return _instance;
482 }
483
487 const Arch::CompatEntry & assertDef( const std::string & archStr_r )
488 { return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; }
490 const Arch::CompatEntry & assertDef( IdString archStr_r )
491 { return *_compatSet.insert( Arch::CompatEntry( archStr_r ) ).first; }
492
493 const_iterator begin() const
494 { return _compatSet.begin(); }
495
496 const_iterator end() const
497 { return _compatSet.end(); }
498
499 struct DumpOnCompare
500 {
501 int operator()( const CompatEntry & lhs, const CompatEntry & rhs ) const
502 { return lhs._idBit.value() < rhs._idBit.value(); }
503 };
504
505 std::ostream & dumpOn( std::ostream & str ) const
506 {
507 str << "ArchCompatSet:";
508 std::list<CompatEntry> ov( _compatSet.begin(), _compatSet.end() );
509 ov.sort( DumpOnCompare() );
510 for_( it, ov.begin(), ov.end() )
511 {
512 str << endl << ' ' << *it;
513 }
514 return str;
515 }
516
517 private:
519 ArchCompatSet()
520 {
521 // _noarch must have _idBit 0.
522 // Other builtins have 1-bit set
523 // and are initialized done on the fly.
524 _compatSet.insert( Arch::CompatEntry( a_noarch(), 0 ) );
526 // Define the CompatibleWith relation:
527 //
528 // NOTE: Order of definition is significant! (Arch::compare)
529 // - define compatible (less) architectures first!
530 //
531 defCompatibleWith( a_i386(), a_noarch() );
532 defCompatibleWith( a_i486(), a_noarch(),a_i386() );
533 defCompatibleWith( a_i586(), a_noarch(),a_i386(),a_i486() );
534 defCompatibleWith( a_i686(), a_noarch(),a_i386(),a_i486(),a_i586() );
535 defCompatibleWith( a_athlon(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686() );
536 defCompatibleWith( a_x86_64(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686(),a_athlon() );
537 defCompatibleWith( a_x86_64_v2(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686(),a_athlon(),a_x86_64() );
538 defCompatibleWith( a_x86_64_v3(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686(),a_athlon(),a_x86_64(),a_x86_64_v2() );
539 defCompatibleWith( a_x86_64_v4(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686(),a_athlon(),a_x86_64(),a_x86_64_v2(),a_x86_64_v3() );
540
541 defCompatibleWith( a_pentium3(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686() );
542 defCompatibleWith( a_pentium4(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686(),a_pentium3() );
543
544 defCompatibleWith( a_ia64(), a_noarch(),a_i386(),a_i486(),a_i586(),a_i686() );
545 //
546 defCompatibleWith( a_s390(), a_noarch() );
547 defCompatibleWith( a_s390x(), a_noarch(),a_s390() );
548 //
549 defCompatibleWith( a_ppc(), a_noarch() );
550 defCompatibleWith( a_ppc64(), a_noarch(),a_ppc() );
551 defCompatibleWith( a_ppc64p7(), a_noarch(),a_ppc(),a_ppc64() );
552 //
553 defCompatibleWith( a_ppc64le(), a_noarch() );
554 //
555 defCompatibleWith( a_alpha(), a_noarch() );
556 defCompatibleWith( a_alphaev5(), a_noarch(),a_alpha() );
557 defCompatibleWith( a_alphaev56(), a_noarch(),a_alpha(),a_alphaev5() );
558 defCompatibleWith( a_alphapca56(), a_noarch(),a_alpha(),a_alphaev5(),a_alphaev56() );
559 defCompatibleWith( a_alphaev6(), a_noarch(),a_alpha(),a_alphaev5(),a_alphaev56(),a_alphapca56() );
560 defCompatibleWith( a_alphaev67(), a_noarch(),a_alpha(),a_alphaev5(),a_alphaev56(),a_alphapca56(),a_alphaev6() );
561 //
562 defCompatibleWith( a_sparc(), a_noarch() );
563 defCompatibleWith( a_sparcv8(), a_noarch(),a_sparc() );
564 defCompatibleWith( a_sparcv9(), a_noarch(),a_sparc(),a_sparcv8() );
565 defCompatibleWith( a_sparcv9v(), a_noarch(),a_sparc(),a_sparcv8(),a_sparcv9() );
566 //
567 defCompatibleWith( a_sparc64(), a_noarch(),a_sparc(),a_sparcv8(),a_sparcv9() );
568 defCompatibleWith( a_sparc64v(), a_noarch(),a_sparc(),a_sparcv8(),a_sparcv9(),a_sparcv9v(),a_sparc64() );
569 //
570 defCompatibleWith( a_armv3l(), a_noarch() );
571 defCompatibleWith( a_armv4l(), a_noarch(),a_armv3l() );
572 defCompatibleWith( a_armv4tl(), a_noarch(),a_armv3l(),a_armv4l() );
573 defCompatibleWith( a_armv5l(), a_noarch(),a_armv3l(),a_armv4l(),a_armv4tl() );
574 defCompatibleWith( a_armv5tl(), a_noarch(),a_armv3l(),a_armv4l(),a_armv4tl(),a_armv5l() );
575 defCompatibleWith( a_armv5tel(), a_noarch(),a_armv3l(),a_armv4l(),a_armv4tl(),a_armv5l(),a_armv5tl() );
576 defCompatibleWith( a_armv5tejl(), a_noarch(),a_armv3l(),a_armv4l(),a_armv4tl(),a_armv5l(),a_armv5tl(),a_armv5tel() );
577 defCompatibleWith( a_armv6l(), a_noarch(),a_armv3l(),a_armv4l(),a_armv4tl(),a_armv5l(),a_armv5tl(),a_armv5tel(),a_armv5tejl() );
578 defCompatibleWith( a_armv7l(), a_noarch(),a_armv3l(),a_armv4l(),a_armv4tl(),a_armv5l(),a_armv5tl(),a_armv5tel(),a_armv5tejl(),a_armv6l() );
579 defCompatibleWith( a_armv8l(), a_noarch(),a_armv3l(),a_armv4l(),a_armv4tl(),a_armv5l(),a_armv5tl(),a_armv5tel(),a_armv5tejl(),a_armv6l(),a_armv7l() );
580
581 defCompatibleWith( a_armv6hl(), a_noarch() );
582 defCompatibleWith( a_armv7hl(), a_noarch(),a_armv6hl() );
583 defCompatibleWith( a_armv8hl(), a_noarch(),a_armv7hl() );
584 defCompatibleWith( a_armv7hnl(), a_noarch(),a_armv7hl(),a_armv6hl() );
585 /*legacy: rpm uses v7hnl */
586 defCompatibleWith( a_armv7nhl(), a_noarch(),a_armv7hnl(),a_armv7hl(),a_armv6hl() );
587
588 /*?*/defCompatibleWith( a_armv7thl(), a_noarch(),a_armv7hl() );
589 /*?*/defCompatibleWith( a_armv7tnhl(), a_noarch(),a_armv7hl(),a_armv7nhl(),a_armv7thl() );
590
591 defCompatibleWith( a_aarch64(), a_noarch() );
592 //
593 defCompatibleWith( a_riscv64(), a_noarch() );
594 //
595 defCompatibleWith( a_sh3(), a_noarch() );
596 //
597 defCompatibleWith( a_sh4(), a_noarch() );
598 defCompatibleWith( a_sh4a(), a_noarch(),a_sh4() );
599
600 defCompatibleWith( a_m68k(), a_noarch() );
601
602 defCompatibleWith( a_mips(), a_noarch() );
603 defCompatibleWith( a_mipsel(), a_noarch() );
604 defCompatibleWith( a_mips64(), a_noarch() );
605 defCompatibleWith( a_mips64el(), a_noarch() );
606
607 defCompatibleWith( a_loong64(), a_noarch() );
608 //
610 // dumpOn( USR ) << endl;
611 }
612
613 private:
619 CompatBits::IntT nextIdBit() const
620 {
621 if ( CompatBits::size == _compatSet.size() )
622 {
623 // Provide more bits in CompatBits::IntT
624 INT << "Need more than " << CompatBits::size << " bits to encode architectures." << endl;
625 ZYPP_THROW( Exception("Need more bits to encode architectures.") );
626 }
627 CompatBits::IntT nextBit = CompatBits::IntT(1) << (_compatSet.size());
628 return nextBit;
629 }
630
634 const CompatEntry & assertCompatSetEntry( IdString archStr_r )
635 { return *_compatSet.insert( Arch::CompatEntry( archStr_r, nextIdBit() ) ).first; }
636
639 void defCompatibleWith( IdString targetArch_r,
640 IdString arch0_r,
641 IdString arch1_r = IdString(),
642 IdString arch2_r = IdString(),
643 IdString arch3_r = IdString(),
644 IdString arch4_r = IdString(),
645 IdString arch5_r = IdString(),
646 IdString arch6_r = IdString(),
647 IdString arch7_r = IdString(),
648 IdString arch8_r = IdString(),
649 IdString arch9_r = IdString() )
650 {
651 const CompatEntry & target( assertCompatSetEntry( targetArch_r ) );
652 target.addCompatBit( assertCompatSetEntry( arch0_r )._idBit );
653#define SETARG(N) if ( arch##N##_r.empty() ) return; target.addCompatBit( assertCompatSetEntry( arch##N##_r )._idBit )
654 SETARG(1); SETARG(2); SETARG(3); SETARG(4);
655 SETARG(5); SETARG(6); SETARG(7); SETARG(8); SETARG(9);
656#undef SETARG
657 }
658
659 private:
660 Set _compatSet;
661 };
662
664 } // namespace
666
668 //
669 // CLASS NAME : Arch
670 //
672
673 const Arch Arch_empty ( IdString::Empty );
674 // remaining Arch_* constants are defined by DEF_BUILTIN above.
675
677 //
678 // METHOD NAME : Arch::Arch
679 // METHOD TYPE : Ctor
680 //
681 Arch::Arch()
682 : _entry( &ArchCompatSet::instance().assertDef( a_noarch() ) )
683 {}
684
685 Arch::Arch( IdString::IdType id_r )
686 : _entry( &ArchCompatSet::instance().assertDef( IdString(id_r) ) )
687 {}
688
689 Arch::Arch( const IdString & idstr_r )
690 : _entry( &ArchCompatSet::instance().assertDef( idstr_r ) )
691 {}
692
693 Arch::Arch( const std::string & str_r )
694 : _entry( &ArchCompatSet::instance().assertDef( str_r ) )
695 {}
696
697 Arch::Arch( const char * cstr_r )
698 : _entry( &ArchCompatSet::instance().assertDef( cstr_r ) )
699 {}
700
701 Arch Arch::detectSystemArchitecture()
702 {
703 static Arch _val( _autoDetectSystemArchitecture() );
704 return _val;
705 }
706
707 Arch::Arch( const CompatEntry & rhs )
708 : _entry( &rhs )
709 {}
710
712 //
713 // METHOD NAME : Arch::idStr
714 // METHOD TYPE : IdString
715 //
716 IdString Arch::idStr() const
717 { return _entry->_idStr; }
718
720 //
721 // METHOD NAME : Arch::asString
722 // METHOD TYPE : const std::string &
723 //
724 const std::string & Arch::asString() const
725 { return _entry->_archStr; }
726
728 //
729 // METHOD NAME : Arch::isBuiltIn
730 // METHOD TYPE : bool
731 //
732 bool Arch::isBuiltIn() const
733 { return _entry->isBuiltIn(); }
734
736 //
737 // METHOD NAME : Arch::compatibleWith
738 // METHOD TYPE : bool
739 //
740 bool Arch::compatibleWith( const Arch & targetArch_r ) const
741 { return _entry->compatibleWith( *targetArch_r._entry ); }
742
744 //
745 // METHOD NAME : Arch::baseArch
746 // METHOD TYPE : Arch
747 //
748 Arch Arch::baseArch( ) const
749 {
750 // check the multilib archs:
751 if (Arch_x86_64.compatibleWith(*this))
752 {
753 return Arch_x86_64;
754 }
755 if (Arch_sparc64v.compatibleWith(*this))
756 {
757 return Arch_sparc64v;
758 }
759 if (Arch_sparc64.compatibleWith(*this))
760 {
761 return Arch_sparc64;
762 }
763 if (Arch_ppc64.compatibleWith(*this))
764 {
765 return Arch_ppc64;
766 }
767 if (Arch_s390x.compatibleWith(*this))
768 {
769 return Arch_s390x;
770 }
771 // Here: no multilib; return arch before noarch
772 CompatSet cset( compatSet( *this ) );
773 if ( cset.size() > 2 ) // systemArchitecture, ..., basearch, noarch
774 {
775 return *(++cset.rbegin());
776 }
777 return *this;
778 }
779
781 //
782 // METHOD NAME : Arch::compare
783 // METHOD TYPE : bool
784 //
785 int Arch::compare( const Arch & rhs ) const
786 { return _entry->compare( *rhs._entry ); }
787
789 //
790 // METHOD NAME : Arch::compatSet
791 // METHOD TYPE : Arch::CompatSet
792 //
793 Arch::CompatSet Arch::compatSet( const Arch & targetArch_r )
794 {
795 Arch::CompatSet ret;
796
797 for ( ArchCompatSet::const_iterator it = ArchCompatSet::instance().begin();
798 it != ArchCompatSet::instance().end(); ++it )
799 {
800 if ( it->compatibleWith( *targetArch_r._entry ) )
801 {
802 ret.insert( Arch(*it) );
803 }
804 }
805
806 return ret;
807 }
808
810} // namespace zypp
SETARG
#define SETARG(N)
DEF_BUILTIN
#define DEF_BUILTIN(A)
Definition Arch.cc:371
Arch.h
Bit.h
for_
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition Easy.h:27
Exception.h
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
Hash.h
ZYPP_DEFINE_ID_HASHABLE
#define ZYPP_DEFINE_ID_HASHABLE(C)
Define hash function for id based classes.
Definition Hash.h:26
IOStream.h
Logger.h
MIL
#define MIL
Definition Logger.h:103
ERR
#define ERR
Definition Logger.h:105
WAR
#define WAR
Definition Logger.h:104
INT
#define INT
Definition Logger.h:107
NonCopyable.h
bool
zypp::Arch
Architecture.
Definition Arch.h:37
zypp::Arch::_entry
const CompatEntry * _entry
Definition Arch.h:153
zypp::Arch::baseArch
Arch baseArch() const
Definition Arch.cc:748
zypp::Arch::compare
int compare(const Arch &rhs) const
Arch comparison.
Definition Arch.cc:785
zypp::Arch::Arch
Arch()
Default ctor Arc_noarch.
Definition Arch.cc:681
zypp::Arch::compatSet
static CompatSet compatSet(const Arch &targetArch_r)
Return a set of all Arch's compatibleWith a targetArch_r.
Definition Arch.cc:793
zypp::Arch::isBuiltIn
bool isBuiltIn() const
Whether this is a buitin (or known) architecture.
Definition Arch.cc:732
zypp::Arch::idStr
IdString idStr() const
String representation of Arch.
Definition Arch.cc:716
zypp::Arch::asString
const std::string & asString() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition Arch.cc:724
zypp::Arch::CompatSet
std::set< Arch, CompareByGT< Arch > > CompatSet
Reversed arch order, best Arch first.
Definition Arch.h:122
zypp::Arch::detectSystemArchitecture
static Arch detectSystemArchitecture()
Determine system architecture evaluating uname and /proc/cpuinfo.
Definition Arch.cc:701
zypp::Arch::compatibleWith
bool compatibleWith(const Arch &targetArch_r) const
Compatibility relation.
Definition Arch.cc:740
zypp::IdString
Access to the sat-pools string space.
Definition IdString.h:55
zypp::IdString::IdType
sat::detail::IdType IdType
Definition IdString.h:57
zypp::IdString::Empty
static const IdString Empty
Empty string.
Definition IdString.h:89
zypp::bit::BitField
An integral type used as BitField.
Definition Bit.h:160
zypp::bit::BitField::value
TInt value() const
Return the value.
Definition Bit.h:179
zypp::filesystem::PathInfo
Wrapper class for stat/lstat.
Definition PathInfo.h:226
zypp::iostr::EachLine
Simple lineparser: Traverse each line in a file.
Definition IOStream.h:113
zypp::iostr::EachLine::next
bool next()
Advance to next line.
Definition IOStream.cc:72
str
String related utilities and Regular expression matching.
zypp::base::NonCopyable
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition NonCopyable.h:26
zypp::bit
Definition Bit.h:29
zypp::str::numstring
std::string numstring(char n, int w=0)
Definition String.h:290
zypp::str::hasPrefix
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
Definition String.h:1097
zypp::str::form
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition String.cc:39
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition CodePitfalls.doc:2
zypp::operator!=
bool operator!=(const Capability &lhs, const Capability &rhs)
relates: Capability
Definition Capability.h:313
zypp::operator==
bool operator==(const Capability &lhs, const Capability &rhs)
relates: Capability
Definition Capability.h:309
zypp::Arch_empty
const Arch Arch_empty(IdString::Empty)
zypp::dumpOn
std::ostream & dumpOn(std::ostream &str, const Capability &obj)
relates: Capability Detailed stream output
Definition Capability.cc:589
zypp::operator<<
std::ostream & operator<<(std::ostream &str, const Capabilities &obj)
relates: Capabilities Stream output
Definition Capabilities.cc:65
zyppng::IdString
zypp::IdString IdString
Definition idstring.h:16
zypp::Arch::CompatEntry
Holds an architecture ID and its compatible relation.
Definition Arch.cc:258
zypp::Arch::CompatEntry::addCompatBit
void addCompatBit(const CompatBits &idBit_r) const
Definition Arch.cc:281
zypp::Arch::CompatEntry::compatibleWith
bool compatibleWith(const CompatEntry &targetEntry_r) const
Return whether this is compatible with targetEntry_r.
Definition Arch.cc:290
zypp::Arch::CompatEntry::compare
int compare(const CompatEntry &rhs) const
compare by score, then archStr.
Definition Arch.cc:308
zypp::Arch::CompatEntry::id
IdString::IdType id() const
Definition Arch.cc:318
zypp::Arch::CompatEntry::_idBit
CompatBits _idBit
Definition Arch.cc:323
zypp::Arch::CompatEntry::_archStr
std::string _archStr
Definition Arch.cc:322
zypp::Arch::CompatEntry::isBuiltIn
bool isBuiltIn() const
Definition Arch.cc:315
zypp::Arch::CompatEntry::CompatBits
bit::BitField< uint64_t > CompatBits
Bitfield for architecture IDs and compatBits relation.
Definition Arch.cc:263
zypp::Arch::CompatEntry::CompatEntry
CompatEntry(IdString archStr_r, CompatBits::IntT idBit_r=1)
Definition Arch.cc:273
zypp::Arch::CompatEntry::_compatBits
CompatBits _compatBits
Definition Arch.cc:324
zypp::Arch::CompatEntry::_idStr
IdString _idStr
Definition Arch.cc:321
zypp::Arch::CompatEntry::CompatEntry
CompatEntry(const std::string &archStr_r, CompatBits::IntT idBit_r=1)
Definition Arch.cc:265
zypp::bit::Range::size
static const unsigned size
Definition Bit.h:88
zypp::bit::Range::IntT
TInt IntT
Definition Bit.h:83
PathInfo.h