0

I have a server application on freebsd written in c++ and I want to add dtrace usdt in it. In order to be built properly, USDT probes require dtrace -G command to be run on all object files that contain probes. Than it generates object file that contains some dtrace functions, and the application should be linked with it. I was able to run dtrace this way, adding a custom command with PRE_LINK flag to my target:

add_executable(foo foo.cpp)
target_link_libraries(foo ${foo_libs})
add_custom_command(
  TARGET foo
  PRE_LINK
  COMMAND dtrace -G -s ${DTRACE_PROVIDER} 
    ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/*.o
    -o provider.o
  )

Than I have to link provider.o to my executable somehow, but I have no idea how to do it in a clean way, if I add it as a dependency to foo:

add_executable(foo foo.cpp)
target_link_libraries(foo ${foo_libs} provider.o)

build fails before provider.o is generated. Adding another fake target is not and option, because it looks like (the documentation is realy poor) dtrace must be also run on the object file that contains main, or it will not be able to register its probes in the system when application starts. Any ideas how to do it? Or maybe it is possible to add sdt probes without patching object files?

Update:

[ 84%] Building CXX object proxy/CMakeFiles/proxy-lib.dir/src/Server.cpp.o
cd /home/pablo/engine/Debug/proxy && /usr/bin/CC -DBOOST_LOG_DYN_LINK -DBOOST_LOG_USE_NATIVE_SYSLOG 
  -DLIBNET_LIL_ENDIAN -std=c++1y -march=native -mtune=native -Wall -pthread -fno-omit-frame-pointer 
  -ggdb3 -O0 -DDEBUG -I/home/pablo/engine/dependencies/asio/include 
  -I/usr/local/include -I/usr/local/include/mysql++ -I/usr/local/include/mysql -I/home/pablo/engine/Debug/UU4/proto 
  -I/home/pablo/engine/common -I/home/pablo/engine -I/home/pablo/engine/proxy/src -I/home/pablo/engine/proxy/test 
  -o CMakeFiles/proxy-lib.dir/src/Server.cpp.o -c /home/pablo/engine/proxy/src/Server.cpp
Linking CXX executable ../server
perform dtrace binary update on files in /home/pablo/engine/Debug/proxy/CMakeFiles/server.dir
cd /home/pablo/engine/Debug/proxy && rm /home/pablo/engine/Debug/proxy/CMakeFiles/server.dir/src/Provider.cpp.o || true
cd /home/pablo/engine/Debug/proxy && dtrace -G -s /home/pablo/engine/proxy/src/Provider.d 
  /home/pablo/engine/Debug/proxy/CMakeFiles/server.dir/*/*.cpp.o -o /home/pablo/engine/Debug/proxy/CMakeFiles/server.dir/src/Provider.cpp.o
cd /home/pablo/engine/Debug/proxy && /usr/local/bin/cmake -E cmake_link_script CMakeFiles/server.dir/link.txt --verbose=1
/usr/bin/CC   -std=c++1y -march=native -mtune=native -Wall -pthread -fno-omit-frame-pointer -ggdb3 
  -O0 -DDEBUG    CMakeFiles/server.dir/src/main.cpp.o CMakeFiles/server.dir/src/ConfigParser.cpp.o CMakeFiles/server.dir/src/Connection.cpp.o 
  CMakeFiles/server.dir/src/ConnectionManager.cpp.o CMakeFiles/server.dir/src/Delegate.cpp.o CMakeFiles/server.dir/src/Request.cpp.o CMakeFiles/server.dir/src/Provider.cpp.o 
  CMakeFiles/server.dir/src/Server.cpp.o  -o ../server  -L/usr/local/lib  ../common/libcommon.a ../proto/libproto.a -lpthread -ltbb /usr/local/lib/libboost_filesystem.so 
  /usr/local/lib/libboost_system.so /usr/local/lib/libboost_unit_test_framework.so /usr/local/lib/libboost_timer.so /usr/local/lib/libboost_program_options.so 
  /usr/local/lib/libboost_regex.so /usr/local/lib/libboost_thread.so /usr/local/lib/mysql/libmysqlclient.so /usr/local/lib/libmysqlpp.so /usr/local/lib/libprotobuf-lite.a 
  /usr/local/lib/libprotobuf.a /usr/local/lib/libsnappy.so /usr/local/lib/libevent.so -lelf -Wl,-rpath,/usr/local/lib:/usr/local/lib/mysql: 
Pavel Davydov
  • 3,379
  • 3
  • 28
  • 41
  • What generator do you use? If it's unix makefiles, then run with the VERBOSE env variable set to 1 and attach the output. What version of cmake do you use? – Kentzo Feb 11 '15 at 05:17
  • @Kentzo I managed to make it work now, with a dirty hack. I created an empty provider.cpp, that is compiled to an empty provider.cpp.o, and then is overriden by PRE_LINK hook output file. Do you know a better way to do it? My cmake version is 2.8.12, I use makefiles. – Pavel Davydov Feb 11 '15 at 08:52
  • I need to take a look at the output of makefiles. Try `add_executable(foo foo.cpp provider.o). You may also specify that provider.o is the result of add_custom_command by specifying OUTPUT. – Kentzo Feb 11 '15 at 10:05
  • @Kentzo please, see my update. I'm afraid setting OUTPUT is not an option, cause it is not available for PRE_LINK custom command ([see the second signature](http://www.cmake.org/cmake/help/v3.0/command/add_custom_command.html)). – Pavel Davydov Feb 11 '15 at 15:10
  • If you can add provider.o to add_executable, you do not need PRE_LINK. CMake should figure out when to execute you custom command before its OUTPUT is actually needed. – Kentzo Feb 11 '15 at 18:52

0 Answers0