me simulation adhoc network by station lte,my code and error is as follows
Mac/802_11Ext set CWMin_ 15
Mac/802_11Ext set CWMax_ 1023
Mac/802_11Ext set SlotTime_ 0.000009
Mac/802_11Ext set SIFS_ 0.000016
Mac/802_11Ext set ShortRetryLimit_ 7
Mac/802_11Ext set LongRetryLimit_ 4
Mac/802_11Ext set HeaderDuration_ 0.000020
Mac/802_11Ext set SymbolDuration_ 0.000004
Mac/802_11Ext set BasicModulationScheme_ 0
Mac/802_11Ext set use_802_11a_flag_ true
Mac/802_11Ext set RTSThreshold_ 2000
Mac/802_11Ext set MAC_DBG 0
#=====================================================================
Phy/WirelessPhyExt set CSThresh_ 6.30957e-12
Phy/WirelessPhyExt set Pt_ 0.001
Phy/WirelessPhyExt set freq_ 5.18e9
Phy/WirelessPhyExt set noise_floor_ 2.51189e-13
Phy/WirelessPhyExt set L_ 1.0
Phy/WirelessPhyExt set PowerMonitorThresh_ 2.10319e-12
Phy/WirelessPhyExt set HeaderDuration_ 0.000020
Phy/WirelessPhyExt set BasicModulationScheme_ 0
Phy/WirelessPhyExt set PreambleCaptureSwitch_ 1
Phy/WirelessPhyExt set DataCaptureSwitch_ 0
Phy/WirelessPhyExt set SINR_PreambleCapture_ 2.5118
Phy/WirelessPhyExt set SINR_DataCapture_ 100.0
Phy/WirelessPhyExt set trace_dist_ 1e6
Phy/WirelessPhyExt set PHY_DBG_ 0
Phy/WirelessPhyExt set CPThresh_ 0 ;# not used at the moment
Phy/WirelessPhyExt set RXThresh_ 0 ;# not used at the moment
#=====================================================================
#configure RF model parameters
Antenna/OmniAntenna set Gt_ 1.0
Antenna/OmniAntenna set Gr_ 1.0
Propagation/Nakagami set use_nakagami_dist_ false
Propagation/Nakagami set gamma0_ 2.0
Propagation/Nakagami set gamma1_ 2.0
Propagation/Nakagami set gamma2_ 2.0
Propagation/Nakagami set d0_gamma_ 200
Propagation/Nakagami set d1_gamma_ 500
Propagation/Nakagami set m0_ 1.0
Propagation/Nakagami set m1_ 1.0
Propagation/Nakagami set m2_ 1.0
Propagation/Nakagami set d0_m_ 80
Propagation/Nakagami set d1_m_ 200
set opt(namfile) out.nam
set opt(tracefile) out.tr
set val(chan) Channel/WirelessChannel; #channel type
set val(prop) Propagation/Nakagami; #radio-propagation model
set val(netif) Phy/WirelessPhyExt; #network interface type
set val(mac) Mac/802_11Ext; #MAC type
set val(ifq) Queue/LTEQueue/ULAirQueue; #interface queue type
set val(ifqlen) 100; #max nbr of packets in ifq
set val(ll) LL; #link layer type
set val(ant) Antenna/OmniAntenna; #antenna type
set val(adhocRP) AODV; #routing protocol
set val(x) 1903; #x dimension of the topography
set val(y) 882; #y dimension of the topography
set val(stop) 3607.0; #simulation time
set val(mobility) "mobility.tcl"
set val(start) 1
set val(stop) 3607.0
set val(nn) 38
set val(eNB) 1
#set val(gw_discovery) reactive; #gateway discovery method
#---------------------------
#Initialize Global Variables
#---------------------------
#create a simulator object
set ns_ [new Simulator]
$ns_ color 0 Brown
#----------------------------------------
#Define The Hierachial Topology Structure
#----------------------------------------
$ns_ node-config -addressType hierarchical
AddrParams set domain_num_ 2
lappend clusterNbr 2 2
AddrParams set cluster_num_ $clusterNbr
lappend eilastlevel 2 2 [expr $val(nn)/2+1] [expr $val(nn)/2-5]
AddrParams set nodes_num_ $eilastlevel
#create trace objects for ns and nam
$ns_ use-newtrace
set nstrace [open $opt(tracefile) w]
$ns_ trace-all $nstrace
set namtrace [open $opt(namfile) w]
$ns_ namtrace-all-wireless $namtrace $val(x) $val(y)
#--------------------------------------------------------
#create a topology object and define topology
#--------------------------------------------------------
set topo [new Topography]
$topo load_flatgrid $val(x) $val(y)
#--------------------------------------------------------
# Create GOD
#--------------------------------------------------------
set god [create-god [expr $val(nn)+$val(eNB)]]
set aGW [$ns_ node 0.0.0]
set server [$ns_ node 0.0.1]
#Use hierarchical addresses for GWs and MNs
set chan1 [new $val(chan)]
#configure for gateway
$ns_ node-config -adhocRouting $val(adhocRP) \
-llType $val(ll) \
-macType $val(mac) \
-ifqType $val(ifq) \
-ifqLen $val(ifqlen) \
-antType $val(ant) \
-propType $val(prop) \
-phyType $val(netif) \
-topoInstance $topo \
-channel $chan1 \
-agentTrace ON \
-routerTrace ON \
-macTrace ON \
-movementTrace ON
$ns_ node-config -wiredRouting ON
set eNB(0) [$ns_ node 2.0.0]
$eNB(0) random-motion 0
$eNB(0) set X_ 500.0
$eNB(0) set Y_ 100.0
$eNB(0) set Z_ 0.0
$ns_ at 0.00 "$eNB(0) setdest 500 100 0"
$ns_ node-config -wiredRouting OFF
for {set i 0} {$i < $val(nn)} {incr i} {
set node_($i) [$ns_ node 2.0.[expr $i + 1]]
$node_($i) base-station [AddrParams addr2id [ $server node-addr]]
$node_($i) random-motion 0
}
#20 defines the node size in nam, must adjust it according to your scenario
#The function must be called after mobility model is defined
for {set i 0} {$i < $val(nn)} {incr i} {
$ns_ initial_node_pos $node_($i) 20
}
$ns_ simplex-link $eNB(0) $aGW 1000Mb 2ms LTEQueue/ULS1Queue
$ns_ simplex-link $aGW $eNB(0) 1000Mb 2ms LTEQueue/DLS1Queue
#The bandwidth between aGW and server is not the bottleneck.
$ns_ simplex-link $aGW $server 5000Mb 2ms DropTail
$ns_ simplex-link $server $aGW 5000Mb 2ms LTEQueue/DLQueue
$ns_ duplex-link-op $server $aGW orient down
$ns_ duplex-link-op $aGW $eNB(0) orient left-down
#---------------------
#Source Mobility Pattern
#---------------------
source $val(mobility)
#----------------
#Labels & Color
#----------------
$server color blue
$aGW color green
$eNB(0) color red
$ns_ at 0.0 "$server label \"SERVER\""
$ns_ at 0.0 "$aGW label \"GTW\""
$ns_ at 0.0 "$eNB(0) label eNB_0"
for {set i 0} {$i < $val(nn)} {incr i} {
$ns_ at 0.0 "$node_($i) label \"vehicle [expr $i]\""
}
#-----------------------------------
#Define Node Initial Position In Nam
#-----------------------------------
#--------------------- #Setup Traffic
for {set i 0} {$i < $val(nn)} {incr i} {
set udp($i) [new Agent/UDP]
set null($i) [new Agent/Null]
$ns_ attach-agent $node_($i) $udp($i)
$ns_ attach-agent $server $null($i)
$udp($i) set fid_ 0
$ns_ connect $udp($i) $null($i)
set cbr($i) [new Application/Traffic/CBR]
$cbr($i) attach-agent $udp($i)
$cbr($i) set packetSize_ 512
$cbr($i) set interval_ 0.2
$ns_ at $val(start) "$cbr($i) start"
$ns_ at $val(stop) "$cbr($i) stop"
}
#-----------------------------------
#Tell Nodes When The Simulation Ends
#-----------------------------------
for {set i 0} {$i < $val(nn)} {incr i} {
$ns_ at $val(stop).0 "$node_($i) reset";
}
$ns_ at $val(stop).0 "expr $server reset";
#$ns_ at $val(stop).0 "expr $server reset";
$ns_ at $val(stop).0001 "stop"
$ns_ at $val(stop).0002 "puts \"NS EXITING...\" ; $ns_ halt"
proc stop {} {
global ns_ nstrace namtrace
$ns_ flush-trace
close $nstrace
close $namtrace
exec nam out.nam &
exit 0
}
puts "Starting simulation..."
$ns_ run
and its erorr:
madani#ubuntu:~/cluster$ ns map.tcl
num_nodes is set 39
INITIALIZE THE LIST xListHead
Starting simulation...
Segmentation fault (core dumped)
It is possible to use Queue/LTEQueue/DLAirQueue together with {Propagation/Nakagami, Phy/WirelessPhyExt, Mac/802_11Ext + the suggested "802.11p settings"} in a simulation. Example LTE file: bicfixdownlink.tcl https://drive.google.com/file/d/0B7S255p3kFXNSmd4Q3h3dXp1QWc/view?usp=sharing
source 802.11p-file
set opt(chan) Channel/WirelessChannel ;# channel type
set opt(prop) Propagation/Nakagami ;# radio-propagation model
set opt(netif) Phy/WirelessPhyExt ;# network interface type
set opt(mac) Mac/802_11Ext ;# MAC type
set opt(ifq) Queue/LTEQueue/DLAirQueue ;# interface queue type
... where 802.11p-file is your code from the question.
The edited "bicfixdownlink.tcl" runs OK with the LTE patched ns. The 'nam' animation is good. And the xgraph output is acceptable :
xgraph down0 down1 down2 down3 down4 &
EDIT: Other example, L-guindy-teatinos40A.tcl + flowmod-teatinos-M40.tcl + mobmod-teatinos-M40A.tcl, where L-guindy-* is using the 802.11p settings from mobmod-teatinos-M40A.tcl https://drive.google.com/file/d/0B7S255p3kFXNRkVKVFBuNnFLcG8/view?usp=sharing
The Teatinos SUMO files are from http://neo.lcc.uma.es/staff/jamal/vanet/?q=node/11
I currently have one agentset(ports) hatching another agentset(ships).
The idea is to have the ships face the closest port to their current location.
[let target min-one-of ports [distance myself]
face target].
Unfortunately this makes the ships face their current location since they are being hatched at a given port. If there is no way to exclude the port they hatch on- I have an index of the locations(ports) and could potentially set the target as the following item in the index however I am not sure how I would accomplish this. any suggestions?
full code example
breed [ships ship]
breed[ports port]
to setup
let index 0
create-ports 3
[ let loc item index [ [459 -324] [670 -233] [677 -356] ]
setxy (item 0 loc) (item 1 loc)
set index index + 1
set shape "circle"
set size 5
set color red - 1]
ask ports
[ hatch-ships 1
[ set size 10
set color red
pen-down
set pen-size 1
let target min-one-of other ports [distance myself]
face target] ]
reset-ticks
end
You can assign the who value of hatching port to the ship as their current port and define their target port as the closes port which is not the current port.
breed [ships ship]
breed[ports port]
ships-own [currentPort targetPort]
to setup
clear-all
let index 0
create-ports 3
[
; let loc item index [ [459 -324] [670 -233] [677 -356] ]
let loc item index [ [4 -4] [ 9 5] [ -11 11] ]
setxy (item 0 loc) (item 1 loc)
set index index + 1
set shape "circle"
set size 5
set color red - 1]
ask ports
[
let s who
set label ( word S " Port " s )
hatch-ships 1
[ set currentPort s
set shape "sailboat side"
set size 10
set color red
pen-down
set pen-size 1
Set targetPort min-one-of ports with [ who != s] [distance myself]
set heading towards targetport
set label (word "target " targetport)
] ]
reset-ticks
end
So about a week ago I worked on setting up a mail server for my company's mail service. I ended up using zpanel to make it easier to create new mail accounts. Zpanel uses postfix and dovecot that is configured via the installation. I've been trying to set up ssl on this server using a self signed certificate but I continue to receive a your server doesn't support ssl.
/etc/postfix/main.cf
# postfix config file
# uncomment for debugging if needed
soft_bounce=yes
# postfix main
mail_owner = postfix
setgid_group = postdrop
delay_warning_time = 4
# postfix paths
html_directory = no
command_directory = /usr/sbin
daemon_directory = /usr/lib/postfix
queue_directory = /var/spool/postfix
sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
manpage_directory = /usr/share/man
sample_directory = /usr/share/doc/postfix-2.2.2/samples
readme_directory = /usr/share/doc/postfix-2.2.2/README_FILES
# network settings
inet_interfaces = all
mydomain = mail.thetactilegroup.com
myhostname = mail.thetactilegroup.com
mynetworks = all
mydestination = localhost.$mydomain, localhost
relay_domains = proxy:mysql:/etc/zpanel/configs/postfix/mysql-relay_domains_maps.cf
# mail delivery
recipient_delimiter = +
# mappings
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
#transport_maps = hash:/etc/postfix/transport
#local_recipient_maps =
# virtual setup
virtual_alias_maps = proxy:mysql:/etc/zpanel/configs/postfix/mysql- virtual_alias_maps.cf,
regexp:/etc/zpanel/configs/postfix/virtual_regexp
virtual_mailbox_base = /var/zpanel/vmail
virtual_mailbox_domains = proxy:mysql:/etc/zpanel/configs/postfix/mysql- virtual_domains_maps.cf
virtual_mailbox_maps = proxy:mysql:/etc/zpanel/configs/postfix/mysql- virtual_mailbox_maps.cf
virtual_mailbox_limit_maps = proxy:mysql:/etc/zpanel/configs/postfix/mysql-virtual_mailbox_limit_maps.cf
virtual_minimum_uid = 150
virtual_uid_maps = static:150
virtual_gid_maps = static:8
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
# debugging
debug_peer_level = 2
debugger_command =
PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
xxgdb $daemon_directory/$process_name $process_id & sleep 5
# authentication
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
broken_sasl_auth_clients = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
# tls config
smtp_use_tls = no
smtpd_use_tls = yes
#smtp_tls_note_starttls_offer = yes
#smtpd_tls_loglevel = 1
#smtpd_tls_received_header = yes
#smtpd_tls_session_cache_timeout = 3600s
#tls_random_source = dev:/dev/urandom
#smtp_tls_session_cache_database = btree:$data_directory/smtp_tls_session_cache
# Change mail.example.com.* to your host name
smtpd_tls_key_file = /etc/postfix/ssl/smtp.in.key
smtpd_tls_cert_file = /etc/postfix/ssl/smtp.in.pem
# smtpd_tls_CAfile = /etc/pki/tls/root.crt
# rules restrictions
smtpd_client_restrictions =
smtpd_helo_restrictions =
smtpd_sender_restrictions =
smtpd_recipient_restrictions = permit_sasl_authenticated,
permit_mynetworks,
reject_unauth_destination,
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unknown_recipient_domain
# uncomment for realtime black list checks
# ,reject_rbl_client zen.spamhaus.org
# ,reject_rbl_client bl.spamcop.net
# ,reject_rbl_client dnsbl.sorbs.net
smtpd_helo_required = yes
unknown_local_recipient_reject_code = 550
disable_vrfy_command = yes
smtpd_data_restrictions = reject_unauth_pipelining
message_size_limit = 52428800
smtp_tls_security_level = may
/etc/postfix/master.cf
#
# Postfix master process configuration file. For details on the format
# of the file, see the Postfix master(5) manual page.
#
# ***** Unused items removed *****
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (yes) (never) (100)
# ==========================================================================
submission inet n - - - - smtpd
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth
-o smtpd_sasl_security_options=noanonymous
-o smtpd_sasl_local_domain=$myhostname
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o smtpd_sender_login_maps=hash:/etc/postfix/virtual
-o smtpd_sender_restrictions=reject_sender_login_mismatch
-o smtpd_recipient_restrictions=reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject
#smtp inet n - n - - smtpd
# -o content_filter=smtp-amavis:127.0.0.1:10024
# -o receive_override_options=no_address_mappings
pickup fifo n - n 60 1 pickup
-o content_filter=
-o receive_override_options=no_header_body_checks
cleanup unix n - n - 0 cleanup
qmgr fifo n - n 300 1 qmgr
#qmgr fifo n - n 300 1 oqmgr
tlsmgr unix - - n 1000? 1 tlsmgr
rewrite unix - - n - - trivial-rewrite
bounce unix - - n - 0 bounce
defer unix - - n - 0 bounce
trace unix - - n - 0 bounce
verify unix - - n - 1 verify
flush unix n - n 1000? 0 flush
proxymap unix - - n - - proxymap
smtp unix - - n - - smtp
# When relaying mail as backup MX, disable fallback_relay to avoid MX loops
relay unix - - n - - smtp
-o fallback_relay=
# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq unix n - n - - showq
error unix - - n - - error
discard unix - - n - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - n - - lmtp
anvil unix - - n - 1 anvil
scache unix - - n - 1 scache
#
# ====================================================================
# Interfaces to non-Postfix software. Be sure to examine the manual
# pages of the non-Postfix software to find out what options it wants.
# ====================================================================
maildrop unix - n n - - pipe
flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient}
uucp unix - n n - - pipe
flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
ifmail unix - n n - - pipe
flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp unix - n n - - pipe
flags=Fq. user=foo argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient
#
# spam/virus section
#
smtp-amavis unix - - y - 2 smtp
-o smtp_data_done_timeout=1200
-o disable_dns_lookups=yes
-o smtp_send_xforward_command=yes
127.0.0.1:10025 inet n - y - - smtpd
-o content_filter=
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=127.0.0.0/8
-o smtpd_error_sleep_time=0
-o smtpd_soft_error_limit=1001
-o smtpd_hard_error_limit=1000
-o receive_override_options=no_header_body_checks
-o smtpd_bind_address=127.0.0.1
-o smtpd_helo_required=no
-o smtpd_client_restrictions=
-o smtpd_restriction_classes=
-o disable_vrfy_command=no
-o strict_rfc821_envelopes=yes
#
# Dovecot LDA
dovecot unix - n n - - pipe
flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/deliver -d ${recipient}
#
# Vacation mail
vacation unix - n n - - pipe
flags=Rq user=vacation argv=/var/spool/vacation/vacation.pl -f ${sender} -- ${recipient}
How would I correct this issue?
mydomain = mail.thetactilegroup.com
myhostname = mail.thetactilegroup.com
convert to this
mydomain = thetactilegroup.com
myhostname = mail.thetactilegroup.com
Basically you need to enable smtp_use_tls:
smtp_use_tls = yes
Additionally, I recommend the following switches:
smtp_tls_loglevel = 1
smtpd_tls_loglevel = 1
smtp_tls_note_starttls_offer = yes
smtp_tls_security_level = may
smtpd_tls_security_level = may
smtpd_tls_ciphers = high
smtpd_tls_exclude_ciphers = aNULL, aDSS, aECDSA
smtpd_tls_protocols = !SSLv2, !SSLv3
smtpd_tls_received_header = yes
You can read more about here http://www.postfix.org/postconf.5.html
Try this in master.cf:
smtps inet n - n - - smtpd
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
Save and restart Postfix:
service postfix restart
I'm having issues with my netlogo program. Code follows:
globals[
growth-param
money-size-ratio
]
turtles-own[
location
tsize
bbalance
]
to setup
ca
reset-ticks
ask patches[set pcolor blue]
create-turtles initial-telemarketers [
set size 1
set bbalance 0.0
setxy random-xcor random-ycor
set shape "circle"
]
set growth-param 1000
set money-size-ratio 0.001
end
to go
ask patches[set pcolor blue]
sell
accounting
observer-updates
tick
end
to sell
let territory 10 * sqrt size
let maxcalls 100 * size
ask n-of maxcalls patches in-radius territory[
if pcolor = blue [set pcolor black]
set bbalance bbalance + 2
]
end
to accounting
let cost size * 50
ask turtles[
set bbalance bbalance - cost
ifelse bbalance < 1
[die]
[set size bbalance * growth-param]
]
end
to observer-updates
end
It's supposed to be a model of how many telemarketing companies interact, simplistically. It's from Railsback & Grimm's modeling book.
Each time it tries to run, it provides two problems that I can see: in procedure sell, it doesn't want to set bbalance to the new value because it is turtle-only, and tick is observer-context only.
Thanks for any help!
globals[
money-size-ratio
]
turtles-own[
location
tsize
bbalance
maxsize
]
to setup
ca
reset-ticks
ask patches[set pcolor blue]
create-turtles initial-telemarketers [
set size 1
set bbalance 0.0
setxy random-xcor random-ycor
set shape "circle"
set maxsize 0
]
set money-size-ratio 0.001
end
to go
ask patches[set pcolor blue]
ask turtles [sell]
ask turtles [accounting] ;; let's ask the turtles to do this
observer-updates
tick
end
to sell
let territory 10 * sqrt size
let maxcalls 100 * size
if maxcalls > 40401[
set maxcalls 40401;keeps maxcalls within acceptable bounds
]
let coun 0
ask n-of maxcalls patches in-radius territory[
if pcolor = blue[
set pcolor black
set coun coun + 2
]
]
set bbalance bbalance + coun
end
to accounting
let cost size * 50 ;; size is a turtle variable so if you want to access it this way, let's make the whole thing
;; a turtle procedure. That's what was confusing Netlogo about the tick command
set bbalance bbalance - cost
if bbalance > growth-param
[set size size + (bbalance - growth-param) * money-size-ratio
set bbalance growth-param
]
if size > maxsize[
set maxsize size
]
if bbalance <= 0
[show (word "dead. Maximum size: " maxsize)
die
]
if size = 0
[show (word "dead. Maximum size: " maxsize)
die
]
end
to observer-updates
end
sell is a turtle procedure (because it uses turtle primitives such as size and in-radius). But go is an observer procedure. You can't call a turtle procedure directly from an observer procedure; you need to specify which turtles you want to run it. Inside go, I think you may have meant to write ask turtles [ sell ] instead of just sell.
Look at this makefile, it has some sort of primitive progress indication (could have been a progress bar).
Please give me suggestions/comments on it!
# BUILD is initially undefined
ifndef BUILD
# max equals 256 x's
sixteen := x x x x x x x x x x x x x x x x
MAX := $(foreach x,$(sixteen),$(sixteen))
# T estimates how many targets we are building by replacing BUILD with a special string
T := $(shell $(MAKE) -nrRf $(firstword $(MAKEFILE_LIST)) $(MAKECMDGOALS) \
BUILD="COUNTTHIS" | grep -c "COUNTTHIS")
# N is the number of pending targets in base 1, well in fact, base x :-)
N := $(wordlist 1,$T,$(MAX))
# auto-decrementing counter that returns the number of pending targets in base 10
counter = $(words $N)$(eval N := $(wordlist 2,$(words $N),$N))
# BUILD is now defined to show the progress, this also avoids redefining T in loop
BUILD = #echo $(counter) of $(T)
endif
# dummy phony targets
.PHONY: all clean
all: target
#echo done
clean:
#rm -f target *.c
# dummy build rules
target: a.c b.c c.c d.c e.c f.c g.c
#touch $#
$(BUILD)
%.c:
#touch $#
$(BUILD)
All suggestions welcome!
This one is less intrusive and more awesome.
ifneq ($(words $(MAKECMDGOALS)),1)
.DEFAULT_GOAL = all
%:
#$(MAKE) $# --no-print-directory -rRf $(firstword $(MAKEFILE_LIST))
else
ifndef ECHO
T := $(shell $(MAKE) $(MAKECMDGOALS) --no-print-directory \
-nrRf $(firstword $(MAKEFILE_LIST)) \
ECHO="COUNTTHIS" | grep -c "COUNTTHIS")
N := x
C = $(words $N)$(eval N := x $N)
ECHO = echo "`expr " [\`expr $C '*' 100 / $T\`" : '.*\(....\)$$'`%]"
endif
.PHONY: all clean
all: target
#$(ECHO) All done
clean:
#rm -f target *.c
# #$(ECHO) Clean done
target: a.c b.c c.c d.c e.c
#$(ECHO) Linking $#
#sleep 0.1
#touch $#
%.c:
#$(ECHO) Compiling $#
#sleep 0.1
#touch $#
endif
There wasn't really a question so this is less of a standalone answer and more of an extension to Giovanni Funchai's solution. This question is the first google result for "GNU Make Progress" so I ended up here looking for how to do this.
As pointed out by Rob Wells, the solution doesn't work for <10%, but the technique can be extended with the print formatting done by a helper script in whatever language you feel is portable enough for your build. For example, using a python helper script:
echo_progress.py:
"""
Print makefile progress
"""
import argparse
import math
import sys
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--stepno", type=int, required=True)
parser.add_argument("--nsteps", type=int, required=True)
parser.add_argument("remainder", nargs=argparse.REMAINDER)
args = parser.parse_args()
nchars = int(math.log(args.nsteps, 10)) + 1
fmt_str = "[{:Xd}/{:Xd}]({:6.2f}%)".replace("X", str(nchars))
progress = 100 * args.stepno / args.nsteps
sys.stdout.write(fmt_str.format(args.stepno, args.nsteps, progress))
for item in args.remainder:
sys.stdout.write(" ")
sys.stdout.write(item)
sys.stdout.write("\n")
if __name__ == "__main__":
main()
And the modified Makefile:
_mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
I := $(patsubst %/,%,$(dir $(_mkfile_path)))
ifneq ($(words $(MAKECMDGOALS)),1)
.DEFAULT_GOAL = all
%:
#$(MAKE) $# --no-print-directory -rRf $(firstword $(MAKEFILE_LIST))
else
ifndef ECHO
T := $(shell $(MAKE) $(MAKECMDGOALS) --no-print-directory \
-nrRf $(firstword $(MAKEFILE_LIST)) \
ECHO="COUNTTHIS" | grep -c "COUNTTHIS")
N := x
C = $(words $N)$(eval N := x $N)
ECHO = python $(I)/echo_progress.py --stepno=$C --nsteps=$T
endif
.PHONY: all clean
all: target
#$(ECHO) All done
clean:
#rm -f target *.c
# #$(ECHO) Clean done
target: a.c b.c c.c d.c e.c f.c g.c h.c i.c j.c k.c l.c m.c n.c o.c p.c q.c \
r.c s.c t.c u.c v.c w.c x.c y.c z.c
#$(ECHO) Linking $#
#sleep 0.01
#touch $#
%.c:
#$(ECHO) Compiling $#
#sleep 0.01
#touch $#
endif
yields:
$ make
[ 1/28]( 3.57%) Compiling a.c
[ 2/28]( 7.14%) Compiling b.c
[ 3/28]( 10.71%) Compiling c.c
[ 4/28]( 14.29%) Compiling d.c
[ 5/28]( 17.86%) Compiling e.c
[ 6/28]( 21.43%) Compiling f.c
[ 7/28]( 25.00%) Compiling g.c
[ 8/28]( 28.57%) Compiling h.c
[ 9/28]( 32.14%) Compiling i.c
[10/28]( 35.71%) Compiling j.c
[11/28]( 39.29%) Compiling k.c
[12/28]( 42.86%) Compiling l.c
[13/28]( 46.43%) Compiling m.c
[14/28]( 50.00%) Compiling n.c
[15/28]( 53.57%) Compiling o.c
[16/28]( 57.14%) Compiling p.c
[17/28]( 60.71%) Compiling q.c
[18/28]( 64.29%) Compiling r.c
[19/28]( 67.86%) Compiling s.c
[20/28]( 71.43%) Compiling t.c
[21/28]( 75.00%) Compiling u.c
[22/28]( 78.57%) Compiling v.c
[23/28]( 82.14%) Compiling w.c
[24/28]( 85.71%) Compiling x.c
[25/28]( 89.29%) Compiling y.c
[26/28]( 92.86%) Compiling z.c
[27/28]( 96.43%) Linking target
[28/28](100.00%) All done
One could even print a fancy progress bar with unicode characters.
Modified echo_progress.py:
"""
Print makefile progress
"""
import argparse
import math
import sys
def get_progress_bar(numchars, fraction=None, percent=None):
"""
Return a high resolution unicode progress bar
"""
if percent is not None:
fraction = percent / 100.0
if fraction >= 1.0:
return "█" * numchars
blocks = [" ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█"]
length_in_chars = fraction * numchars
n_full = int(length_in_chars)
i_partial = int(8 * (length_in_chars - n_full))
n_empty = max(numchars - n_full - 1, 0)
return ("█" * n_full) + blocks[i_partial] + (" " * n_empty)
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--stepno", type=int, required=True)
parser.add_argument("--nsteps", type=int, required=True)
parser.add_argument("remainder", nargs=argparse.REMAINDER)
args = parser.parse_args()
nchars = int(math.log(args.nsteps, 10)) + 1
fmt_str = "\r[{:Xd}/{:Xd}]({:6.2f}%) ".replace("X", str(nchars))
progress = 100 * args.stepno / args.nsteps
sys.stdout.write(fmt_str.format(args.stepno, args.nsteps, progress))
sys.stdout.write(get_progress_bar(20, percent=progress))
remainder_str = " ".join(args.remainder)
sys.stdout.write(" {:20s}".format(remainder_str[:20]))
if args.stepno == args.nsteps:
sys.stdout.write("\n")
if __name__ == "__main__":
main()
Which would result in something like this:
$ make clean && make
[12/28]( 42.86%) ███████▊ Compiling k.c
during progress and:
$ make clean && make
[28/28](100.00%) ████████████████████ All done
upon completion.
This is a slight modification to #GiovanniFunchal's excellent answer.
So I wanted to understand this better and make it work for < 10% so I dug into the documentation and learned more about expr.
# PLACE AT THE TOP OF YOUR MAKEFILE
#---------------------------------
# Progress bar defs
#--------------------------------
# words = count the number of words
ifneq ($(words $(MAKECMDGOALS)),1) # if no argument was given to make...
.DEFAULT_GOAL = all # set the default goal to all
# http://www.gnu.org/software/make/manual/make.html
# $# = target name
# %: = last resort recipe
# --no-print-directory = don't print enter/leave messages for each output grouping
# MAKEFILE_LIST = has a list of all the parsed Makefiles that can be found *.mk, Makefile, etc
# -n = dry run, just print the recipes
# -r = no builtin rules, disables implicit rules
# -R = no builtin variables, disables implicit variables
# -f = specify the name of the Makefile
%: # define a last resort default rule
#$(MAKE) $# --no-print-directory -rRf $(firstword $(MAKEFILE_LIST)) # recursive make call,
else
ifndef ECHO
# execute a dry run of make, defining echo beforehand, and count all the instances of "COUNTTHIS"
T := $(shell $(MAKE) $(MAKECMDGOALS) --no-print-directory \
-nrRf $(firstword $(MAKEFILE_LIST)) \
ECHO="COUNTTHIS" | grep -c "COUNTTHIS")
# eval = evaluate the text and read the results as makefile commands
N := x
# Recursively expand C for each instance of ECHO to count more x's
C = $(words $N)$(eval N := x $N)
# Multipy the count of x's by 100, and divide by the count of "COUNTTHIS"
# Followed by a percent sign
# And wrap it all in square brackets
ECHO = echo -ne "\r [`expr $C '*' 100 / $T`%]"
endif
#------------------
# end progress bar
#------------------
# REST OF YOUR MAKEFILE HERE
#----- Progressbar endif at end Makefile
endif
I got rid of the : '.*\(....\)$$' part. It would return the last 4 characters of the inner expr command, but would fail if it was less than 4. And now it works for sub 10%!
And here is the comment free version:
ifneq ($(words $(MAKECMDGOALS)),1) # if no argument was given to make...
.DEFAULT_GOAL = all # set the default goal to all
%: # define a last resort default rule
#$(MAKE) $# --no-print-directory -rRf $(firstword $(MAKEFILE_LIST)) # recursive make call,
else
ifndef ECHO
T := $(shell $(MAKE) $(MAKECMDGOALS) --no-print-directory \
-nrRf $(firstword $(MAKEFILE_LIST)) \
ECHO="COUNTTHIS" | grep -c "COUNTTHIS")
N := x
C = $(words $N)$(eval N := x $N)
ECHO = echo -ne "\r [`expr $C '*' 100 / $T`%]"
endif
# ...
endif
Hope that helps.
Many thanks to #Giovanni Funchal and #phyatt for the question and answers!
I just simplified it even more for my own better understanding.
ifndef ECHO
HIT_TOTAL != ${MAKE} ${MAKECMDGOALS} --dry-run ECHO="HIT_MARK" | grep -c "HIT_MARK"
HIT_COUNT = $(eval HIT_N != expr ${HIT_N} + 1)${HIT_N}
ECHO = echo "[`expr ${HIT_COUNT} '*' 100 / ${HIT_TOTAL}`%]"
endif
!= assigns from shell command
= evaluates variable each time it's used
eval executes its argument without any output
expr allows to make arithmetic calculations
( Not sure though which approach is faster: to call shell with expr or to count 'x'-es with make. )
Usage is the same:
target:
#$(ECHO) $#
Nice trick! (-:
But not really scalable for growing projects that are distributed across many directories with lots of makefiles.
I'd be more inclined to have logging sprinkled through the [Mm]akefiles* in your project and use that to keep track of progress.
Just a thought. BTW Thanks for sharing this.
Edit: Just had a thought. This could be useful in a modified form to display a throbber to show progress while a long task proceeds, e.g unpacking a large distribution tarball instead of just specifying the -v option to the tar command. Still a bit of sugar coating but a bit of fun aswell. (-:
cheers,
Rob