The current build procedure for 'make use=dtrace' is working
correctly for OS X and Linux+SystemTap because both are hybrids
compared to the original Solaris implementation. FreeBSD's
implementation is very close to Solaris's.
The original implemntation requires a two-stage process for compiling
the USDT probe specification file, e.g., `src/common/dtrace_probes.d`).
The first stage, `dtrace -h`, creates the C header file prerequisite
for compilation. The second stage, `dtrace -G`, analyzes the object
files for DTrace probe data and creates a new object file that must
also be linked into the executable.
The `Makefile` procedure for the second stage for Linux is apparently
sufficient for Linux+SystemTap but isn't sufficient for FreeBSD.
The FreeBSD linker does not automatically add the `dtrace_probes.o`
object file to its workflow. (Presumably Linux's linker does.) The
result are these errors at linking time, using the command
`gmake use=dtrace verbose=true`:
Linking ponyc
c++ -o build/release-dtrace/ponyc build/release-dtrace/obj/ponyc/main.o -march=native -mtune=generic -mcx16 -L build/release-dtrace -L /usr/local/lib -L/usr/local/llvm39/lib -lponyc -lponyrt -lLLVMLTO -lLLVMObjCARCOpts -lLLVMSymbolize -lLLVMDebugInfoPDB -lLLVMDebugInfoDWARF -lLLVMMIRParser -lLLVMCoverage -lLLVMTableGen -lLLVMOrcJIT -lLLVMXCoreDisassembler -lLLVMXCoreCodeGen -lLLVMXCoreDesc -lLLVMXCoreInfo -lLLVMXCoreAsmPrinter -lLLVMSystemZDisassembler -lLLVMSystemZCodeGen -lLLVMSystemZAsmParser -lLLVMSystemZDesc -lLLVMSystemZInfo -lLLVMSystemZAsmPrinter -lLLVMSparcDisassembler -lLLVMSparcCodeGen -lLLVMSparcAsmParser -lLLVMSparcDesc -lLLVMSparcInfo -lLLVMSparcAsmPrinter -lLLVMPowerPCDisassembler -lLLVMPowerPCCodeGen -lLLVMPowerPCAsmParser -lLLVMPowerPCDesc -lLLVMPowerPCInfo -lLLVMPowerPCAsmPrinter -lLLVMNVPTXCodeGen -lLLVMNVPTXDesc -lLLVMNVPTXInfo -lLLVMNVPTXAsmPrinter -lLLVMMSP430CodeGen -lLLVMMSP430Desc -lLLVMMSP430Info -lLLVMMSP430AsmPrinter -lLLVMMipsDisassembler -lLLVMMipsCodeGen -lLLVMMipsAsmParser -lLLVMMipsDesc -lLLVMMipsInfo -lLLVMMipsAsmPrinter -lLLVMHexagonDisassembler -lLLVMHexagonCodeGen -lLLVMHexagonAsmParser -lLLVMHexagonDesc -lLLVMHexagonInfo -lLLVMBPFCodeGen -lLLVMBPFDesc -lLLVMBPFInfo -lLLVMBPFAsmPrinter -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMARMInfo -lLLVMARMAsmPrinter -lLLVMAMDGPUDisassembler -lLLVMAMDGPUCodeGen -lLLVMAMDGPUAsmParser -lLLVMAMDGPUDesc -lLLVMAMDGPUInfo -lLLVMAMDGPUAsmPrinter -lLLVMAMDGPUUtils -lLLVMAArch64Disassembler -lLLVMAArch64CodeGen -lLLVMGlobalISel -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter -lLLVMAArch64Utils -lLLVMObjectYAML -lLLVMLibDriver -lLLVMOption -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMDebugInfoCodeView -lLLVMX86Desc -lLLVMMCDisassembler -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMMCJIT -lLLVMLineEditor -lLLVMPasses -lLLVMipo -lLLVMVectorize -lLLVMLinker -lLLVMIRReader -lLLVMAsmParser -lLLVMInterpreter -lLLVMExecutionEngine -lLLVMRuntimeDyld -lLLVMObject -lLLVMMCParser -lLLVMCodeGen -lLLVMTarget -lLLVMScalarOpts -lLLVMInstCombine -lLLVMInstrumentation -lLLVMTransformUtils -lLLVMMC -lLLVMBitWriter -lLLVMBitReader -lLLVMAnalysis -lLLVMProfileData -lLLVMCore -lLLVMSupport -lz -lncurses -lpthread -lexecinfo -lblake2 -rdynamic
build/release-dtrace/libponyrt.a(trace.o): In function `pony_gc_send':
src/libponyrt/gc/trace.c:(.text+0x19): undefined reference to `__dtrace_pony___gc__send__start'
build/release-dtrace/libponyrt.a(trace.o): In function `pony_gc_recv':
src/libponyrt/gc/trace.c:(.text+0x39): undefined reference to `__dtrace_pony___gc__recv__start'
build/release-dtrace/libponyrt.a(trace.o): In function `pony_send_done':
src/libponyrt/gc/trace.c:(.text+0xd1): undefined reference to `__dtrace_pony___gc__send__end'
build/release-dtrace/libponyrt.a(trace.o): In function `pony_recv_done':
src/libponyrt/gc/trace.c:(.text+0x109): undefined reference to `__dtrace_pony___gc__recv__end'
build/release-dtrace/libponyrt.a(heap.o): In function `ponyint_heap_setnextgcfactor':
src/libponyrt/mem/heap.c:(.text+0x5a): undefined reference to `__dtrace_pony___gc__threshold'
[... 54 additional lines of output omitted ...]
AFAICT, the Pony compiler gives the linker several `-L` flags in to
specify where `libponyrt.a` and perhaps other library files may
be stored: in the `ponyc` repo, or in the `make install` destination
directory. If we tell the linker to link `dtrace_probes.o`
directly, then we need to give a correct, full path to it.
However, if we put `dtrace_probes.o` into a library, then we can
let the linker search its list of directories (one of them will be
good).
To force the linker to read & use the data in the new shared
library, `libdtrace_probes.a`, I've also added the flag
`-Wl,--whole-archive` to the linker's command line. (NOTE: using
the `--whole-archive` trick on the entire `libponyrt.a` library
had some side effects that IMHO makes it worthwhile to put the
DTrace stuff into a new library file. If PR review really does
not like the new library file, please say so.)