patches to improve cross compilation - please review

Compilation and installation of DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
frosteyes
Posts: 2
Joined: Mon, 2021-10-04, 16:28

patches to improve cross compilation - please review

#1 Post by frosteyes » Mon, 2021-10-11, 10:33

I will like to propose 2 patches for improving the cross compilation capability of dcmtk.
First I will just share the link to the patches on github, and next add the background info the patches.

The patches is located here
https://github.com/frosteyes/dcmtk/tree ... le-options

Background
Part of the dcmtk cmake configuration is 5 places of DCMTK_TRY_RUN in CMake/GenerateDCMTKConfigure.cmake.
DCMTK_TRY_RUN ends up calling the the cmake try_run. In practice this means that the cmake configuration before compilation needs to compile some code, run the code and use the output to set some cmake variables. This is only possible if the target where you want to compile the code for is available for running this test code.
In many situation this requirement is not feasible to respect. A common example would be compilation on a development workstation for running on a dedicated medical device. The device could be based on another architecture like ARM64. The other way around is also possible - e.g. developing on a Apple M1, but compilation for x86_64.

You can see the issue if you try to compile the dcmtk like this. Notice setting CMAKE_SYSTEM_NAME sets the CMAKE_CROSSCOMPILING.
mkdir build && cd build && cmake -DCMAKE_SYSTEM_NAME:STRING=Linux ..

It shows the issues for each DCMTK_TRY_RUN.
-- Checking signedness of char
CMake Warning at CMake/dcmtkTryRun.cmake:78 (message):
Emulation for your target platform is not available, please fill in the
required configure test results manually.
Call Stack (most recent call first):
CMake/dcmtkTryRun.cmake:89 (DCMTK_TRY_RUN_CROSS)
CMake/GenerateDCMTKConfigure.cmake:765 (DCMTK_TRY_RUN)
CMake/dcmtkPrepare.cmake:558 (include)
CMakeLists.txt:52 (include)


CMake Error: TRY_RUN() invoked in cross-compiling mode, please set the following cache variables appropriately:
C_CHAR_SIGNED (advanced)
For details see /home/x/Git/Github/frosteyes/dcmtk/build/TryRunResults.cmake
Solution
The solution in the proposed patches is to introduce a boolean variable DCMTK_NO_TRY_RUN:BOOL.
Setting it to true or 1 prevent the DCMTK_TRY_RUN from running and instead asking the user to set the result from running the try_run directly.
This means that the user will set a number of variables already present in the CMAKE system manually instead of relying on the compilation and running of a test program for determining the results.
Default is to be exactly like dcmtk currently is - so adding the patches does not change anything for the default.

The minimum setup for compilation when CMAKE_SYSTEM_NAME is set with the proposed patches is to set the following variables. Notice we only set the results for the 3 cases of TRY_RUN here.
The number 4 TRY_RUN is part of generating an arith.h file. This currently need to be provided of the user after cmake. (Further info about arith.h later).
You can typically get the values for those variables by running the cmake systems once on a equivalent hardware as the final target.

Code: Select all

cmake -DCMAKE_SYSTEM_NAME:STRING=Linux \
-DDCMTK_NO_TRY_RUN:BOOL=1 \
-DC_CHAR_UNSIGNED:BOOL=0 \
-DDCMTK_ICONV_FLAGS_ANALYZED:BOOL=TRUE \
-DDCMTK_FIXED_ICONV_CONVERSION_FLAGS:STRING=AbortTranscodingOnIllegalSequence \
-DDCMTK_STDLIBC_ICONV_HAS_DEFAULT_ENCODING:BOOL=TRUE \
..
The last (5 TRY_RUN) is handled by the second patch, and is if you enable STL. So here the setup is if you enable STL you also need to handle all the STL testing result.

Code: Select all

-DDCMTK_ENABLE_STL:BOOL=ON \
-DHAVE_STL_VECTOR_TEST_RESULT:BOOL=OFF \
-DHAVE_STL_ALGORITHM_TEST_RESULT:BOOL=OFF \
-DHAVE_STL_LIMITS_TEST_RESULT:BOOL=OFF \
-DHAVE_STL_LIST_TEST_RESULT:BOOL=OFF \
-DHAVE_STL_MAP_TEST_RESULT:BOOL=OFF \
-DHAVE_STL_MEMORY_TEST_RESULT:BOOL=OFF \
-DHAVE_STL_STACK_TEST_RESULT:BOOL=OFF \
-DHAVE_STL_STRING_TEST_RESULT:BOOL=OFF \
-DHAVE_STL_TYPE_TRAITS_TEST_RESULT:BOOL=OFF \
-DHAVE_STL_TUPLE_TEST_RESULT:BOOL=OFF \
-DHAVE_STL_SYSTEM_ERROR_TEST_RESULT:BOOL=OFF \
arith.h
Currently the output from using DCMTK_NO_TRY_RUN regarding arith.h is the following status message.
Be sure to copy arith.h to /home/frosteyes/Golf/FrostEyes/Git/Github/frosteyes/dcmtk/build/config/include/dcmtk/config/arith.h before build
CMake Warning at CMakeLists.txt:78 (message):
Emulation for your target platform is not available, CTest will not be able
to execute the unit tests!
I am working on a patch to provide a default arith.h for some specific platforms, and introduce some new variables for specifying this.
Something like the variable names below. Here the idea is that if DCMTK_NO_TRY_RUN is set, the cmake system do a fatal error if not one of those is specified.
It would still be possible to have a custom setup for a custom platform, but dcmtk would also provide a default for the common platforms (x86_64 and ARM64)
  • DCMTK_ARITH_H_GCC_X86_64
  • DCMTK_ARITH_H_ARM64
  • DCMTK_ARITH_H_CUSTOM
Will try to follow up with an Yocto example when I have time. So for now - please comment on the patches, and the idea about providing some "standard" arith.h" for some common platforms.

frosteyes
Posts: 2
Joined: Mon, 2021-10-04, 16:28

Re: patches to improve cross compilation - please review

#2 Post by frosteyes » Thu, 2021-10-28, 08:46

Have created a yocto example located here. https://github.com/frosteyes/yocto-dcmtk

You can read the primary README.md for a guide how to compile the qemuarm64 and qemux86-64 images.

The most important part seen from dcmtk perspective is the yocto recipe for building dcmtk.
https://github.com/frosteyes/yocto-dcmt ... mtk_git.bb
Regarding the flags, beside the needed for cross compilation, they are just example for how I intended to use it.
You are welcome to clone and change to your need.

Have run the test tools successfully on the 2 machines (qemuarm64 and qemux86-64) but you are welcome to do more testing to see if something is missing.

Regarding the idea about having some pre-generated generics arith.h files, it might not be so easy.

The CPU info from qemu x86-64 seems to be based on a old core 2 duo

Code: Select all

...
vendor_id	: GenuineIntel
cpu family	: 6
model		: 15
model name	: Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz
stepping	: 11
cpu MHz		: 2708.822
cache size	: 16384 KB
physical id	: 0
siblings	: 1
core id		: 0
cpu cores	: 1
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 10
wp		: yes
flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush acpi mmx fxsr sse sse2 syscall nx lm constant_tsc rep_good nopl cpuid pni monitor ssse3 cx16 hypervisor lahf_lm pti
bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit
bogomips	: 5417.64
clflush size	: 64
cache_alignment	: 64
address sizes	: 40 bits physical, 48 bits virtual
power management:
This result in a arith.h like the one added in my yocto example. https://github.com/frosteyes/yocto-dcmt ... mux86-64.h

Comparing this arith.h to one generated for a more modern x86-64 like a Intel(R) Core(TM) i7-10850H CPU @ 2.70GHz, shows the difference show below.

Code: Select all

42c42
< #define DCMTK_FLOAT_HAS_SIGNALING_NAN OFFalse
---
> #define DCMTK_FLOAT_HAS_SIGNALING_NAN OFTrue
44c44
< #define DCMTK_DOUBLE_HAS_SIGNALING_NAN OFFalse
---
> #define DCMTK_DOUBLE_HAS_SIGNALING_NAN OFTrue
46,47c46,47
< #define DCMTK_FLOAT_IS_IEC559 OFFalse
< #define DCMTK_DOUBLE_IS_IEC559 OFFalse
---
> #define DCMTK_FLOAT_IS_IEC559 OFTrue
> #define DCMTK_DOUBLE_IS_IEC559 OFTrue
52,55c52,55
< #define DCMTK_FLOAT_TINYNESS_BEFORE OFFalse
< #define DCMTK_DOUBLE_TINYNESS_BEFORE OFFalse
< #define DCMTK_FLOAT_HAS_DENORM_LOSS OFFalse
< #define DCMTK_DOUBLE_HAS_DENORM_LOSS OFFalse
---
> #define DCMTK_FLOAT_TINYNESS_BEFORE OFTrue
> #define DCMTK_DOUBLE_TINYNESS_BEFORE OFTrue
> #define DCMTK_FLOAT_HAS_DENORM_LOSS OFTrue
> #define DCMTK_DOUBLE_HAS_DENORM_LOSS OFTrue
So not knowing how many x86-64 is needed, I selected just to keep the current solution for now - as it makes it possible to place the needed arith.h together with other BSP (board support) specific parts for the image, and I would rather have a compile error because the machine / architecture does not provide an arith.h then I try to guess and maybe create a subtle error runtime.

Just for reference - the cpu info for the newer CPU.

Code: Select all

...
vendor_id	: GenuineIntel
cpu family	: 6
model		: 165
model name	: Intel(R) Core(TM) i7-10850H CPU @ 2.70GHz
stepping	: 2
microcode	: 0xea
cpu MHz		: 2700.000
cache size	: 12288 KB
physical id	: 0
siblings	: 12
core id		: 5
cpu cores	: 6
apicid		: 11
initial apicid	: 11
fpu		: yes
fpu_exception	: yes
cpuid level	: 22
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust sgx bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp pku ospke sgx_lc md_clear flush_l1d arch_capabilities
vmx flags	: vnmi preemption_timer posted_intr invvpid ept_x_only ept_ad ept_1gb flexpriority apicv tsc_offset vtpr mtf vapic ept vpid unrestricted_guest vapic_reg vid ple shadow_vmcs pml ept_mode_based_exec
bugs		: spectre_v1 spectre_v2 spec_store_bypass swapgs itlb_multihit
bogomips	: 5399.81
clflush size	: 64
cache_alignment	: 64
address sizes	: 39 bits physical, 48 bits virtual
power management:

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest