How to execute external programs from qmake? - qmake

I am trying run a program from a qmake .pro file which modifies the final binary. I have already tried system(...) but it does not work. The reason I want this is because by default some properties of the binary prevent debugging and it is inconvenient to do it manually every time. I can do this from simple makefiles.
Here is my .pro file:
TARGET = lprog_server
QT += core \
xml \
network
HEADERS += Network/PlayerJoined.hh \
...
SOURCES += Globals.cc \
...
FORMS +=
RESOURCES +=
QMAKE_LFLAGS += -lboost_random-mt
system(paxctl -pemrxs lprog_server)
It is needed for my homework but the assignment is not to execute something from qmake. It is in fact a server-client software using Qt already more than 2500 lines long.

QMAKE_POST_LINK=paxctl -pemrxs $(TARGET)

Related

Is there a guide on porting edk2 to a new ARM64 platform?

I am new to EDK2.
For porting ekd2 firmware to a new ARM64 platform, it would be good to first get a minimum edk2 port which can run UEFI Shell at least, improvements can be added gradually based on that.
It seems that the first step is rather steep, e.g., how to determine a minimal set of "items" in .dsc and .fdf file for a platform? In my case, I would like to build the .fd for my platform and treat it as BL33 of TF-A, effectively I would like to build an edk2 firmware to replace u-boot.
It seems that such a guide is hard to find on the web. I found a old version of edk2 which contains some instructions, but apparently they are obsolete (not exist in latest master branch, while can be found in UDK branches such as UDK2014), and I am not sure why those documents are removed from master branch.
Currently I can build .fd for FVP (edk2-platforms/Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc), and it seems that the build output FVP_AARCH64_EFI.fd is supposed to be treated as BL33. Theoretically this could be a prototype for my new ARM64 platform, but to me it's too complex to start with: the firmware is about 2.5MiB in size (as compare to 500K of u-boot), so I guess it's far from a "minimum" version. but it's hard to figure out what features to be removed (and how).
I am wondering if there is a detailed guide on such topic...
After 1 month of trial and error, today I managed to bring my ARM64 platform into a UEFI Shell environment. I treat it as my 1st milestone on the EDK2 journey. Below I will try to summarize the steps I took so far, as a tentative answer to my question above. Guidance/corrections/comments are welcomed.
Get familiar with UEFI/PI spec and EDK2 implementation by reading books/specs/articles. Well, UEFI/PI specs are thousands of pages long...how to start? My main reading list is:
"Beyond Bios--Developing with the Unified Extensible Firmware Interface", 3rd ed, by Vincent Zimmer, et al. As the authors explained, the book is a kind of high level summary of the thousands-paged specs. And I find that the book is well organized for a new comer to get familiar with various UEFI related concepts. The main purpose of the 1st read (before playing with edk2 code base) is to get familiar with concepts and architectural ideas, not the details yet. Related sections need to be consulted later when reading EDK2 implementations.
EDK2 specs, including:
EDKII User Manual
EDKII Build Specification
EDKII DSC/FDF/DEC/INF File Specification
Various articles on the web...
Get a reference platform which can correctly boot a FD image built from latest EDK2 source, and play with the boot manager and Shell environment a bit. In my case, I chose RPi4B. For me, this is very important, as the reference platform serves as a handrail during the whole process, that whenever I encounter bugs or have doubts, I check the source/log of the reference platform. This solves most of the problems I encountered. Btw, always generating "build log" and "build report" for both reference platform and the target platform, as the two files contains very detailed information for comparison and check. Consult the EDK2 build spec on how to generate these two files during build.
I use the following script to build for RPi4B platform:
#!/bin/bash
# https://github.com/tianocore/edk2-platforms#how-to-build-linux-environment
export WORKSPACE=/home/bruin/work/tianocore
export PACKAGES_PATH=$WORKSPACE/edk2:$WORKSPACE/edk2-platforms:$WORKSPACE/edk2-non-osi
pushd $WORKSPACE
rm -rf ./Build/RPi4
source edk2/edksetup.sh
echo "Building BaseTools..."
make -C edk2/BaseTools all
#sudo apt install acpica-tools # iasl
# pip install antlr4-python3-runtime # -Y EXECUTION_ORDER
echo "Building firmware for Pi4B..."
GCC5_AARCH64_PREFIX=aarch64-none-linux-gnu- build \
-n 4 \
-a AARCH64 \
-p Platform/RaspberryPi/RPi4/RPi4.dsc \
-t GCC5 \
-b NOOPT \
-v -d 9 -j RPi4-build.log \
-y RPi4-build-report.txt \
-Y PCD \
-Y LIBRARY \
-Y DEPEX \
-Y HASH \
-Y BUILD_FLAGS \
-Y FLASH \
-Y FIXED_ADDRESS \
-Y EXECUTION_ORDER \
all
How to use the build result RPI_EFI.fd on RPi4B, consult the following:
edk2-platforms/Platform/RaspberryPi/RPi4/Readme.md
readme.md inside https://github.com/pftf/RPi4/releases/download/v1.17/RPi4_UEFI_Firmware_v1.32.zip. btw, I need to replace the original start4.elf and fixup4.dat with the ones in the zip file, otherwise, the boot of RPi4 will fail, complaining something like below:
RpiFirmwareGetClockRate: Get Clock Rate return: ClockRate=0 ClockId=C
ASSERT [ArasanMMCHost] /home/bruin/work/tianocore/edk2-platforms/Platform/RaspberryPi/
Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.c(263): BaseFrequency != 0
It's worth to analysis the RPI_EFI.fd content to some extend, by using some UEFI utilities. I mainly use the GUI version UEFITool of sudo apt install uefitool uefitool-cli. Other tools are also available. The anotomy of RPI_EFI.fd is of help when reading EDK2 build specs for checking understanding of the concepts.
One special aspect of RPI_EFI.fd is that the 1st 128K is bl31.bin binary from ATF. I guess this is due to the special booting connfiguration methods for RPi. For my platform, I don't need such kind of packaging, I only need to build the UEFI image MY.fd, which is treated as BL33 image and packaged into fip.bin togehter with BL2 and BL31 images by ATF build script.
Another aspect to notice is the "reset vector" in the begining of the .fd file. This related to the entry point of UEFI image (and entry point of each EDK2 modules), as well as interpreting the BL instruction for AArch64. Basically, it can be summarized as below:
The first [Components] in RPI_EFI.fd is ArmPlatformPkg/PrePi/PeiUniCore.inf, which is of MODULE_TYPE = SEC.
What's this component: this is the first (and only) SEC (Security) module in RPi4. What the name PrePi and Pei implies?
... the PI spec is not tied to edk2 PEIMs, and I don't see where EDKII PEI modules are currently the only "acknowledged" silicon init environment. The edk2 tree itself seems to contain platforms that don't use the edk2 PEI module set at all, but (IIRC) jump from SEC to DXE. I believe "ArmPlatformPkg/PrePi" and "ArmVirtPkg/PrePi" are related to this.
--- https://listman.redhat.com/archives/edk2-devel-archive/2020-November/msg00021.html
Its entry point: all UEFI components have the same entry point (_ModuleEntryPoint).
By "component", it means either a UEFI driver and UEFI app, both are PE32 executables, usually with suffix .efi.
The .efis are converted from ELF executables (.dll) by GenFw tool: modifying the file headers.
To verify that "all components' entry point is _ModuleEntryPoint":
Check the .dll generating command line in build report (build -y <BUILD_REPORT_FILE>), we have two flags "aarch64-none-linux-gnu-gcc" -o xxx.dll -u _ModuleEntryPoint -Wl,-e,_ModuleEntryPoint ...:
-u: gcc --help -v|grep "undefined SYMBOL" gives -u SYMBOL --undefined SYMBOL: star with undefined reference to SYMBOL.
Wl,-e: ld --help|grep "entry" gives -e ADDRESS, --entry ADDRESS Set start address.
Check all .dll files that Entry point address == _ModuleEntryPoint: find . -type f -name "*.dll" -exec sh -c "readelf -a {} |grep -E 'Entry point address|_ModuleEntryPoint'" \;
Its entry point is the entry point of whole UEFI FD image (i.e., from bl33_base_addr jump to this _ModuleEntryPoint):
Topology of the UEFI Firmware File
A UEFI Firmware File (actually a UEFI Firmware Device - FD file) is a collection of UEFI binaries encapsulated into a single image. The format of this image is defined by the Platform Initialization Specification Volume 3. A Vector Table is located at the base of this file. A 'BL' branch instruction at the base of the firwmare (location of the Reset Entry into the Vector Table) will jump to the first 'SEC' module of the UEFI Firmware Image.
--- https://github.com/lzeng14/tianocore/wiki/ArmPkg-Debugging
To verify the statements above:
Disassember the reset vector (i.e., the 1st word) of generated .FD (we got offset=0x360):
$ xxd -l 4 -e TEST.fd <== dump 4 bytes in little endian
00000000: 140000d8 <== BL {PC}+(0xd8<<2); offset=0x360
Check the Entry point in .dll (we got offset=0x240):
$ aarch64-none-elf-objdump -t ArmPlatformPrePiUniCore.dll|grep _ModuleEntryPoint
0000000000000240 g F .text 0000000000000000 _ModuleEntryPoint
$ readelf -h ArmPlatformPrePiUniCore.dll|grep Entry
Entry point address: 0x240
Compare contents of two files at different offset (we got identicial content):
$ xxd -s 0x360 -l 64 TEST.fd <== skip 0x360 bytes, dump 64 bytes
00000360: 901e 0094 050a 0094 ea03 00aa a1cd 0a58 ...............X
00000370: 0200 e0d2 2200 c0f2 0240 a0f2 0200 80f2 ...."....#......
00000380: c303 a0d2 e3ff 9ff2 6304 00d1 6300 028b ........c...c...
00000390: 0400 a1d2 0400 80f2 2000 03eb 8400 0054 ........ ......T
$ xxd -s 0x240 -l 64 ArmPlatformPrePiUniCore.dll <== skip 0x240 bytes
00000240: 901e 0094 050a 0094 ea03 00aa a1cd 0a58 ...............X
00000250: 0200 e0d2 2200 c0f2 0240 a0f2 0200 80f2 ...."....#......
00000260: c303 a0d2 e3ff 9ff2 6304 00d1 6300 028b ........c...c...
00000270: 0400 a1d2 0400 80f2 2000 03eb 8400 0054 ........ ......T
Prepare an empty pkg, and make it build ok. The main purpuse is to do some exercise with EDK2 build system, and use the empty pkg as the start point for the new platform.
Make a copy of RaspberryPi.dec, change all gRaspberry to gMyPlatform.
Make a copy of RPi4.dsc and RPi4.fdf, and comment out all stuff in DSC and FDF file.
Replace all GUIDs in DSC/FDF/DEC files, generating new ones using online guid generator.
Note that PCD are declared in DEC files, and DEC files are refered by modules (INF files). As the empty package contains no module, no PCD definition will be available in FDF. So for a success build of the empty package, we need to comment out all PCD reference in FDF.
The NOOPT build command for MyPlatform is as below:
#!/bin/bash
export WORKSPACE=/home/bruin/work/tianocore
export PACKAGES_PATH=$WORKSPACE/edk2:$WORKSPACE/edk2-platforms:$WORKSPACE/edk2-non-osi
pushd $WORKSPACE
source edk2/edksetup.sh
echo "Building BaseTools..."
make -C edk2/BaseTools all
echo "Building UEFI firmware for MyPlatform..."
GCC5_AARCH64_PREFIX=aarch64-none-linux-gnu- build \
-n 4 \
-a AARCH64 \
-p Platform/MyCorp/MyPlatform/MyPlatform.dsc \
-t GCC5 \
-b NOOPT \
-v -d 9 -j MyPlatform-build.log \
-y MyPlatform-build-report.txt \
-Y EXECUTION_ORDER \
-Y PCD \
-Y LIBRARY \
-Y DEPEX \
-Y HASH \
-Y BUILD_FLAGS \
-Y FLASH \
-Y FIXED_ADDRESS \
all
popd
Add the 1st component ArmPlatformPrePiUniCore. This component is to prepare the HOBs for DXE phae. The main purpose is to get serial port working and memory config correct. Another purpose of this step is to familiar with steps for adding a component/module/lib. Below is a brief summary of the steps:
Uncomment the module's INF into both DSC ([Components] section), and FDF ([FV.FVMAIN_COMPACT]).
Rebuild the pkg, and resolve all Instance of library class [xxxLib] is not found errors reported, by updating [LibraryClasses] sections of DSC.
This step is a repeating process for dozens of times.
Some lib-class has multiple lib-instances, making sure choose the appropriate lib-instance (ref the build-report of RPi4).
if encounter ModuleEntryPoint.iiii:31: Error: immediate out of range: enable gArmTokenSpaceGuid.PcdFdBaseAddress and gArmTokenSpaceGuid.PcdFdSize in FDF.
if encounter undefined reference to _gPcd_BinaryPatch_PcdSerialClockRate: set PcdSerialClockRate in [PcdsPatchableInModule] section in DSC. FIXME: why? ref.
Check the PCDs listed in build log: inspect any abnormal PCD values, and supply correct values.
Customize platform-specific drivers or libraries.
SerialPortLib: locate the lib-class header file (MdePkg/Include/Library/SerialPortLib.h) by find edk2 -type f -name "*.dec" -exec grep -Hn SerialPortLib. The following functions are required:
SerialPortInitialize()
SerialPortWrite()
SerialPortRead()
SerialPortPoll()
SerialPortSetControl(): RETURN_UNSUPPORTED
SerialPortGetControl(): RETURN_UNSUPPORTED
SerialPortSetAttributes(): RETURN_UNSUPPORTED
ArmPlatformLib: interface header at Include/Library/ArmPlatformLib.h. The following functions are required:
ArmPlatformGetCorePosition(): return cpu idx in the cluster given the MPIDR value. this function is used in _ModuleEntryPoint for setting stack for secondary cores. Assuming one cluster for now.
ArmPlatformIsPrimaryCore()
ArmPlatformGetPrimaryCoreMpId()
ArmPlatformGetBootMode()
ArmPlatformPeiBootAction()
ArmPlatformInitialize()
ArmPlatformGetVirtualMemoryMap()
ArmPlatformGetPlatformPpiList()
etc...
Uncomment more modules in DSC/FDF, module by module...For driver/libs which are RPi platform specific, we can:
either search the edk2/edk2-platform for similiar driver or lib instances, or
copy the RPi4 implementation and comment out most of the content, make the pkg build success first, and then bug fixing.
Debugging: my current main debugging method is through adding "printf()", i.e., the edk2 macro DEBUG((DEBUG_INFO,)). One needs to set gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel to an appropriate value to see more debug info.

How to get static library in sdk?

Everyone who searched how to include a static library in SDK, surely read this thread from 2014. I tried what they suggested, but that didn't work.
Reading the yocto mega manual version 2.1 (yocto morty), I found in chapter 5.9.12. (Poky Reference Distribution Changes), that they added DISABLE_STATIC variable, to disable generation of static libraries. I tried adding this to my recipe, and it didn't enable adding static library to SDK:
DISABLE_STATIC = ""
I can see the library in the sysroot when building the image. But it is not getting in the SDK.
So, what exactly do I need to do to get a static library and the headers in SDK?
What worked is adding the staticdev package to ´IMAGE_INSTALL´ in local.conf, but I don't want to have to do that.
I created an example recipe, which demonstrates my problem. The directory structure is like this:
example-staticlib/
example-staticlib/example-staticlib_0.1.bb
example-staticlib/files/
example-staticlib/files/lib.c
example-staticlib/files/lib.h
example-staticlib/files/Makefile
example-staticlib_0.1.bb :
DESCRIPTION = "example stared library"
LICENSE = "LGPLv2"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/LGPL-2.0;md5=9427b8ccf5cf3df47c29110424c9641a"
SRC_URI = "file://lib.c \
file://lib.h \
file://Makefile"
PR = "r0"
S = "${WORKDIR}"
ALLOW_EMPTY_${PN} = "1"
do_install () {
oe_runmake install DEST=${D}
}
TOOLCHAIN_TARGET_TASK += "example-staticlib-dev"
TOOLCHAIN_TARGET_TASK += "example-staticlib-staticdev"
lib.c:
int foo()
{
return 42;
}
lib.h:
int foo();
Makefile:
TARGET=libexample.a
all:$(TARGET)
install :
#install -d $(DEST)/usr/lib/
#install -m 0644 $(TARGET) $(DEST)/usr/lib/
#install -d $(DEST)/usr/include/
#install -m 0644 lib.h $(DEST)/usr/include/
$(TARGET) : lib.c
$(CC) -c lib.c -o lib.o
$(AR) rcs $# lib.o
clean:
rm -rf lib.o $(TARGET)
How exactly to modify the recipe, in order to get the static library in the SDK?
Following your added example.
Adding the following line to your image recipe (or to an .bbappend, eg core-image-minimal.bbappend)
TOOLCHAIN_TARGET_TASK += "example-staticlib-staticdev"
should work for you. That will give you the .a file in the SDK, after running bitbake core-image-minimal -c populate_sdk. (Again assuming that the image used is core-image-minimal).
That your experiment to add the .a file to ${PN}-dev didn't work, is duet to the order of how files are put into packages. The order is ${PN}-dbg ${PN}-staticdev ${PN}-dev ${PN}-doc ${PN}-locale ${PACKAGE_BEFORE_PN} ${PN}. Thus, the .a file will, regardless, be put into ${PN}-staticdev, as that packages is handled prior to {PN}-dev.
Note, you add this line, TOOLCHAIN_TARGET_TASK += "example-staticlib-staticdev" to your image recipe, thus, you need to write the package name instead of PN.
I tried a way which doesn't require editing the image recipe.
example-staticlib_0.1.bb :
After do_install. I didn't use TOOLCHAIN_TARGET_TASK
FILES_${PN}-staticdev += "${libdir}/libexample.a"
RDEPENDS_${PN}-dev += "${PN}-staticdev"
BBCLASSEXTEND = "native nativesdk"

Make and Percent Sign in Paths

I seem to have hit a quirk regarding Makefiles, list processing, and pattern rules. When my source is installed in a directory whose name includes '%', it fails to build correctly. I've boiled it down to a simple test case anybody could run.
I have the following Makefile:
INSTALL_DIR=$(shell pwd)/idir
INSTALL_TREE =
INSTALL_TREE += $(INSTALL_DIR)/dir1
INSTALL_TREE += $(INSTALL_DIR)/dir2
INSTALL_TREE += $(INSTALL_DIR)/dir3
create_tree: $(INSTALL_TREE)
$(INSTALL_TREE):
mkdir -p $#
I put this in a directory called test1, and when I run it I get exactly what I want... all the directories listed in INSTALL_TREE are created:
% make -n
mkdir -p /home/christopher.arguin/test/test1/idir/dir1
mkdir -p /home/christopher.arguin/test/test1/idir/dir2
mkdir -p /home/christopher.arguin/test/test1/idir/dir3
Now use the exact same Makefile in a directory called test%2, and this is what I get:
% make -n
mkdir -p /home/christopher.arguin/test/test2%/idir/dir1
It stops after the first directory. Interestingly, if the first directory does not have a % sign, they all get generated..., e.g.,
INSTALL_TREE =
INSTALL_TREE += ./idir/dir4
INSTALL_TREE += $(INSTALL_DIR)/dir1
INSTALL_TREE += $(INSTALL_DIR)/dir2
INSTALL_TREE += $(INSTALL_DIR)/dir3
gives me:
mkdir -p dir4
mkdir -p /home/christopher.arguin/test/test2%/idir/dir1
mkdir -p /home/christopher.arguin/test/test2%/idir/dir2
mkdir -p /home/christopher.arguin/test/test2%/idir/dir3
The other interesting thing is that the files names are correct... if the % were being misinterpreted as a prefix rule or something you might expect some substitution, but if I let it create the directories it does the absolute right thing.
I tried escaping the % character, but to no avail. Adding this code:
PERCENT := %
ITREE = $(subst $(PERCENT),$(PERCENT)$(PERCENT),$(INSTALL_TREE))
create_tree2: $(ITREE)
$(ITREE):
mkdir -p $#
Just yielded
mkdir -p /home/christopher.arguin/test/test2%%/idir/dir1
The substitution worked, but it didn't actually escape the percent sign. Neither did replacing "%" with "$(PERCENT)", as the filename just contained $(PERCENT) in it afterward.
I found two related questions,
Does GNU Make support '%' in a filename?
and How to correctly escape "%" sign when using pattern rules and patsubst in GNU make?
but neither of those suffered the basic problem I have... that the directory my source is in is out of my control.
Background:
The reason is this an issue for me is that I am trying to migrate to Jenkins Multibranch Pipeline. When Jenkins detects a commit, it creates a workspace based on the name of the branch. If your branch naming convention happens to have slashes in it, Jenkins does the right thing and converts those to "%2F". My makefiles are running afoul of those.
A target containing % defines a pattern rule, and pattern rules with multiple targets are processed differently:
https://www.gnu.org/software/make/manual/make.html#Pattern-Intro
Pattern rules may have more than one target. Unlike normal rules, this does not act as many different rules with the same prerequisites and recipe. If a pattern rule has multiple targets, make knows that the rule’s recipe is responsible for making all of the targets. The recipe is executed only once to make all the targets.
You can fix this by quoting % when defining the path rule. Note that this isn't necessary for the dependencies of create_tree as that is a regular rule, in fact it won't work if you do, as make will look for targets with a literal \%.
INSTALL_DIR := $(abspath .)/idir
INSTALL_TREE += $(INSTALL_DIR)/dir1
INSTALL_TREE += $(INSTALL_DIR)/dir2
INSTALL_TREE += $(INSTALL_DIR)/dir3
.PHONY: create_tree
create_tree: $(INSTALL_TREE)
$(subst %,\%,$(INSTALL_TREE)):
mkdir -p $#

Fortify, how to start analysis through command

How we can generate FortiFy report using command ??? on linux.
In command, how we can include only some folders or files for analyzing and how we can give the location to store the report. etc.
Please help....
Thanks,
Karthik
1. Step#1 (clean cache)
you need to plan scan structure before starting:
scanid = 9999 (can be anything you like)
ProjectRoot = /local/proj/9999/
WorkingDirectory = /local/proj/9999/working
(this dir is huge, you need to "rm -rf ./working && mkdir ./working" before every scan, or byte code piles underneath this dir and consume your harddisk fast)
log = /local/proj/9999/working/sca.log
source='/local/proj/9999/source/src/**.*'
classpath='local/proj/9999/source/WEB-INF/lib/*.jar; /local/proj/9999/source/jars/**.*; /local/proj/9999/source/classes/**.*'
./sourceanalyzer -b 9999 -Dcom.fortify.sca.ProjectRoot=/local/proj/9999/ -Dcom.fortify.WorkingDirectory=/local/proj/9999/working -logfile /local/proj/working/9999/working/sca.log -clean
It is important to specify ProjectRoot, if not overwrite this system default, it will put under your /home/user.fortify
sca.log location is very important, if fortify does not find this file, it cannot find byte code to scan.
You can alter the ProjectRoot and Working Directory once for all if your are the only user: FORTIFY_HOME/Core/config/fortify_sca.properties).
In such case, your command line would be ./sourceanalyzer -b 9999 -clean
2. Step#2 (translate source code to byte code)
nohup ./sourceanalyzer -b 9999 -verbose -64 -Xmx8000M -Xss24M -XX:MaxPermSize=128M -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:+UseParallelGC -Dcom.fortify.sca.ProjectRoot=/local/proj/9999/ -Dcom.fortify.WorkingDirectory=/local/proj/9999/working -logfile /local/proj/9999/sca.log -source 1.5 -classpath '/local/proj/9999/source/WEB-INF/lib/*.jar:/local/proj/9999/source/jars/**/*.jar:/local/proj/9999/source/classes/**/*.class' -extdirs '/local/proj/9999/source/wars/*.war' '/local/proj/9999/source/src/**/*' &
always unix background job (&) in case your session to server is timeout, it will keep working.
cp : put all your known classpath here for fortify to resolve the functiodfn calls. If function not found, fortify will skip the source code translation, so this part will not be scanned later. You will get a poor scan quality but FPR looks good (low issue reported). It is important to have all dependency jars in place.
-extdir: put all directories/files you don't want to be scanned here.
the last section, files between ' ' are your source.
-64 is to use 64-bit java, if not specified, 32-bit will be used and the max heap should be <1.3 GB (-Xmx1200M is safe).
-XX: are the same meaning as in launch application server. only use these to control the class heap and garbage collection. This is to tweak performance.
-source is java version (1.5 to 1.8)
3. Step#3 (scan with rulepack, custom rules, filters, etc)
nohup ./sourceanalyzer -b 9999 -64 -Xmx8000M -Dcom.fortify.sca.ProjectRoot=/local/proj/9999 -Dcom.fortify.WorkingDirectory=/local/proj/9999/working -logfile /local/ssap/proj/9999/working/sca.log **-scan** -filter '/local/other/filter.txt' -rules '/local/other/custom/*.xml -f '/local/proj/9999.fpr' &
-filter: file name must be filter.txt, any ruleguid in this file will not be reported.
rules: this is the custom rule you wrote. the HP rulepack is in FORTIFY_HOME/Core/config/rules directory
-scan : keyword to tell fortify engine to scan existing scanid. You can skip step#2 and only do step#3 if you did notchange code, just want to play with different filter/custom rules
4. Step#4 Generate PDF from the FPR file (if required)
./ReportGenerator -format pdf -f '/local/proj/9999.pdf' -source '/local/proj/9999.fpr'

How to refer to the source directory in qmake?

I added
version.target = version.h
version.commands = bash generate-version.sh
QMAKE_EXTRA_TARGETS += version
PRE_TARGETDEPS += version.h
to the project, but it attempts to run "generate-version.sh" in destination directory:
make: Leaving directory `.../qqq-build-desktop'
make: Entering directory `.../qqq-build-desktop'
Makefile:236: warning: overriding commands for target `version.h'
Makefile:233: warning: ignoring old commands for target `version.h'
bash generate-version.sh
bash: generate-version.sh: No such file or directory
make: Leaving directory `.../qqq-build-desktop'
There is $$DESTDIR, but I don't see $$SRCDIR. How to refer to the project directory in qmake (or how to rewrite this)?
My first thought is to try to rewrite
version.commands = bash generate-version.sh
so as not to have to invoke a shell script. Perhaps you can combine all of the statements into one line:
version.commands = echo \'char VERSION[]=\"1.0\";\' > version.h && ls && echo Done
If you are stuck with invoking the script, probably PWD or OUT_PWD are what you are looking for. From the qmake Variable Reference
PWD
This variable contains the full path leading to the directory where the qmake project file (project.pro) is located.
OUT_PWD
This variable contains the full path leading to the directory where qmake places the generated Makefile.
The one caveat that is not mentioned in the documentation is that if you are doing a recursive qmake, PWD refers to where the top level .pro file was read from. Thus if you run qmake -r from {proj-root}, when sub/sub/sub/dir-proj.pro is finally read in, PWD will still point to {proj-root}.
Assuming that generate-version.sh is in the same directory as your top level .pro file, you might try:
version.commands = bash $$PWD/generate-version.sh
I found a better and cleaner solution
version.target = version.h
version.commands = bash ${QMAKE_VAR__PRO_FILE_PWD_}/generate-version.sh
QMAKE_EXTRA_TARGETS += version
The variable _PRO_FILE_PWD_ is documented since qt 4.5 and contains the path to the directory containing the project file in use (Contains the .pro file)
But to access this variable for QMAKE_EXTRA_TARGETS, QMAKE_VAR_ must be appended.
PWD
Specifies the full path leading to the directory containing the
current file being parsed. This can be useful to refer to files within
the source tree when writing project files to support shadow builds.
I use (Linux and g++)
DEFINES += SVN_VERSION=\\\"\""`svnversion $$PWD`\""\\\"
DEFINES += COMPILE_DATE=\\\"\""`date`\""\\\"
DEFINES += SW_VERSION=\\\"\"0.5\"\\\"
which defines the macro SVNVERSON to be the svn version.
To access it from C++:
QString svnVersion = SVN_VERSION;
QString swVersion = SW_VERSION;
Explanation: On the shell I want to see this call:
-DSVN_VERSION=\""`svnversion /path/to/my/source`"\"
As you see some escapes are necessary on shell level. In the .pro-file it then has to be escaped twice.
This works and is easy to understand.
version.commands = ( cd $${PWD}; generate-version.sh )

Resources