Hello team,
I have made changes to the jt9.exe code to allow it decode MSK144. This does not affect the existing functions of WSJT-X, so it
is a low risk change, and I would like it to be merged to the main branch. The modified files are attached. Do I need to do
anything else to make my submission accepted?
73 Alex VE3NEA
subroutine decode_msk144(audio_samples, params, data_dir)
include 'jt9com.f90'
! constants
integer, parameter :: SAMPLING_RATE = 12000
integer, parameter :: BLOCK_SIZE = 7168
integer, parameter :: STEP_SIZE = BLOCK_SIZE / 2
integer, parameter :: CALL_LENGTH = 12
! aguments
integer*2 audio_samples(NMAX)
type(params_block) :: params
character(len = 500) :: data_dir
! parameters of mskrtd
integer*2 :: buffer(BLOCK_SIZE)
real :: tsec
logical :: bshmsg = .false. ! enables shorthand messages
logical :: btrain = .false. ! turns on training in MSK144 mode
real*8 :: pcoeffs(5) = (/ 0.0, 0.0, 0.0, 0.0, 0.0 /); ! phase equalization
logical :: bswl = .false.
character(len = 80) :: line
character(len = CALL_LENGTH) :: mycall
character(len = CALL_LENGTH) :: hiscall
! local variables
integer :: sample_count
integer :: position
integer :: message_count = 0
! decode in 0.3s blocks
sample_count = params%ntr * SAMPLING_RATE
mycall = transfer(params%mycall, mycall) ! string to char[]
hiscall = transfer(params%hiscall, hiscall)
do position = 1, sample_count - BLOCK_SIZE + 1, STEP_SIZE
buffer = audio_samples(position : position + BLOCK_SIZE - 1)
tsec = position / REAL(SAMPLING_RATE)
call mskrtd(buffer, params%nutc, tsec, params%ntol, params%nfqso,
params%ndepth, &
mycall, hiscall, bshmsg, btrain, pcoeffs, bswl, data_dir, line)
if (line(1:1) .ne. char(0)) then
line = line(1:index(line, char(0))-1)
write(*, 1001) line
1001 format(a80)
message_count = message_count + 1;
end if
end do
if (.not. params%ndiskdat) then
write(*, 1002) 0, message_count, 0
1002 format('<DecodeFinished>', 2i4, i9)
end if
end subroutine decode_msk144
program jt9
! Decoder for JT9. Can run stand-alone, reading data from *.wav files;
! or as the back end of wsjt-x, with data placed in a shared memory region.
use options
use prog_args
use, intrinsic :: iso_c_binding
use FFTW3
use timer_module, only: timer
use timer_impl, only: init_timer, fini_timer
use readwav
include 'jt9com.f90'
integer*2 id2a(180000)
integer(C_INT) iret
type(wav_header) wav
real*4 s(NSMAX)
real*8 TRperiod
character c
character(len=500) optarg, infile
character wisfile*256
!### ndepth was defined as 60001. Why???
integer :: arglen,stat,offset,remain,mode=0,flow=200,fsplit=2700, &
fhigh=4000,nrxfreq=1500,ndepth=1,nexp_decode=0,nQSOProg=0
logical :: read_files = .true., tx9 = .false., display_help = .false., &
bLowSidelobes = .false., nexp_decode_set = .false., &
have_ntol = .false.
type (option) :: long_options(33) = [ &
option ('help', .false., 'h', 'Display this help message', ''), &
option ('shmem',.true.,'s','Use shared memory for sample data','KEY'), &
option ('tr-period', .true., 'p', 'Tx/Rx period, default SECONDS=60', &
'SECONDS'), &
option ('executable-path', .true., 'e', &
'Location of subordinate executables (KVASD) default PATH="."', &
'PATH'), &
option ('data-path', .true., 'a', &
'Location of writeable data files, default PATH="."', 'PATH'), &
option ('temp-path', .true., 't', &
'Temporary files path, default PATH="."', 'PATH'), &
option ('lowest', .true., 'L', &
'Lowest frequency decoded (JT65), default HERTZ=200', 'HERTZ'), &
option ('highest', .true., 'H', &
'Highest frequency decoded, default HERTZ=4007', 'HERTZ'), &
option ('split', .true., 'S', &
'Lowest JT9 frequency decoded, default HERTZ=2700', 'HERTZ'), &
option ('rx-frequency', .true., 'f', &
'Receive frequency offset, default HERTZ=1500', 'HERTZ'), &
option ('freq-tolerance', .true., 'F', &
'Receive frequency tolerance, default HERTZ=20', 'HERTZ'), &
option ('patience', .true., 'w', &
'FFTW3 planing patience (0-4), default PATIENCE=1', 'PATIENCE'), &
option ('fft-threads', .true., 'm', &
'Number of threads to process large FFTs, default THREADS=1', &
'THREADS'), &
option ('q65', .false., '3', 'Q65 mode', ''), &
option ('jt4', .false., '4', 'JT4 mode', ''), &
option ('ft4', .false., '5', 'FT4 mode', ''), &
option ('jt65', .false.,'6', 'JT65 mode', ''), &
option ('fst4', .false., '7', 'FST4 mode', ''), &
option ('fst4w', .false., 'W', 'FST4W mode', ''), &
option ('fst4w', .false., 'Y', 'FST4W mode, print hash22 values', ''), &
option ('ft8', .false., '8', 'FT8 mode', ''), &
option ('jt9', .false., '9', 'JT9 mode', ''), &
option ('qra64', .false., 'q', 'QRA64 mode', ''), &
option ('msk144', .false., 'k', 'MSK144 mode', ''), &
option ('QSOprog', .true., 'Q', 'QSO progress (0-5), default PROGRESS=1',&
'QSOprogress'), &
option ('sub-mode', .true., 'b', 'Sub mode, default SUBMODE=A', 'A'), &
option ('depth', .true., 'd', &
'Decoding depth (1-3), default DEPTH=1', 'DEPTH'), &
option ('tx-jt9', .false., 'T', 'Tx mode is JT9', ''), &
option ('my-call', .true., 'c', 'my callsign', 'CALL'), &
option ('my-grid', .true., 'G', 'my grid locator', 'GRID'), &
option ('his-call', .true., 'x', 'his callsign', 'CALL'), &
option ('his-grid', .true., 'g', 'his grid locator', 'GRID'), &
option ('experience-decode', .true., 'X', &
'experience based decoding flags (1..n), default FLAGS=0', &
'FLAGS') ]
type(dec_data), allocatable :: shared_data
character(len=20) :: datetime=''
character(len=12) :: mycall='K1ABC', hiscall='W9XYZ'
character(len=6) :: mygrid='', hisgrid='EN37'
common/patience/npatience,nthreads
common/decstats/ntry65a,ntry65b,n65a,n65b,num9,numfano
data npatience/1/,nthreads/1/,wisfile/' '/
nsubmode = 0
ntol = 20
TRperiod=60.d0
do
call getopt('hs:e:a:b:r:m:p:d:f:F:w:t:9876543WYqkTL:S:H:c:G:x:g:X:Q:',
&
long_options,c,optarg,arglen,stat,offset,remain,.true.)
if (stat .ne. 0) then
exit
end if
select case (c)
case ('h')
display_help = .true.
case ('s')
read_files = .false.
shm_key = optarg(:arglen)
case ('e')
exe_dir = optarg(:arglen)
case ('a')
data_dir = optarg(:arglen)
case ('b')
nsubmode = ichar (optarg(:1)) - ichar ('A')
case ('t')
temp_dir = optarg(:arglen)
case ('m')
read (optarg(:arglen), *) nthreads
case ('p')
read (optarg(:arglen), *) TRperiod
case ('d')
read (optarg(:arglen), *) ndepth
case ('f')
read (optarg(:arglen), *) nrxfreq
case ('F')
read (optarg(:arglen), *) ntol
have_ntol = .true.
case ('L')
read (optarg(:arglen), *) flow
case ('S')
read (optarg(:arglen), *) fsplit
case ('H')
read (optarg(:arglen), *) fhigh
case ('q')
mode = 164
case ('k')
mode = 144
case ('Q')
read (optarg(:arglen), *) nQSOProg
case ('3')
mode = 66
case ('4')
mode = 4
case ('5')
mode = 5
case ('6')
if (mode.lt.65) mode = mode + 65
case ('7')
mode = 240
case ('8')
mode = 8
case ('9')
if (mode.lt.9.or.mode.eq.65) mode = mode + 9
case ('T')
tx9 = .true.
case ('w')
read (optarg(:arglen), *) npatience
case ('W')
mode = 241
case ('Y')
mode = 242
case ('c')
read (optarg(:arglen), *) mycall
case ('G')
read (optarg(:arglen), *) mygrid
case ('x')
read (optarg(:arglen), *) hiscall
case ('g')
read (optarg(:arglen), *) hisgrid
case ('X')
read (optarg(:arglen), *) nexp_decode
nexp_decode_set = .true.
end select
end do
if (display_help .or. stat .lt. 0 &
.or. (.not. read_files .and. remain .gt. 0) &
.or. (read_files .and. remain .lt. 1)) then
print *, 'Usage: jt9 [OPTIONS] file1 [file2 ...]'
print *, ' Reads data from *.wav files.'
print *, ''
print *, ' jt9 -s <key> [-w patience] [-m threads] [-e path] [-a
path] [-t path]'
print *, ' Gets data from shared memory region with key==<key>'
print *, ''
print *, 'OPTIONS:'
print *, ''
do i = 1, size (long_options)
call long_options(i) % print (6)
end do
go to 999
endif
iret=fftwf_init_threads() !Initialize FFTW threading
! Default to 1 thread, but use nthreads for the big ones
call fftwf_plan_with_nthreads(1)
! Import FFTW wisdom, if available
wisfile=trim(data_dir)//'/jt9_wisdom.dat'// C_NULL_CHAR
iret=fftwf_import_wisdom_from_filename(wisfile)
ntry65a=0
ntry65b=0
n65a=0
n65b=0
num9=0
numfano=0
if (.not. read_files) then
call jt9a() !We're running under control of WSJT-X
go to 999
endif
if(mycall.eq.'b') mycall=' '
if(hiscall.eq.'b') then
hiscall=' '
hisgrid=' '
endif
if (mode .eq. 241 .or. mode .eq. 242) then
ntol = min (ntol, 100)
else if (mode .eq. 65 + 9 .and. .not. have_ntol) then
ntol = 20
else if (mode .eq. 66 .and. .not. have_ntol) then
ntol = 10
else
ntol = min (ntol, 1000)
end if
if (.not. nexp_decode_set) then
if (mode .eq. 240 .or. mode .eq. 241 .or. mode .eq. 242) then
nexp_decode = 3 * 256 ! single decode off and nb=0
end if
end if
allocate(shared_data)
nflatten=0
do iarg = offset + 1, offset + remain
call get_command_argument (iarg, optarg, arglen)
infile = optarg(:arglen)
call wav%read (infile)
nfsample=wav%audio_format%sample_rate
i1=index(infile,'.wav')
if(i1.lt.1) i1=index(infile,'.WAV')
if(infile(i1-5:i1-5).eq.'_') then
read(infile(i1-4:i1-1),*,err=1) nutc
else
read(infile(i1-6:i1-1),*,err=1) nutc
endif
go to 2
1 nutc=0
2 nsps=6912
npts=TRperiod*12000.d0
kstep=nsps/2
k=0
nhsym=0
nhsym0=-999
if(iarg .eq. offset + 1) then
call init_timer (trim(data_dir)//'/timer.out')
call timer('jt9 ',0)
endif
shared_data%id2=0 !??? Why is this necessary ???
if(mode.eq.5) npts=21*3456
if(mode.eq.66) npts=TRperiod*12000
do iblk=1,npts/kstep
k=iblk*kstep
if(mode.eq.8 .and. k.gt.179712) exit
call timer('read_wav',0)
read(unit=wav%lun,end=3) shared_data%id2(k-kstep+1:k)
go to 4
3 call timer('read_wav',1)
print*,'EOF on input file ',trim(infile)
exit
4 call timer('read_wav',1)
nhsym=(k-2048)/kstep
if(nhsym.ge.1 .and. nhsym.ne.nhsym0) then
if(mode.eq.9 .or. mode.eq.74) then
! Compute rough symbol spectra for the JT9 decoder
ingain=0
call timer('symspec ',0)
nminw=1
call symspec(shared_data,k,Tperiod,nsps,ingain, &
bLowSidelobes,nminw,pxdb,s,df3,ihsym,npts8,pxdbmax)
call timer('symspec ',1)
endif
nhsym0=nhsym
if(nhsym.ge.181 .and. mode.ne.240 .and. mode.ne.241 .and. &
mode.ne.242 .and. mode.ne.66) exit
endif
enddo
close(unit=wav%lun)
shared_data%params%nutc=nutc
shared_data%params%ndiskdat=.true.
shared_data%params%ntr=TRperiod
shared_data%params%nfqso=nrxfreq
shared_data%params%newdat=.true.
shared_data%params%npts8=74736
shared_data%params%nfa=flow
shared_data%params%nfsplit=fsplit
shared_data%params%nfb=fhigh
shared_data%params%ntol=ntol
shared_data%params%kin=64800
if(mode.eq.240) shared_data%params%kin=720000 !### 60 s periods ###
shared_data%params%nzhsym=nhsym
shared_data%params%ndepth=ndepth
shared_data%params%lft8apon=.true.
shared_data%params%ljt65apon=.true.
shared_data%params%napwid=75
shared_data%params%dttol=3.
if(mode.eq.164 .and. nsubmode.lt.100) nsubmode=nsubmode+100
shared_data%params%nagain=.false.
shared_data%params%nclearave=.false.
shared_data%params%lapcqonly=.false.
shared_data%params%naggressive=0
shared_data%params%n2pass=2
shared_data%params%nQSOprogress=nQSOProg
shared_data%params%nranera=6 !### ntrials=3000
shared_data%params%nrobust=.false.
shared_data%params%nexp_decode=nexp_decode
shared_data%params%mycall=transfer(mycall,shared_data%params%mycall)
shared_data%params%mygrid=transfer(mygrid,shared_data%params%mygrid)
shared_data%params%hiscall=transfer(hiscall,shared_data%params%hiscall)
shared_data%params%hisgrid=transfer(hisgrid,shared_data%params%hisgrid)
if (tx9) then
shared_data%params%ntxmode=9
else
shared_data%params%ntxmode=65
end if
if (mode.eq.0) then
shared_data%params%nmode=65+9
else
shared_data%params%nmode=mode
end if
shared_data%params%nsubmode=nsubmode
!### temporary, for MAP65:
if(mode.eq.66 .and. TRperiod.eq.60) shared_data%params%emedelay=2.5
datetime="2013-Apr-16 15:13" !### Temp
shared_data%params%datetime=transfer(datetime,shared_data%params%datetime)
if(mode.eq.9 .and. fsplit.ne.2700) shared_data%params%nfa=fsplit
if(mode.eq.8) then
! "Early" decoding pass, FT8 only, when jt9 reads data from disk
nearly=41
shared_data%params%nzhsym=nearly
id2a(1:nearly*3456)=shared_data%id2(1:nearly*3456)
id2a(nearly*3456+1:)=0
call multimode_decoder(shared_data%ss,id2a, &
shared_data%params,nfsample)
nearly=47
shared_data%params%nzhsym=nearly
id2a(1:nearly*3456)=shared_data%id2(1:nearly*3456)
id2a(nearly*3456+1:)=0
call multimode_decoder(shared_data%ss,id2a, &
shared_data%params,nfsample)
id2a(nearly*3456+1:50*3456)=shared_data%id2(nearly*3456+1:50*3456)
id2a(50*3456+1:)=0
shared_data%params%nzhsym=50
call multimode_decoder(shared_data%ss,id2a, &
shared_data%params,nfsample)
cycle
! MSK144
else if (mode .eq. 144) then
call decode_msk144(shared_data%id2, shared_data%params, data_dir)
endif
! Normal decoding pass
call multimode_decoder(shared_data%ss,shared_data%id2, &
shared_data%params,nfsample)
enddo
call timer('jt9 ',1)
call timer('jt9 ',101)
999 continue
! Output decoder statistics
call fini_timer ()
! Save FFTW wisdom and free memory
if(len(trim(wisfile)).gt.0) iret=fftwf_export_wisdom_to_filename(wisfile)
call four2a(a,-1,1,1,1)
call filbig(a,-1,1,0.0,0,0,0,0,0) !used for FFT plans
call fftwf_cleanup_threads()
call fftwf_cleanup()
end program jt9
subroutine jt9a()
use, intrinsic :: iso_c_binding, only: c_f_pointer, c_null_char, c_bool
use prog_args
use timer_module, only: timer
use timer_impl, only: init_timer !, limtrace
use shmem
include 'jt9com.f90'
integer*2 id2a(180000)
! Multiple instances:
type(dec_data), pointer, volatile :: shared_data !also makes target volatile
type(params_block) :: local_params
logical(c_bool) :: ok
call init_timer (trim(data_dir)//'/timer.out')
! open(23,file=trim(data_dir)//'/CALL3.TXT',status='unknown')
! limtrace=-1 !Disable all calls to timer()
! Multiple instances: set the shared memory key before attaching
call shmem_setkey(trim(shm_key)//c_null_char)
ok=shmem_attach()
if(.not.ok) call abort
msdelay=30
call c_f_pointer(shmem_address(),shared_data)
! Terminate if ipc(2) is 999
10 ok=shmem_lock()
if(.not.ok) call abort
if(shared_data%ipc(2).eq.999.0) then
ok=shmem_unlock()
ok=shmem_detach()
go to 999
endif
! Wait here until GUI has set ipc(2) to 1
if(shared_data%ipc(2).ne.1) then
ok=shmem_unlock()
if(.not.ok) call abort
call sleep_msec(msdelay)
go to 10
endif
shared_data%ipc(2)=0
nbytes=shmem_size()
if(nbytes.le.0) then
ok=shmem_unlock()
ok=shmem_detach()
print*,'jt9a: Shared memory does not exist.'
print*,"Must start 'jt9 -s <thekey>' from within WSJT-X."
go to 999
endif
local_params=shared_data%params !save a copy because wsjtx carries on
accessing
ok=shmem_unlock()
if(.not.ok) call abort
call flush(6)
call timer('decoder ',0)
if(local_params%nmode.eq.8 .and. local_params%ndiskdat .and. &
.not. local_params%nagain) then
! Early decoding pass, FT8 only, when wsjtx reads from disk
nearly=41
local_params%nzhsym=nearly
id2a(1:nearly*3456)=shared_data%id2(1:nearly*3456)
id2a(nearly*3456+1:)=0
call multimode_decoder(shared_data%ss,id2a,local_params,12000)
nearly=47
local_params%nzhsym=nearly
id2a(1:nearly*3456)=shared_data%id2(1:nearly*3456)
id2a(nearly*3456+1:)=0
call multimode_decoder(shared_data%ss,id2a,local_params,12000)
local_params%nzhsym=50
endif
if(local_params%nmode .eq. 144) then
! MSK144
call decode_msk144(shared_data%id2, shared_data%params, data_dir)
else
! Normal decoding pass
call multimode_decoder(shared_data%ss,shared_data%id2,local_params,12000)
endif
call timer('decoder ',1)
! Wait here until GUI routine decodeDone() has set ipc(3) to 1
100 ok=shmem_lock()
if(.not.ok) call abort
if(shared_data%ipc(3).ne.1) then
ok=shmem_unlock()
if(.not.ok) call abort
call sleep_msec(msdelay)
go to 100
endif
shared_data%ipc(3)=0
ok=shmem_unlock()
if(.not.ok) call abort
go to 10
999 call timer('decoder ',101)
return
end subroutine jt9a
cmake_minimum_required (VERSION 3.7.2 FATAL_ERROR)
if (APPLE)
#
# The following variables define the portability and compatability attributes
of the Mac macOS build
# they are choosen with care and should not be changed without good cause.
#
# Among other things these options are chosen to match the portability and
compatability options of the
# Qt framework dylibs which can be checked as follows:
#
# otool -l <binary> | grep -A3 LC_VERSION_MIN_MACOSX
#
set (CMAKE_OSX_DEPLOYMENT_TARGET 10.12
CACHE STRING "Earliest version of macOS supported
Earliest version we can support with Qt 5.12, C++11 & libc++ is 10.12.
Do not override this if you intend to build an official deployable installer.")
endif (APPLE)
#
# CMake policies
#
if (POLICY CMP0020)
cmake_policy (SET CMP0020 NEW) # link to Qt winmain on Windows
endif ()
if (POLICY CMP0043)
cmake_policy (SET CMP0043 NEW) # ignore COMPILE_DEFINITIONS_<CONFIG>
endif ()
if (POLICY CMP0048)
cmake_policy (SET CMP0048 NEW) # clear PROJECT_Version_* variables if not set
in project() command
endif ()
if (POLICY CMP0063)
cmake_policy (SET CMP0063 NEW) # honour visibility properties for all library
types
endif ()
if (POLICY CMP0071)
cmake_policy (SET CMP0071 NEW) # run automoc and autouic on generated sources
endif ()
if (POLICY CMP0075)
cmake_policy (SET CMP0075 NEW) # honour CMAKE_REQUIRED_LIBRARIES in config
checks
endif ()
project (wsjtx
VERSION 2.7.0.0
LANGUAGES C CXX Fortran
)
set (PROJECT_DESCRIPTION "WSJT-X: Digital Modes for Weak Signal Communications
in Amateur Radio")
set (CMAKE_PROJECT_DESCRIPTION ${PROJECT_DESCRIPTION})
#
# Local CMake modules and support files
#
set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake/Modules ${CMAKE_MODULE_PATH})
set (PROJECT_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}")
if (NOT PROJECT_ARCHITECTURE)
# This is supposed to happen already on Windows
if (CMAKE_SIZEOF_VOID_P MATCHES 8)
set (PROJECT_ARCHITECTURE "x64")
else ()
set (PROJECT_ARCHITECTURE "$ENV{PROCESSOR_ARCHITECTURE}")
endif ()
endif ()
message (STATUS "******************************************************")
message (STATUS "Building for for:
${CMAKE_SYSTEM_NAME}-${PROJECT_ARCHITECTURE}")
message (STATUS "******************************************************")
include (set_build_type)
# RC 0 or omitted is a development build, GA is a General Availability release
build
set_build_type (RC 3)
set (wsjtx_VERSION
"${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${BUILD_TYPE_REVISION}")
#
# project information
#
set (PROJECT_BUNDLE_NAME "WSJT-X")
set (PROJECT_VENDOR "Joe Taylor, K1JT")
set (PROJECT_CONTACT "Joe Taylor <k...@arrl.net>")
set (PROJECT_COPYRIGHT "Copyright (C) 2001-2023 by Joe Taylor, K1JT")
set (PROJECT_HOMEPAGE https://wsjt.sourceforge.io/wsjtx.html)
set (PROJECT_MANUAL wsjtx-main)
set (PROJECT_MANUAL_DIRECTORY_URL https://wsjt.sourceforge.io/wsjtx-doc/)
set (PROJECT_SAMPLES_URL http://downloads.sourceforge.net/project/wsjt/)
set (PROJECT_SAMPLES_UPLOAD_DEST frs.sourceforge.net:/home/frs/project/wsjt/)
# make sure that the default configuration is a RELEASE
if (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE RELEASE CACHE STRING
"Choose the type of build, options are: None Debug Release."
FORCE)
endif (NOT CMAKE_BUILD_TYPE)
if (CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")
set (is_debug_build 1)
endif ()
#
# Options & features
#
# Some of these directly effect compilation by being defined in
# wsjtx_config.h.in which makes them available to the C/C++
# pre-processor.
#
include (CMakeDependentOption)
# Allow the developer to select if Dynamic or Static libraries are built
OPTION (BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
# Set the LIB_TYPE variable to STATIC
SET (LIB_TYPE STATIC)
if (BUILD_SHARED_LIBS)
# User wants to build Dynamic Libraries, so change the LIB_TYPE variable to
CMake keyword 'SHARED'
set (LIB_TYPE SHARED)
endif (BUILD_SHARED_LIBS)
option (UPDATE_TRANSLATIONS "Update source translation translations/*.ts
files (WARNING: make clean will delete the source .ts files! Danger!)")
option (WSJT_SHARED_RUNTIME "Debugging option that allows running from a shared
Cloud directory.")
option (WSJT_QDEBUG_TO_FILE "Redirect Qt debuging messages to a trace file.")
option (WSJT_SOFT_KEYING "Apply a ramp to CW keying envelope to reduce
transients." ON)
option (WSJT_SKIP_MANPAGES "Skip *nix manpage generation.")
option (WSJT_GENERATE_DOCS "Generate documentation files." ON)
option (WSJT_RIG_NONE_CAN_SPLIT "Allow split operation with \"None\" as rig.")
option (WSJT_TRACE_UDP "Debugging option that turns on UDP message protocol
diagnostics.")
option (WSJT_BUILD_UTILS "Build simulators and code demonstrators." ON)
CMAKE_DEPENDENT_OPTION (WSJT_QDEBUG_IN_RELEASE "Leave Qt debugging statements
in Release configuration." OFF
"NOT is_debug_build" OFF)
CMAKE_DEPENDENT_OPTION (WSJT_ENABLE_EXPERIMENTAL_FEATURES "Enable features not
fully ready for public releases." ON
is_debug_build OFF)
CMAKE_DEPENDENT_OPTION (WSJT_CREATE_WINMAIN
"The wsjtx target is normally built as GUI executable with a WinMain entry
point on Windows,
if you want a console application instead then set this option to OFF.
If you just want to see the debug output from the application then the easiest
way is to
attach a debugger which will then receive the console output inside its
console." ON
"WIN32" OFF)
#
# install locations
#
if (APPLE)
set (CMAKE_INSTALL_BINDIR ${CMAKE_PROJECT_NAME}.app/Contents/MacOS)
set (CMAKE_INSTALL_DATAROOTDIR ${CMAKE_PROJECT_NAME}.app/Contents/Resources)
endif ()
include (GNUInstallDirs)
set (PLUGIN_DESTINATION ${CMAKE_INSTALL_LIBDIR}/plugins)
set (QT_CONF_DESTINATION ${CMAKE_INSTALL_BINDIR})
if (WIN32)
set (PLUGIN_DESTINATION plugins)
elseif (APPLE)
set (PLUGIN_DESTINATION ${CMAKE_INSTALL_BINDIR}/../PlugIns)
set (QT_CONF_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR})
endif ()
set (WSJT_PLUGIN_DESTINATION ${PLUGIN_DESTINATION} CACHE PATH "Path for
plugins")
set (WSJT_QT_CONF_DESTINATION ${QT_CONF_DESTINATION} CACHE PATH "Path for the
qt.conf file")
#
# Project sources
#
set (fort_qt_CXXSRCS
lib/shmem.cpp
)
set (wsjt_qt_CXXSRCS
helper_functions.cpp
qt_helpers.cpp
widgets/MessageBox.cpp
MetaDataRegistry.cpp
Network/NetworkServerLookup.cpp
revision_utils.cpp
L10nLoader.cpp
WFPalette.cpp
Radio.cpp
RadioMetaType.cpp
NonInheritingProcess.cpp
models/IARURegions.cpp
models/Bands.cpp
models/Modes.cpp
models/FrequencyList.cpp
models/StationList.cpp
widgets/FrequencyLineEdit.cpp
widgets/FrequencyDeltaLineEdit.cpp
item_delegates/CandidateKeyFilter.cpp
item_delegates/ForeignKeyDelegate.cpp
item_delegates/MessageItemDelegate.cpp
validators/LiveFrequencyValidator.cpp
GetUserId.cpp
Audio/AudioDevice.cpp
Transceiver/Transceiver.cpp
Transceiver/TransceiverBase.cpp
Transceiver/EmulateSplitTransceiver.cpp
Transceiver/TransceiverFactory.cpp
Transceiver/PollingTransceiver.cpp
Transceiver/HamlibTransceiver.cpp
Transceiver/HRDTransceiver.cpp
Transceiver/DXLabSuiteCommanderTransceiver.cpp
Network/NetworkMessage.cpp
Network/MessageClient.cpp
widgets/LettersSpinBox.cpp
widgets/HintedSpinBox.cpp
widgets/RestrictedSpinBox.cpp
widgets/HelpTextWindow.cpp
SampleDownloader.cpp
SampleDownloader/DirectoryDelegate.cpp
SampleDownloader/Directory.cpp
SampleDownloader/FileNode.cpp
SampleDownloader/RemoteFile.cpp
DisplayManual.cpp
MultiSettings.cpp
validators/MaidenheadLocatorValidator.cpp
validators/CallsignValidator.cpp
widgets/SplashScreen.cpp
EqualizationToolsDialog.cpp
widgets/DoubleClickablePushButton.cpp
widgets/DoubleClickableRadioButton.cpp
Network/LotWUsers.cpp
Network/FileDownload.cpp
models/DecodeHighlightingModel.cpp
widgets/DecodeHighlightingListView.cpp
models/FoxLog.cpp
widgets/AbstractLogWindow.cpp
widgets/FoxLogWindow.cpp
widgets/CabrilloLogWindow.cpp
item_delegates/CallsignDelegate.cpp
item_delegates/MaidenheadLocatorDelegate.cpp
item_delegates/FrequencyDelegate.cpp
item_delegates/FrequencyDeltaDelegate.cpp
item_delegates/SQLiteDateTimeDelegate.cpp
models/CabrilloLog.cpp
logbook/AD1CCty.cpp
logbook/WorkedBefore.cpp
logbook/Multiplier.cpp
Network/NetworkAccessManager.cpp
widgets/LazyFillComboBox.cpp
widgets/CheckableItemComboBox.cpp
widgets/BandComboBox.cpp
)
set (wsjt_qtmm_CXXSRCS
Audio/BWFFile.cpp
)
set (jt9_FSRCS
lib/jt9.f90
lib/jt9a.f90
)
set (wsjtx_CXXSRCS
WSJTXLogging.cpp
logbook/logbook.cpp
Network/PSKReporter.cpp
Modulator/Modulator.cpp
Detector/Detector.cpp
widgets/logqso.cpp
widgets/displaytext.cpp
Decoder/decodedtext.cpp
getfile.cpp
Audio/soundout.cpp
Audio/soundin.cpp
widgets/meterwidget.cpp
widgets/signalmeter.cpp
widgets/plotter.cpp
widgets/widegraph.cpp
widgets/echograph.cpp
widgets/echoplot.cpp
widgets/fastgraph.cpp
widgets/fastplot.cpp
widgets/about.cpp
widgets/astro.cpp
widgets/messageaveraging.cpp
widgets/activeStations.cpp
widgets/colorhighlighting.cpp
WSPR/WsprTxScheduler.cpp
widgets/mainwindow.cpp
Configuration.cpp
main.cpp
Network/wsprnet.cpp
WSPR/WSPRBandHopping.cpp
widgets/ExportCabrillo.cpp
)
set (wsjt_CXXSRCS
Logger.cpp
lib/crc10.cpp
lib/crc13.cpp
lib/crc14.cpp
)
# deal with a GCC v6 UB error message
set_source_files_properties (
lib/crc10.cpp
lib/crc13.cpp
lib/crc14.cpp
PROPERTIES COMPILE_FLAGS -fpermissive)
if (WIN32)
set (wsjt_CXXSRCS
${wsjt_CXXSRCS}
killbyname.cpp
)
set (wsjt_qt_CXXSRCS
${wsjt_qt_CXXSRCS}
Transceiver/OmniRigTransceiver.cpp
)
endif (WIN32)
set (wsjt_FSRCS
# put module sources first in the hope that they get rebuilt before use
lib/types.f90
lib/C_interface_module.f90
lib/shmem.f90
lib/crc.f90
lib/fftw3mod.f90
lib/hashing.f90
lib/iso_c_utilities.f90
lib/jt4.f90
lib/jt4_decode.f90
lib/jt65_decode.f90
lib/jt65_mod.f90
lib/ft8_decode.f90
lib/ft4_decode.f90
lib/fst4_decode.f90
lib/get_q3list.f90
lib/jt9_decode.f90
lib/options.f90
lib/packjt.f90
lib/77bit/packjt77.f90
lib/qra/q65/q65.f90
lib/q65_decode.f90
lib/readwav.f90
lib/timer_C_wrapper.f90
lib/timer_impl.f90
lib/timer_module.f90
lib/wavhdr.f90
lib/qra/q65/q65_encoding_modules.f90
lib/ft8/ft8_a7.f90
# remaining non-module sources
lib/addit.f90
lib/afc65b.f90
lib/afc9.f90
lib/ana64.f90
lib/ana932.f90
lib/analytic.f90
lib/astro.f90
lib/astrosub.f90
lib/astro0.f90
lib/avecho.f90
lib/averms.f90
lib/azdist.f90
lib/ft8/baseline.f90
lib/ft4/ft4_baseline.f90
lib/blanker.f90
lib/bpdecode40.f90
lib/bpdecode128_90.f90
lib/ft8/bpdecode174_91.f90
lib/baddata.f90
lib/cablog.f90
lib/calibrate.f90
lib/ccf2.f90
lib/ccf65.f90
lib/ft8/chkcrc13a.f90
lib/ft8/chkcrc14a.f90
lib/chkcall.f90
lib/chkhist.f90
lib/chkmsg.f90
lib/chkss2.f90
lib/ft4/clockit.f90
lib/ft8/compress.f90
lib/coord.f90
lib/db.f90
lib/decode4.f90
lib/decode65a.f90
lib/decode65b.f90
lib/decode9w.f90
lib/ft8/decode174_91.f90
lib/decoder.f90
lib/deep4.f90
lib/deg2grid.f90
lib/degrade_snr.f90
lib/demod64a.f90
lib/determ.f90
lib/downsam9.f90
lib/echosim.f90
lib/echo_snr.f90
lib/encode232.f90
lib/encode4.f90
lib/encode_msk40.f90
lib/encode_128_90.f90
lib/ft8/encode174_91.f90
lib/ft8/encode174_91_nocrc.f90
lib/entail.f90
lib/ephem.f90
lib/extract.f90
lib/extract4.f90
lib/extractmessage77.f90
lib/fano232.f90
lib/fast9.f90
lib/fast_decode.f90
lib/fchisq.f90
lib/fchisq0.f90
lib/fchisq65.f90
lib/fil3.f90
lib/fil3c.f90
lib/fil4.f90
lib/fil6521.f90
lib/filbig.f90
lib/ft8/filt8.f90
lib/fitcal.f90
lib/flat1.f90
lib/flat1a.f90
lib/flat1b.f90
lib/flat2.f90
lib/flat4.f90
lib/flat65.f90
lib/fmtmsg.f90
lib/foldspec9f.f90
lib/four2a.f90
lib/fspread_lorentz.f90
lib/ft8/foxfilt.f90
lib/ft8/foxgen.f90
lib/ft8/foxgen_wrap.f90
lib/freqcal.f90
lib/ft8/ft8apset.f90
lib/ft8/ft8b.f90
lib/ft8/ft8code.f90
lib/ft8/ft8_downsample.f90
lib/ft8/ft8sim.f90
lib/gen4.f90
lib/gen65.f90
lib/gen9.f90
lib/genwave.f90
lib/ft8/genft8.f90
lib/qra/q65/genq65.f90
lib/genmsk_128_90.f90
lib/genmsk40.f90
lib/ft4/ft4code.f90
lib/ft4/genft4.f90
lib/ft4/gen_ft4wave.f90
lib/ft8/gen_ft8wave.f90
lib/ft8/genft8refsig.f90
lib/genwspr.f90
lib/geodist.f90
lib/ft8/get_crc14.f90
lib/getlags.f90
lib/getmet4.f90
lib/ft8/get_spectrum_baseline.f90
lib/ft2/gfsk_pulse.f90
lib/graycode.f90
lib/graycode65.f90
lib/grayline.f90
lib/grid2deg.f90
lib/ft8/h1.f90
lib/hash.f90
lib/hint65.f90
lib/hspec.f90
lib/indexx.f90
lib/init_random_seed.f90
lib/interleave4.f90
lib/interleave63.f90
lib/interleave9.f90
lib/inter_wspr.f90
lib/jplsubs.f
lib/jt9fano.f90
lib/libration.f90
lib/lorentzian.f90
lib/fst4/lorentzian_fading.f90
lib/lpf1.f90
lib/map65_mmdec.f90
lib/mixlpf.f90
lib/makepings.f90
lib/moondopjpl.f90
lib/morse.f90
lib/move.f90
lib/msk40decodeframe.f90
lib/msk144decodeframe.f90
lib/msk40spd.f90
lib/msk144spd.f90
lib/msk40sync.f90
lib/msk144sync.f90
lib/msk40_freq_search.f90
lib/msk144_freq_search.f90
lib/mskrtd.f90
lib/msk144signalquality.f90
lib/msk144sim.f90
lib/mskrtd.f90
lib/nuttal_window.f90
lib/decode_msk144.f90
lib/ft4/ft4sim.f90
lib/ft4/ft4sim_mult.f90
lib/ft4/ft4_downsample.f90
lib/77bit/my_hash.f90
lib/wsprd/osdwspr.f90
lib/ft8/osd174_91.f90
lib/osd128_90.f90
lib/pctile.f90
lib/peakdt9.f90
lib/peakup.f90
lib/plotsave.f90
lib/platanh.f90
lib/pltanh.f90
lib/polyfit.f90
lib/prog_args.f90
lib/ps4.f90
lib/qra/q65/q65_ap.f90
lib/qra/q65/q65_loops.f90
lib/qra/q65/q65_set_list.f90
lib/qra/q65/q65_set_list2.f90
lib/refspectrum.f90
lib/savec2.f90
lib/save_dxbase.f90
lib/save_echo_params.f90
lib/sec0.f90
lib/sec_midn.f90
lib/setup65.f90
lib/sh65.f90
lib/sh65snr.f90
lib/slasubs.f
lib/sleep_msec.f90
lib/slope.f90
lib/smo.f90
lib/smo121.f90
lib/softsym.f90
lib/softsym9f.f90
lib/softsym9w.f90
lib/shell.f90
lib/spec64.f90
lib/spec9f.f90
lib/stdmsg.f90
lib/subtract65.f90
lib/ft8/subtractft8.f90
lib/ft4/subtractft4.f90
lib/sun.f90
lib/symspec.f90
lib/symspec2.f90
lib/symspec65.f90
lib/sync4.f90
lib/sync65.f90
lib/ft4/getcandidates4.f90
lib/ft4/get_ft4_bitmetrics.f90
lib/ft8/sync8.f90
lib/ft8/sync8d.f90
lib/ft4/sync4d.f90
lib/sync9.f90
lib/sync9f.f90
lib/sync9w.f90
lib/test_snr.f90
lib/timf2.f90
lib/tweak1.f90
lib/twkfreq.f90
lib/ft8/twkfreq1.f90
lib/twkfreq65.f90
lib/update_recent_calls.f90
lib/update_msk40_hasharray.f90
lib/ft8/watterson.f90
lib/wav11.f90
lib/wav12.f90
lib/xcor.f90
lib/xcor4.f90
lib/wqdecode.f90
lib/wqencode.f90
lib/wspr_downsample.f90
lib/zplot9.f90
lib/fst4/decode240_101.f90
lib/fst4/decode240_74.f90
lib/fst4/encode240_101.f90
lib/fst4/encode240_74.f90
lib/fst4/fst4sim.f90
lib/fst4/gen_fst4wave.f90
lib/fst4/genfst4.f90
lib/fst4/get_fst4_bitmetrics.f90
lib/fst4/get_fst4_bitmetrics2.f90
lib/fst4/ldpcsim240_101.f90
lib/fst4/ldpcsim240_74.f90
lib/fst4/osd240_101.f90
lib/fst4/osd240_74.f90
lib/fst4/fastosd240_74.f90
lib/fst4/get_crc24.f90
lib/fst4/fst4_baseline.f90
lib/77bit/hash22calc.f90
)
# temporary workaround for a gfortran v7.3 ICE on Fedora 27 64-bit
set_source_files_properties (lib/slasubs.f PROPERTIES COMPILE_FLAGS -O2)
set (ka9q_CSRCS
lib/ftrsd/decode_rs.c
lib/ftrsd/encode_rs.c
lib/ftrsd/init_rs.c
)
set_source_files_properties (${ka9q_CSRCS} PROPERTIES COMPILE_FLAGS
-Wno-sign-compare)
set (qra_CSRCS
lib/qra/qracodes/qra12_63_64_irr_b.c
lib/qra/qracodes/qra13_64_64_irr_e.c
lib/qra/q65/npfwht.c
lib/qra/q65/pdmath.c
lib/qra/q65/qracodes.c
lib/qra/q65/normrnd.c
lib/qra/q65/qra15_65_64_irr_e23.c
lib/qra/q65/q65.c
lib/qra/q65/q65_subs.c
)
set (wsjt_CSRCS
${ka9q_CSRCS}
lib/ftrsd/ftrsdap.c
lib/sgran.c
lib/golay24_table.c
lib/gran.c
lib/igray.c
lib/init_random_seed.c
lib/ldpc32_table.c
lib/wsprd/nhash.c
lib/tab.c
lib/tmoonsub.c
lib/usleep.c
lib/vit213.c
lib/wisdom.c
lib/wrapkarn.c
${ldpc_CSRCS}
${qra_CSRCS}
)
set (wsjt_qt_UISRCS
wf_palette_design_dialog.ui
widgets/FoxLogWindow.ui
widgets/CabrilloLogWindow.ui
)
set (wsprsim_CSRCS
lib/wsprd/wsprsim.c
lib/wsprd/wsprsim_utils.c
lib/wsprd/wsprd_utils.c
lib/wsprd/fano.c
lib/wsprd/tab.c
lib/wsprd/nhash.c
)
set (wsprd_CSRCS
lib/wsprd/wsprd.c
lib/wsprd/wsprsim_utils.c
lib/wsprd/wsprd_utils.c
lib/wsprd/fano.c
lib/wsprd/jelinek.c
lib/wsprd/tab.c
lib/wsprd/nhash.c
lib/init_random_seed.c
)
set (wsjtx_UISRCS
widgets/mainwindow.ui
widgets/about.ui
widgets/astro.ui
widgets/colorhighlighting.ui
widgets/echograph.ui
widgets/fastgraph.ui
widgets/messageaveraging.ui
widgets/activeStations.ui
widgets/widegraph.ui
widgets/logqso.ui
Configuration.ui
widgets/ExportCabrillo.ui
)
set (UDP_library_CXXSRCS
Radio.cpp
RadioMetaType.cpp
Network/NetworkMessage.cpp
UDPExamples/MessageServer.cpp
)
set (UDP_library_HEADERS
Radio.hpp
UDPExamples/MessageServer.hpp
${PROJECT_BINARY_DIR}/udp_export.h
)
set (message_aggregator_CXXSRCS
UDPExamples/MessageAggregator.cpp
UDPExamples/MessageAggregatorMainWindow.cpp
UDPExamples/DecodesModel.cpp
UDPExamples/BeaconsModel.cpp
UDPExamples/ClientWidget.cpp
validators/MaidenheadLocatorValidator.cpp
)
set (message_aggregator_STYLESHEETS
UDPExamples/qss/default.qss
)
set (qcp_CXXSRCS
qcustomplot-source/qcustomplot.cpp
)
set (all_CXXSRCS
${wsjt_CXXSRCS}
${fort_qt_CXXSRCS}
${wsjt_qt_CXXSRCS}
${wsjt_qtmm_CXXSRCS}
${wsjtx_CXXSRCS}
${qcp_CXXSRCS}
)
set (all_C_and_CXXSRCS
${wsjt_CSRCS}
${wsprsim_CSRCS}
${wsprd_CSRCS}
${all_CXXSRCS}
)
set (TOP_LEVEL_RESOURCES
icons/Darwin/wsjtx.iconset/icon_128x128.png
contrib/gpl-v3-logo.svg
artwork/splash.png
)
set (PALETTE_FILES
Palettes/Banana.pal
Palettes/Blue1.pal
Palettes/Blue2.pal
Palettes/Blue3.pal
Palettes/Brown.pal
Palettes/Cyan1.pal
Palettes/Cyan2.pal
Palettes/Cyan3.pal
Palettes/Default.pal
Palettes/Digipan.pal
Palettes/Fldigi.pal
Palettes/Gray1.pal
Palettes/Gray2.pal
Palettes/Green1.pal
Palettes/Green2.pal
Palettes/Jungle.pal
Palettes/Linrad.pal
Palettes/Negative.pal
Palettes/Orange.pal
Palettes/Pink.pal
Palettes/Rainbow.pal
Palettes/Scope.pal
Palettes/Sunburst.pal
Palettes/VK4BDJ.pal
Palettes/YL2KF.pal
Palettes/Yellow1.pal
Palettes/Yellow2.pal
Palettes/ZL1FZ.pal
)
if (APPLE)
set (WSJTX_ICON_FILE ${CMAKE_PROJECT_NAME}.icns)
set (ICONSRCS
icons/Darwin/${CMAKE_PROJECT_NAME}.iconset/icon_16x16.png
icons/Darwin/${CMAKE_PROJECT_NAME}.iconset/icon_16...@2x.png
icons/Darwin/${CMAKE_PROJECT_NAME}.iconset/icon_32x32.png
icons/Darwin/${CMAKE_PROJECT_NAME}.iconset/icon_32...@2x.png
icons/Darwin/${CMAKE_PROJECT_NAME}.iconset/icon_128x128.png
icons/Darwin/${CMAKE_PROJECT_NAME}.iconset/icon_128x...@2x.png
icons/Darwin/${CMAKE_PROJECT_NAME}.iconset/icon_256x256.png
icons/Darwin/${CMAKE_PROJECT_NAME}.iconset/icon_256x...@2x.png
icons/Darwin/${CMAKE_PROJECT_NAME}.iconset/icon_512x512.png
icons/Darwin/${CMAKE_PROJECT_NAME}.iconset/icon_512x...@2x.png
)
add_custom_command (
OUTPUT ${WSJTX_ICON_FILE}
COMMAND iconutil -c icns --output "${CMAKE_BINARY_DIR}/${WSJTX_ICON_FILE}"
"${CMAKE_SOURCE_DIR}/icons/Darwin/${CMAKE_PROJECT_NAME}.iconset"
DEPENDS ${ICONSRCS}
COMMENT "Building Icons"
)
else ()
set (WSJTX_ICON_FILE icons/windows-icons/wsjtx.ico)
endif (APPLE)
set_source_files_properties (${WSJTX_ICON_FILE} PROPERTIES
MACOSX_PACKAGE_LOCATION Resources)
# suppress intransigent compiler diagnostics
set_source_files_properties (lib/decoder.f90 PROPERTIES COMPILE_FLAGS
"-Wno-unused-dummy-argument")
set_source_files_properties (lib/filbig.f90 PROPERTIES COMPILE_FLAGS
"-Wno-aliasing")
## disable Qt trace and warning messages from release configurations
#set_property (DIRECTORY APPEND PROPERTY
# COMPILE_DEFINITIONS
$<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG_OUTPUT;QT_NO_WARNING_OUTPUT>
# )
set_property (SOURCE ${all_C_and_CXXSRCS} APPEND_STRING PROPERTY COMPILE_FLAGS
" -include wsjtx_config.h")
set_property (SOURCE ${all_C_and_CXXSRCS} APPEND PROPERTY OBJECT_DEPENDS
${CMAKE_CURRENT_BINARY_DIR}/wsjtx_config.h)
if (WIN32)
# generate the OmniRig COM interface source
find_program (DUMPCPP dumpcpp)
if (DUMPCPP-NOTFOUND)
message (FATAL_ERROR "dumpcpp tool not found")
endif (DUMPCPP-NOTFOUND)
execute_process (
COMMAND ${DUMPCPP} -getfile {4FE359C5-A58F-459D-BE95-CA559FB4F270}
OUTPUT_VARIABLE AXSERVER
OUTPUT_STRIP_TRAILING_WHITESPACE
)
string (STRIP "${AXSERVER}" AXSERVER)
if (NOT AXSERVER)
message (FATAL_ERROR "You need to install OmniRig on this computer")
endif (NOT AXSERVER)
string (REPLACE "\"" "" AXSERVER ${AXSERVER})
file (TO_CMAKE_PATH ${AXSERVER} AXSERVERSRCS)
endif ()
#
# decide on platform specifc packing and fixing up
#
if (APPLE)
set (WSJTX_BUNDLE_VERSION ${wsjtx_VERSION})
# make sure CMAKE_INSTALL_PREFIX ends in /
string (LENGTH "${CMAKE_INSTALL_PREFIX}" LEN)
math (EXPR LEN "${LEN} -1" )
string (SUBSTRING "${CMAKE_INSTALL_PREFIX}" ${LEN} 1 ENDCH)
if (NOT "${ENDCH}" STREQUAL "/")
set (CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/")
endif ()
endif (APPLE)
#
# find some useful tools
#
include (CheckTypeSize)
include (CheckCSourceCompiles)
include (CheckIncludeFiles)
include (CheckSymbolExists)
include (generate_version_info)
find_program(CTAGS ctags)
find_program(ETAGS etags)
#
# Platform checks
#
check_include_files ("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS)
check_include_files (stdio.h HAVE_STDIO_H)
check_include_files (stdlib.h HAVE_STDLIB_H)
check_include_files (unistd.h HAVE_UNISTD_H)
check_include_files (sys/ioctl.h HAVE_SYS_IOCTL_H)
check_include_files (sys/types.h HAVE_SYS_TYPES_H)
check_include_files (fcntl.h HAVE_FCNTL_H)
check_include_files (sys/stat.h HAVE_SYS_STAT_H)
check_include_files ("linux/ppdev.h;linux/parport.h" HAVE_LINUX_PPDEV_H)
check_include_files ("dev/ppbus/ppi.h;dev/ppbus/ppbconf.h" HAVE_DEV_PPBUS_PPI_H)
#
# Standard C Math Library
#
set (LIBM_TEST_SOURCE "#include<math.h>\nfloat f; int main(){sqrt(f);return
0;}")
check_c_source_compiles ("${LIBM_TEST_SOURCE}" HAVE_MATH)
if (HAVE_MATH)
set (LIBM_LIBRARIES)
else ()
set (CMAKE_REQUIRED_LIBRARIES m)
check_c_source_compiles ("${LIBM_TEST_SOURCE}" HAVE_LIBM_MATH)
unset (CMAKE_REQUIRED_LIBRARIES)
if (NOT HAVE_LIBM_MATH)
message (FATAL_ERROR "Unable to use C math library functions")
endif ()
set (LIBM_LIBRARIES m)
endif ()
#
# Boost
#
if (WIN32)
set (Boost_USE_STATIC_LIBS OFF)
endif ()
find_package (Boost 1.62 REQUIRED COMPONENTS log_setup log)
#
# OpenMP
#
find_package (OpenMP)
#
# fftw3 single precision library
#
find_package (FFTW3 COMPONENTS single threads REQUIRED)
#
# hamlib setup
#
find_package (Hamlib REQUIRED)
find_program (RIGCTL_EXE rigctl)
find_program (RIGCTLD_EXE rigctld)
find_program (RIGCTLCOM_EXE rigctlcom)
check_type_size (CACHE_ALL HAMLIB_OLD_CACHING)
check_symbol_exists (rig_set_cache_timeout_ms "hamlib/rig.h"
HAVE_HAMLIB_CACHING)
find_package (Usb REQUIRED)
#
# Qt5 setup
#
# Widgets finds its own dependencies.
find_package (Qt5 COMPONENTS Widgets SerialPort Multimedia PrintSupport Sql
LinguistTools REQUIRED)
if (WIN32)
add_definitions (-DQT_NEEDS_QTMAIN)
find_package (Qt5AxContainer REQUIRED)
endif (WIN32)
#
# Library building setup
#
include (GenerateExportHeader)
set (CMAKE_CXX_VISIBILITY_PRESET hidden)
set (CMAKE_C_VISIBILITY_PRESET hidden)
set (CMAKE_Fortran_VISIBILITY_PRESET hidden)
set (CMAKE_VISIBILITY_INLINES_HIDDEN ON)
#set (CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
#
# C & C++ setup
#
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -fexceptions
-frtti")
if (NOT APPLE)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-pragmas")
if (${OPENMP_FOUND})
if (OpenMP_C_FLAGS)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_C_FLAGS}")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
endif ()
endif ()
set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fdata-sections
-ffunction-sections")
set (CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} -fdata-sections
-ffunction-sections")
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fdata-sections
-ffunction-sections")
set (CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}
-fdata-sections -ffunction-sections")
endif (NOT APPLE)
if (WIN32)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
endif (WIN32)
if (APPLE AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
else ()
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=gnu++11 -pthread")
endif ()
#
# Fortran setup
#
set (General_FFLAGS "-Wall -Wno-conversion -fno-second-underscore")
# FFLAGS depend on the compiler
get_filename_component (Fortran_COMPILER_NAME ${CMAKE_Fortran_COMPILER} NAME)
if (Fortran_COMPILER_NAME MATCHES "gfortran.*")
# gfortran
# CMake compiler test is supposed to do this but doesn't yet
if (CMAKE_OSX_DEPLOYMENT_TARGET)
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}
-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
endif (CMAKE_OSX_DEPLOYMENT_TARGET)
if (CMAKE_OSX_SYSROOT)
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -isysroot
${CMAKE_OSX_SYSROOT}")
endif (CMAKE_OSX_SYSROOT)
set (CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}
-fbounds-check -funroll-all-loops -fno-f2c
-ffpe-summary=invalid,zero,overflow,underflow ${General_FFLAGS}")
### TEMPORARY: Let Fortran use RElEASE flags for DEBUG builds
#set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -g -fbacktrace
-fbounds-check -fno-f2c -ffpe-summary=invalid,zero,overflow,underflow
${General_FFLAGS}")
set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_RELEASE} -fbounds-check
-funroll-all-loops -fno-f2c -ffpe-summary=invalid,zero,overflow,underflow
${General_FFLAGS}")
# FPE traps currently disabled in Debug configuration builds until
# we decide if they are meaningful, without these FP instructions
# run in nonstop mode and do not trap
#set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG}
${CMAKE_Fortran_FLAGS_DEBUG} -ffpe-trap=invalid,zero,overflow")
elseif (Fortran_COMPILER_NAME MATCHES "ifort.*")
# ifort (untested)
set (CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -f77rtl
${General_FFLAGS}")
set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -f77rtl
${General_FFLAGS}")
elseif (Fortran_COMPILER_NAME MATCHES "g77")
# g77
set (CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE}
-funroll-all-loops -fno-f2c -m32 ${General_FFLAGS}")
set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fbounds-check
-fno-f2c -m32 ${General_FFLAGS}")
else (Fortran_COMPILER_NAME MATCHES "gfortran.*")
message ("CMAKE_Fortran_COMPILER full path: " ${CMAKE_Fortran_COMPILER})
message ("Fortran compiler: " ${Fortran_COMPILER_NAME})
message ("No optimized Fortran compiler flags are known, we just try -O3...")
set (CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -O3
${General_FFLAGS}")
set (CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fbounds-check
${General_FFLAGS}")
endif (Fortran_COMPILER_NAME MATCHES "gfortran.*")
#
# Linker setup
#
if (NOT APPLE)
set (CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}
-Wl,--gc-sections")
set (CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL}
-Wl,--gc-sections")
endif (NOT APPLE)
#
# setup and test Fortran C/C++ interaction
#
include (FortranCInterface)
FortranCInterface_VERIFY (CXX)
FortranCInterface_HEADER (FC.h MACRO_NAMESPACE "FC_" SYMBOL_NAMESPACE "FC_"
SYMBOLS
grayline
)
#
# sort out pre-requisites
#
#
# Setup RPATH so that built executable targets will run in both the
# build tree and the install location without having to set a
# (DYLD|LD)_LIBRARY_PATH override.
#
# use the full RPATH of the build tree
set (CMAKE_SKIP_BUILD_RPATH FALSE)
# when building, don't use the install RPATH, it will still be used
# later on in the install phase
set (CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
# set (CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
# add the automaticaly determined parts of the RPATH which point to
# directories outside of the build tree to the install RPATH
set (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# the RPATH to be used when installing, but only if it's not a system
# directory
# list (FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" isSystemDir)
# if ("${isSystemDir}" STREQUAL "-1")
# set (CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
# endif ("${isSystemDir}" STREQUAL "-1")
set (QT_NEED_RPATH FALSE)
if (NOT "${QT_LIBRARY_DIR}" STREQUAL "/lib" AND NOT "${QT_LIBRARY_DIR}"
STREQUAL "/usr/lib" AND NOT "${QT_LIBRARY_DIR}" STREQUAL "/lib64" AND NOT
"${QT_LIBRARY_DIR}" STREQUAL "/usr/lib64")
set (QT_NEED_RPATH TRUE)
endif ()
#
# stuff only qmake can tell us
#
get_target_property (QMAKE_EXECUTABLE Qt5::qmake LOCATION)
get_target_property (LCONVERT_EXECUTABLE Qt5::lconvert LOCATION)
function (QUERY_QMAKE VAR RESULT)
exec_program (${QMAKE_EXECUTABLE} ARGS "-query ${VAR}" RETURN_VALUE
return_code OUTPUT_VARIABLE output)
if (NOT return_code)
file (TO_CMAKE_PATH "${output}" output)
set (${RESULT} ${output} PARENT_SCOPE)
endif (NOT return_code)
message (STATUS "Asking qmake for ${RESULT} and got ${output}")
endfunction (QUERY_QMAKE)
query_qmake (QT_INSTALL_PLUGINS QT_PLUGINS_DIR)
query_qmake (QT_INSTALL_TRANSLATIONS QT_TRANSLATIONS_DIR)
query_qmake (QT_INSTALL_IMPORTS QT_IMPORTS_DIR)
query_qmake (QT_HOST_DATA QT_DATA_DIR)
set (QT_MKSPECS_DIR ${QT_DATA_DIR}/mkspecs)
# project definitions
add_definitions (-DQT5 -DCMAKE_BUILD -DBIGSYM=1 -DBOOST_ALL_DYN_LINK)
if (CMAKE_HOST_UNIX)
add_definitions (-DUNIX)
elseif (CMAKE_HOST_WIN32)
add_definitions (-DWIN32)
endif ()
#
# sub-directories
#
if (EXISTS ${CMAKE_SOURCE_DIR}/samples AND IS_DIRECTORY
${CMAKE_SOURCE_DIR}/samples)
add_subdirectory (samples)
endif ()
if (WSJT_GENERATE_DOCS)
add_subdirectory (doc)
endif (WSJT_GENERATE_DOCS)
if (EXISTS ${CMAKE_SOURCE_DIR}/tests AND IS_DIRECTORY ${CMAKE_SOURCE_DIR}/tests)
add_subdirectory (tests)
endif ()
# build a library of package functionality (without and optionally with OpenMP
support)
add_library (wsjt_cxx STATIC ${wsjt_CSRCS} ${wsjt_CXXSRCS})
target_link_libraries (wsjt_cxx ${LIBM_LIBRARIES} Boost::log_setup
${LIBM_LIBRARIES})
# build an OpenMP variant of the Fortran library routines
add_library (wsjt_fort STATIC ${wsjt_FSRCS})
target_link_libraries (wsjt_fort ${FFTW3_LIBRARIES})
if (${OPENMP_FOUND} OR APPLE)
add_library (wsjt_fort_omp STATIC ${wsjt_FSRCS})
target_link_libraries (wsjt_fort_omp ${FFTW3_LIBRARIES})
if (OpenMP_C_FLAGS AND NOT APPLE)
set_target_properties (wsjt_fort_omp
PROPERTIES
COMPILE_FLAGS "${OpenMP_C_FLAGS}"
)
endif ()
set_target_properties (wsjt_fort_omp
PROPERTIES
Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp
)
file (MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp)
if (APPLE)
# On Mac we don't have working OpenMP support in the C/C++
# compilers so we have to manually set the correct flags to get
# OpenMP support in jt9.
target_compile_options (wsjt_fort_omp
PRIVATE
$<$<COMPILE_LANGUAGE:Fortran>:-fopenmp> # assumes GNU style Fortran
compiler
)
endif (APPLE)
endif (${OPENMP_FOUND} OR APPLE)
if(WSJT_BUILD_UTILS)
add_executable (jt4sim lib/jt4sim.f90)
target_link_libraries (jt4sim wsjt_fort wsjt_cxx)
add_executable (jt65sim lib/jt65sim.f90)
target_link_libraries (jt65sim wsjt_fort wsjt_cxx)
add_executable (sumsim lib/sumsim.f90)
target_link_libraries (sumsim wsjt_fort wsjt_cxx)
add_executable (cablog lib/cablog.f90)
target_link_libraries (cablog)
add_executable (test_snr lib/test_snr.f90)
target_link_libraries (test_snr wsjt_fort)
add_executable (q65sim lib/qra/q65/q65sim.f90)
target_link_libraries (q65sim wsjt_fort wsjt_cxx)
add_executable (q65code lib/qra/q65/q65code.f90)
target_link_libraries (q65code wsjt_fort wsjt_cxx)
add_executable (test_q65 lib/test_q65.f90)
target_link_libraries (test_q65 wsjt_fort wsjt_cxx)
add_executable (q65_ftn_test lib/qra/q65/q65_ftn_test.f90)
target_link_libraries (q65_ftn_test wsjt_fort wsjt_cxx)
add_executable (jt49sim lib/jt49sim.f90)
target_link_libraries (jt49sim wsjt_fort wsjt_cxx)
#add_executable (allsim lib/allsim.f90)
#target_link_libraries (allsim wsjt_fort wsjt_cxx)
add_executable (rtty_spec lib/rtty_spec.f90)
target_link_libraries (rtty_spec wsjt_fort wsjt_cxx)
add_executable (jt65code lib/jt65code.f90)
target_link_libraries (jt65code wsjt_fort wsjt_cxx)
add_executable (jt9code lib/jt9code.f90)
target_link_libraries (jt9code wsjt_fort wsjt_cxx)
add_executable (wsprcode lib/wsprcode/wsprcode.f90 lib/wsprcode/nhash.c)
target_link_libraries (wsprcode wsjt_fort wsjt_cxx)
add_executable (encode77 lib/77bit/encode77.f90)
target_link_libraries (encode77 wsjt_fort wsjt_cxx)
add_executable (hash22calc lib/77bit/hash22calc.f90)
target_link_libraries (hash22calc wsjt_fort wsjt_cxx)
add_executable (wsprsim ${wsprsim_CSRCS})
target_link_libraries (wsprsim ${LIBM_LIBRARIES})
add_executable (jt4code lib/jt4code.f90)
target_link_libraries (jt4code wsjt_fort wsjt_cxx)
add_executable (msk144code lib/msk144code.f90)
target_link_libraries (msk144code wsjt_fort wsjt_cxx)
add_executable (ft8code lib/ft8/ft8code.f90)
target_link_libraries (ft8code wsjt_fort wsjt_cxx)
add_executable (ft4code lib/ft4/ft4code.f90)
target_link_libraries (ft4code wsjt_fort wsjt_cxx)
add_executable (echosim lib/echosim.f90)
target_link_libraries (echosim wsjt_fort wsjt_cxx)
add_executable (ft8sim lib/ft8/ft8sim.f90)
target_link_libraries (ft8sim wsjt_fort wsjt_cxx)
add_executable (msk144sim lib/msk144sim.f90)
target_link_libraries (msk144sim wsjt_fort wsjt_cxx)
add_executable (ft4sim lib/ft4/ft4sim.f90)
target_link_libraries (ft4sim wsjt_fort wsjt_cxx)
add_executable (ft4sim_mult lib/ft4/ft4sim_mult.f90)
target_link_libraries (ft4sim_mult wsjt_fort wsjt_cxx)
add_executable (fst4sim lib/fst4/fst4sim.f90)
target_link_libraries (fst4sim wsjt_fort wsjt_cxx)
if (WIN32)
set_target_properties (fst4sim PROPERTIES
LINK_FLAGS -Wl,--stack,0x4000000,--heap,0x6000000
)
endif ()
add_executable (ldpcsim240_101 lib/fst4/ldpcsim240_101.f90)
target_link_libraries (ldpcsim240_101 wsjt_fort wsjt_cxx)
add_executable (ldpcsim240_74 lib/fst4/ldpcsim240_74.f90)
target_link_libraries (ldpcsim240_74 wsjt_fort wsjt_cxx)
endif(WSJT_BUILD_UTILS)
add_executable (fmtave lib/fmtave.f90)
add_executable (fcal lib/fcal.f90)
add_executable (fmeasure lib/fmeasure.f90)
# build the wsprd WSPR mode decoder driver
generate_version_info (wsprd_VERSION_RESOURCES
NAME wsprd
BUNDLE ${PROJECT_BUNDLE_NAME}
ICON ${WSJTX_ICON_FILE}
FILE_DESCRIPTION "WSPR mode decoder"
)
add_executable (wsprd ${wsprd_CSRCS} lib/indexx.f90 lib/wsprd/osdwspr.f90
${wsprd_VERSION_RESOURCES})
target_include_directories (wsprd PRIVATE ${FFTW3_INCLUDE_DIRS})
target_link_libraries (wsprd ${FFTW3_LIBRARIES} ${LIBM_LIBRARIES})
# Tell CMake to run moc when necessary
set (CMAKE_AUTOMOC ON)
include_directories (${CMAKE_CURRENT_BINARY_DIR})
# don't use Qt "keywords" signal, slot, emit in generated files to
# avoid compatability issue with other libraries
# ADD_DEFINITIONS (-DQT_NO_KEYWORDS)
# ADD_DEFINITIONS (-DUNICODE) #as per qmake
# As moc files are generated in the binary dir, tell CMake to always
# look for includes there:
set (CMAKE_INCLUDE_CURRENT_DIR ON)
#
# source navigation
#
set (sources
${CMAKE_SOURCE_DIR}/*
${CMAKE_SOURCE_DIR}/logbook/*
${CMAKE_SOURCE_DIR}/lib/*
)
add_custom_target (ctags COMMAND ${CTAGS} -o ${CMAKE_SOURCE_DIR}/tags -R
${sources})
add_custom_target (etags COMMAND ${ETAGS} -o ${CMAKE_SOURCE_DIR}/TAGS -R
${sources})
# Qt i18n - always include the country generic if any regional variant is
included
set (LANGUAGES
ca # Catalan
da # Danish
en # English (we need this to stop
# translation loaders loading the
# second preference UI languge, it
# doesn't need to be populated)
en_GB # English UK
es # Spanish
it # Italian
ja # Japanese
#no # Norwegian
#pt # Portuguese
ru # Russian
#sv # Swedish
zh # Chinese
zh_HK # Chinese per Hong Kong
zh_TW # Chinese traditional
it # Italian
)
foreach (lang_ ${LANGUAGES})
file (TO_NATIVE_PATH ${CMAKE_SOURCE_DIR}/translations/wsjtx_${lang_}.ts ts_)
list (APPEND TS_FILES ${ts_})
set (qt_translations_ "${QT_TRANSLATIONS_DIR}/qtbase_${lang_}.qm")
if (EXISTS "${qt_translations_}")
add_custom_command (
OUTPUT "${CMAKE_BINARY_DIR}/qt_${lang_}.qm"
COMMAND ${LCONVERT_EXECUTABLE} -o "${CMAKE_BINARY_DIR}/qt_${lang_}.qm"
${qt_translations_}
COMMENT "Building required Qt translations for language ${lang_}"
)
list (APPEND QM_FILES "${CMAKE_BINARY_DIR}/qt_${lang_}.qm")
endif ()
endforeach ()
if (UPDATE_TRANSLATIONS)
message (STATUS "UPDATE_TRANSLATIONS option is set.")
qt5_create_translation (
QM_FILES ${wsjt_qt_UISRCS} ${wsjtx_UISRCS} ${wsjt_qt_CXXSRCS}
${wsjtx_CXXSRCS}
${TS_FILES}
OPTIONS -I${CMAKE_CURRENT_SOURCE_DIR}
)
else ()
qt5_add_translation (QM_FILES ${TS_FILES})
endif ()
add_custom_target (translations DEPENDS ${QM_FILES})
set_property (DIRECTORY PROPERTY CLEAN_NO_CUSTOM TRUE)
# embedded resources
function (add_resources resources path)
foreach (resource_file_ ${ARGN})
get_filename_component (name_ ${resource_file_} NAME)
if (IS_ABSOLUTE "${resource_file_}")
file (TO_NATIVE_PATH ${resource_file_} source_)
else ()
file (TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${resource_file_}
source_)
endif ()
file (TO_NATIVE_PATH ${path}/${name_} dest_)
set (resources_ "${resources_}\n <file
alias=\"${dest_}\">${source_}</file>")
set (${resources} ${${resources}}${resources_} PARENT_SCOPE)
endforeach (resource_file_ ${ARGN})
endfunction (add_resources resources path)
add_resources (wsjtx_RESOURCES "" ${TOP_LEVEL_RESOURCES})
add_resources (wsjtx_RESOURCES /Palettes ${PALETTE_FILES})
add_resources (wsjtx_RESOURCES /Translations ${QM_FILES})
configure_file (wsjtx.qrc.in wsjtx.qrc @ONLY)
# UI generation
qt5_wrap_ui (wsjt_qt_GENUISRCS ${wsjt_qt_UISRCS})
qt5_wrap_ui (wsjtx_GENUISRCS ${wsjtx_UISRCS})
# Resource generation
qt5_add_resources (wsjtx_RESOURCES_RCC
${CMAKE_BINARY_DIR}/wsjtx.qrc
contrib/QDarkStyleSheet/qdarkstyle/style.qrc
)
# AX COM servers
if (WIN32)
include (QtAxMacros)
wrap_ax_server (GENAXSRCS ${AXSERVERSRCS})
endif (WIN32)
#
# targets dependent on Qt
#
# build a library for the QCustomPlot widget
add_library (qcp STATIC ${qcp_CXXSRCS})
target_include_directories (qcp PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/qcustomplot-source>)
target_link_libraries (qcp Qt5::Widgets Qt5::PrintSupport)
# build a library of package Qt functionality
add_library (wsjt_qt STATIC ${wsjt_qt_CXXSRCS} ${wsjt_qt_GENUISRCS}
${GENAXSRCS})
# set wsjtx_udp exports to static variants
target_compile_definitions (wsjt_qt PUBLIC UDP_STATIC_DEFINE)
target_link_libraries (wsjt_qt Hamlib::Hamlib Boost::log qcp Qt5::Widgets
Qt5::Network Qt5::Sql)
if (WIN32)
target_link_libraries (wsjt_qt Qt5::AxContainer Qt5::AxBase)
endif (WIN32)
# build a library of package Qt functionality used in Fortran utilities
add_library (fort_qt STATIC ${fort_qt_CXXSRCS})
target_link_libraries (fort_qt Qt5::Core)
# build a library of WSJT Qt multimedia components
add_library (wsjt_qtmm STATIC ${wsjt_qtmm_CXXSRCS} ${wsjt_qtmm_GENUISRCS})
target_link_libraries (wsjt_qtmm Qt5::Multimedia)
# build the jt9 slow mode decoder driver
generate_version_info (jt9_VERSION_RESOURCES
NAME jt9
BUNDLE ${PROJECT_BUNDLE_NAME}
ICON ${WSJTX_ICON_FILE}
FILE_DESCRIPTION "jt9 - WSJT-X slow mode decoder"
)
add_executable (record_time_signal Audio/tools/record_time_signal.cpp)
target_link_libraries (record_time_signal wsjt_cxx wsjt_qtmm wsjt_qt)
add_executable (jt9 ${jt9_FSRCS} ${jt9_VERSION_RESOURCES})
if (${OPENMP_FOUND} OR APPLE)
if (APPLE)
# On Mac we don't have working OpenMP support in the C/C++
# compilers so we have to manually set the correct linking flags
# and libraries to get OpenMP support in jt9.
set_target_properties (jt9
PROPERTIES
Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp
LINK_LIBRARIES "gomp;gcc_s.1" # assume GNU libgcc OpenMP
)
target_compile_options (jt9
PRIVATE
$<$<COMPILE_LANGUAGE:Fortran>:-fopenmp> # assumes GNU style Fortran
compiler
)
else (APPLE)
if (OpenMP_C_FLAGS)
set_target_properties (jt9
PROPERTIES
COMPILE_FLAGS "${OpenMP_C_FLAGS}"
LINK_FLAGS "${OpenMP_C_FLAGS}"
)
endif ()
set_target_properties (jt9
PROPERTIES
Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp
)
endif (APPLE)
if (WIN32)
set_target_properties (jt9 PROPERTIES
LINK_FLAGS -Wl,--stack,16777216
)
endif ()
target_link_libraries (jt9 wsjt_fort_omp wsjt_cxx fort_qt)
else (${OPENMP_FOUND} OR APPLE)
target_link_libraries (jt9 wsjt_fort wsjt_cxx fort_qt)
endif (${OPENMP_FOUND} OR APPLE)
if (WIN32)
find_package (Portaudio REQUIRED)
add_subdirectory (map65)
endif ()
add_subdirectory (qmap)
# build the main application
generate_version_info (wsjtx_VERSION_RESOURCES
NAME wsjtx
BUNDLE ${PROJECT_BUNDLE_NAME}
ICON ${WSJTX_ICON_FILE}
)
add_executable (wsjtx MACOSX_BUNDLE
${wsjtx_CXXSRCS}
${wsjtx_GENUISRCS}
${WSJTX_ICON_FILE}
${wsjtx_RESOURCES_RCC}
${wsjtx_VERSION_RESOURCES}
)
if (WSJT_CREATE_WINMAIN)
set_target_properties (wsjtx PROPERTIES WIN32_EXECUTABLE ON)
endif (WSJT_CREATE_WINMAIN)
set_target_properties (wsjtx PROPERTIES
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Darwin/Info.plist.in"
MACOSX_BUNDLE_INFO_STRING "${PROJECT_DESCRIPTION}"
MACOSX_BUNDLE_ICON_FILE "${WSJTX_ICON_FILE}"
MACOSX_BUNDLE_BUNDLE_VERSION
${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}
MACOSX_BUNDLE_SHORT_VERSION_STRING
"v${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}"
MACOSX_BUNDLE_LONG_VERSION_STRING "Version
${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${SCS_VERSION_STR}"
MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_BUNDLE_NAME}"
MACOSX_BUNDLE_BUNDLE_EXECUTABLE_NAME "${PROJECT_NAME}"
MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT}"
MACOSX_BUNDLE_GUI_IDENTIFIER "org.k1jt.wsjtx"
)
target_include_directories (wsjtx PRIVATE ${FFTW3_INCLUDE_DIRS})
if ((NOT ${OPENMP_FOUND}) OR APPLE)
target_link_libraries (wsjtx wsjt_fort)
else ()
target_link_libraries (wsjtx wsjt_fort_omp)
if (OpenMP_C_FLAGS)
set_target_properties (wsjtx PROPERTIES
COMPILE_FLAGS "${OpenMP_C_FLAGS}"
LINK_FLAGS "${OpenMP_C_FLAGS}"
)
endif ()
set_target_properties (wsjtx PROPERTIES
Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/fortran_modules_omp
)
if (WIN32)
set_target_properties (wsjtx PROPERTIES
LINK_FLAGS -Wl,--stack,0x1000000,--heap,0x20000000
)
endif ()
endif ()
target_link_libraries (wsjtx Qt5::SerialPort wsjt_cxx wsjt_qt wsjt_qtmm
${FFTW3_LIBRARIES} ${LIBM_LIBRARIES})
# make a library for WSJT-X UDP servers
# add_library (wsjtx_udp SHARED ${UDP_library_CXXSRCS})
add_library (wsjtx_udp-static STATIC ${UDP_library_CXXSRCS})
#target_include_directories (wsjtx_udp
# INTERFACE
# $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/wsjtx>
# )
target_include_directories (wsjtx_udp-static
INTERFACE
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/wsjtx>
)
#set_target_properties (wsjtx_udp PROPERTIES
# PUBLIC_HEADER "${UDP_library_HEADERS}"
# )
set_target_properties (wsjtx_udp-static PROPERTIES
OUTPUT_NAME wsjtx_udp
)
target_compile_definitions (wsjtx_udp-static PUBLIC UDP_STATIC_DEFINE)
target_link_libraries (wsjtx_udp-static Qt5::Network Qt5::Gui)
generate_export_header (wsjtx_udp-static BASE_NAME udp)
generate_version_info (udp_daemon_VERSION_RESOURCES
NAME udp_daemon
BUNDLE ${PROJECT_BUNDLE_NAME}
ICON ${WSJTX_ICON_FILE}
FILE_DESCRIPTION "Example WSJT-X UDP Message Protocol daemon"
)
add_executable (udp_daemon UDPExamples/UDPDaemon.cpp
${udp_daemon_VERSION_RESOURCES})
target_link_libraries (udp_daemon wsjtx_udp-static)
generate_version_info (wsjtx_app_version_VERSION_RESOURCES
NAME wsjtx_app_version
BUNDLE ${PROJECT_BUNDLE_NAME}
ICON ${WSJTX_ICON_FILE}
FILE_DESCRIPTION "Display WSJT-X Application Version on console"
)
add_executable (wsjtx_app_version AppVersion/AppVersion.cpp
${wsjtx_app_version_VERSION_RESOURCES})
target_link_libraries (wsjtx_app_version wsjt_qt)
generate_version_info (message_aggregator_VERSION_RESOURCES
NAME message_aggregator
BUNDLE ${PROJECT_BUNDLE_NAME}
ICON ${WSJTX_ICON_FILE}
FILE_DESCRIPTION "Example WSJT-X UDP Message Protocol application"
)
add_resources (message_aggregator_RESOURCES /qss
${message_aggregator_STYLESHEETS})
configure_file (UDPExamples/message_aggregator.qrc.in message_aggregator.qrc
@ONLY)
qt5_add_resources (message_aggregator_RESOURCES_RCC
${CMAKE_CURRENT_BINARY_DIR}/message_aggregator.qrc
contrib/QDarkStyleSheet/qdarkstyle/style.qrc
)
add_executable (message_aggregator
${message_aggregator_CXXSRCS}
${message_aggregator_RESOURCES_RCC}
${message_aggregator_VERSION_RESOURCES}
)
target_link_libraries (message_aggregator wsjt_qt Qt5::Widgets wsjtx_udp-static)
if (WSJT_CREATE_WINMAIN)
set_target_properties (message_aggregator PROPERTIES WIN32_EXECUTABLE ON)
endif (WSJT_CREATE_WINMAIN)
if (UNIX)
if (NOT WSJT_SKIP_MANPAGES)
add_subdirectory (manpages)
add_dependencies (wsjtx manpages)
endif (NOT WSJT_SKIP_MANPAGES)
if (NOT APPLE)
add_subdirectory (debian)
add_dependencies (wsjtx debian)
endif (NOT APPLE)
endif (UNIX)
#
# installation
#
install (TARGETS wsjtx
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION . COMPONENT runtime
)
# install (TARGETS wsjtx_udp EXPORT udp
# RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
# LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
# ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
# PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/wsjtx
# )
# install (TARGETS wsjtx_udp-static EXPORT udp-static
# DESTINATION ${CMAKE_INSTALL_LIBDIR}
# )
# install (EXPORT udp NAMESPACE wsjtx::
# DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wsjtx
# )
# install (EXPORT udp-static NAMESPACE wsjtx::
# DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wsjtx
# )
install (TARGETS udp_daemon message_aggregator wsjtx_app_version
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
)
install (TARGETS jt9 wsprd fmtave fcal fmeasure
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
)
if(WSJT_BUILD_UTILS)
install (TARGETS ft8code jt65code jt9code jt4code msk144code
q65code fst4sim q65sim echosim hash22calc cablog
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime
)
endif(WSJT_BUILD_UTILS)
install (PROGRAMS
${RIGCTL_EXE}
DESTINATION ${CMAKE_INSTALL_BINDIR}
#COMPONENT runtime
RENAME rigctl-wsjtx${CMAKE_EXECUTABLE_SUFFIX}
)
install (PROGRAMS
${RIGCTLD_EXE}
DESTINATION ${CMAKE_INSTALL_BINDIR}
#COMPONENT runtime
RENAME rigctld-wsjtx${CMAKE_EXECUTABLE_SUFFIX}
)
install (PROGRAMS
${RIGCTLCOM_EXE}
DESTINATION ${CMAKE_INSTALL_BINDIR}
#COMPONENT runtime
RENAME rigctlcom-wsjtx${CMAKE_EXECUTABLE_SUFFIX}
)
install (FILES
README
COPYING
AUTHORS
THANKS
NEWS
BUGS
DESTINATION ${CMAKE_INSTALL_DOCDIR}
#COMPONENT runtime
)
install (FILES
cty.dat
cty.dat_copyright.txt
contrib/Ephemeris/JPLEPH
eclipse.txt
DESTINATION ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}
#COMPONENT runtime
)
install (DIRECTORY
example_log_configurations
DESTINATION ${CMAKE_INSTALL_DOCDIR}
FILES_MATCHING REGEX "^.*[^~]$"
#COMPONENT runtime
)
#
# Mac installer files
#
if (APPLE)
install (FILES
Darwin/ReadMe.txt
Darwin/com.wsjtx.sysctl.plist
DESTINATION .
#COMPONENT runtime
)
endif (APPLE)
#
# uninstall support
#
configure_file (
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
@ONLY)
add_custom_target (uninstall
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
# creates or updates ${PROJECT_BINARY_DIR}/scs_version.h using cmake script
add_custom_target (revisiontag
COMMAND ${CMAKE_COMMAND}
-D SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-D BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
-D OUTPUT_DIR=${PROJECT_BINARY_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/CMake/getsvn.cmake
VERBATIM
BYPRODUCTS scs_version.h
COMMENT "Getting source control system revision information"
)
# explicitly say that the wsjt_qt depends on custom target, this is
# done indirectly so that the revisiontag target gets built exactly
# once per build
add_dependencies (wsjt_qt revisiontag)
add_dependencies (jt9 revisiontag)
add_dependencies (wsprd revisiontag)
#
# versioning and configuration
#
configure_file (
"${CMAKE_CURRENT_SOURCE_DIR}/wsjtx_config.h.in"
"${CMAKE_CURRENT_BINARY_DIR}/wsjtx_config.h"
)
if (NOT WIN32 AND NOT APPLE)
# install a desktop file so wsjtx appears in the application start
# menu with an icon
install (
FILES wsjtx.desktop message_aggregator.desktop
DESTINATION share/applications
#COMPONENT runtime
)
install (
FILES icons/Unix/wsjtx_icon.png
DESTINATION share/pixmaps
#COMPONENT runtime
)
endif (NOT WIN32 AND NOT APPLE)
if (APPLE)
set (CMAKE_POSTFLIGHT_SCRIPT
"${wsjtx_BINARY_DIR}/postflight.sh")
set (CMAKE_POSTUPGRADE_SCRIPT
"${wsjtx_BINARY_DIR}/postupgrade.sh")
configure_file ("${wsjtx_SOURCE_DIR}/Darwin/postflight.sh.in"
"${CMAKE_POSTFLIGHT_SCRIPT}")
configure_file ("${wsjtx_SOURCE_DIR}/Darwin/postupgrade.sh.in"
"${CMAKE_POSTUPGRADE_SCRIPT}")
endif ()
#
# bundle fixup only done in non-Debug configurations
#
if (NOT is_debug_build)
# add this sub-sirectory after all install steps and other
# sub-directories to ensure that all executables are in-place before
# any fixup is done
add_subdirectory (bundle_fixup)
endif ()
#
# packaging
#
set (CPACK_PACKAGE_DESCRIPTION_FILE
"${CMAKE_SOURCE_DIR}/package_description.txt")
set (CPACK_MONOLITHIC_INSTALL 1)
set (CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
set (CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set (CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set (CPACK_PACKAGE_VERSION_PATCH
"${PROJECT_VERSION_PATCH}${BUILD_TYPE_REVISION}")
if (WIN32)
set (CPACK_GENERATOR "NSIS")
elseif (APPLE)
set (CPACK_GENERATOR "DragNDrop")
else ()
find_program (DPKG_BUILDER dpkg-buildpackage DOC "Debian package builder")
if (DPKG_BUILDER)
#
# Derive the correct filename for a Debian package because the DEB
# generator doesn't do this correctly at present.
#
find_program (DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems")
if (DPKG_PROGRAM)
execute_process (
COMMAND ${DPKG_PROGRAM} --print-architecture
OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE
OUTPUT_STRIP_TRAILING_WHITESPACE
)
else (DPKG_PROGRAM)
set (CPACK_DEBIAN_PACKAGE_ARCHITECTURE noarch)
endif (DPKG_PROGRAM)
list (APPEND CPACK_GENERATOR "DEB")
endif (DPKG_BUILDER)
find_program (RPMBUILDER rpmbuild DOC "RPM package builder")
if (RPMBUILDER)
list (APPEND CPACK_GENERATOR "RPM")
endif (RPMBUILDER)
endif ()
set (CPACK_DEBIAN_PACKAGE_HOMEPAGE "${PROJECT_HOMEPAGE}")
set (CPACK_DEBIAN_PACKAGE_DEPENDS "libgfortran5 (>=8.3) | libgfortran4 (>=7.3)
| libgfortran3 (>=6.3), libfftw3-single3 (>=3.3), libgomp1 (>=6),
libqt5serialport5 (>=5.7), libqt5multimedia5-plugins (>=5.7), libqt5widgets5
(>=5.7), libqt5network5 (>=5.7), libqt5printsupport5 (>=5.7), libqt5sql5-sqlite
(>=5.7), libusb-1.0-0 (>=1.0.21), libboost-log1.62.0 (>=1.62.0) |
libboost-log1.65.1 (>=1.65.1) | libboost-log1.67.0 (>=1.67.0) |
libboost-log1.71.0 (>=1.71.0) | libboost-log1.74.0 (>=1.74.0)")
set (CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
set (CPACK_RPM_PACKAGE_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
set (CPACK_RPM_PACKAGE_REQUIRES "qt5-qtbase >= 5.9, qt5-qtserialport >= 5.9,
qt5-qtmultimedia >= 5.9, qt5-qtsvg >= 5.9, libusbx >= 1.0.22, libgfortran >= 7,
libgomp >= 7, fftw-libs-single >= 3.3, boost-log >= 1.62")
set (CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /usr/share/pixmaps
/usr/share/applications /usr/share/man /usr/share/man1)
configure_file ("${PROJECT_SOURCE_DIR}/CMakeCPackOptions.cmake.in"
"${PROJECT_BINARY_DIR}/CMakeCPackOptions.cmake" @ONLY)
set (CPACK_PROJECT_CONFIG_FILE "${PROJECT_BINARY_DIR}/CMakeCPackOptions.cmake")
include (CPack)
_______________________________________________
wsjt-devel mailing list
wsjt-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wsjt-devel