Ubuntu14使用的g++版本比CentOS6使用的版本更严格。幸运的是,g++ 很好地提示了问题所在。
/usr/bin/ld: USRP_UHD-USRP_UHD.o: 未定义对符号 'uuid_generate_random@@UUID_1.0' 的引用 //lib/x86_64-linux-gnu/libuuid.so.1: 添加符号时出错:命令行中缺少 DSO
它基本上是在说“你想要的在 libuuid.so.1 中,但你没有把它放在命令行上,所以我拒绝使用它”。而在 CentOS6 中,g++ 不那么严格,并且无论如何都链接,假设这是您想要的。
您有两种选择,一种是快速有效的简单方法,一种是更好的长期解决方案:
1) 在详细模式下再次运行 make,这将准确显示正在进行的调用,并且您可以修复有问题的调用。让我们在下面这样做:
make V=1
< ... a bunch of calls to g++ that work fine or nothing if these have already run prior .... >
g++ -Wall -D__x86_64__ -D__linux__ -D__OSVERSION__=2 -DENABLE_EVENTS=1 -I/var/lib/redhawk/core/include -I/var/lib/redhawk/core/include/ossie -I/var/lib/redhawk/core/share/idl -pthread -I/usr/include -I/var/lib/redhawk/core/include/frontend -I/var/lib/redhawk/core/include/redhawk -I/var/lib/redhawk/core/include/bulkio -I/var/lib/redhawk/core/include/ossie -g -O2 -Wall -o USRP_UHD USRP_UHD-USRP_UHD.o USRP_UHD-USRP_UHD_base.o USRP_UHD-main.o USRP_UHD-template_impl.o -L/var/lib/redhawk/core/lib64 -lossiecf -lossieidl -lCOS4 -lomniDynamic4 -lomniORB4 -lomnithread -L/usr/lib/x86_64-linux-gnu -lboost_thread -lboost_regex -lboost_system -L/var/lib/redhawk/core/lib64 -lfrontend-2.2.0 -lfrontendInterfaces -lbulkio-1.10 -lbulkioInterfaces -luhd -llog4cxx
/usr/bin/ld: USRP_UHD-USRP_UHD.o: undefined reference to symbol 'uuid_generate_random@@UUID_1.0'
//lib/x86_64-linux-gnu/libuuid.so.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make: *** [USRP_UHD] Error 1
好的,现在我们有了长而丑陋的 g++ 调用,我们只需将“-luuid”添加到链接库列表中,这样我们就可以在最后加上它,瞧!它会毫无错误地返回。请注意,我们只是手动运行了 1 个 g++ 调用,因此为了更好地测量再次运行 Make,以防有任何额外的构建步骤;在这种情况下没有,它只会说“无事可做”
2)更好的修复!所以构建文件显然需要一些修复。
如果我们看一下 configure.ac,我们会发现有这样的调用:
PKG_CHECK_MODULES([LIBUHD], [uhd >= 3.5.3])
这样做是说“检查模块 uhd 的 pkg-config,确保它的版本 >= 3.5.3 并将任何与构建相关的信息存储在以 LIBUHD 为前缀的变量中,以便我以后可以使用它”。听起来像我们想要的。我们可以通过查看它知道的所有包来检查 pkg-config 是否知道 libuuid:
pkg-config --list-all
这将向我们展示 pkg-config 所知道的一切,并且我们看到它知道 uuid。因此,让我们在检查 UHD 驱动程序下方的 configure.ac 中添加一行,看看有什么影响。我的线如下所示:
PKG_CHECK_MODULES([LIBUUID], [uuid])
我没有设置版本限制。好的,现在为了合并该更改,我们需要重新运行 reconf 脚本,然后我们可以看到配置输出。
./reconf
./configure
<....a bunch of stuff....>
checking for LIBUUID... yes
<....a bunch more stuff....>
那是新的!我们现在正在我们的配置调用中检查 uuid 库,如果您查看 config.log 文件,则添加了新变量:
LIBUID_CFLAGS='-I/usr/include/uuid'LIBUUID_LIBS='-luuid'
好了,差不多了!查看 Makefile.am 文件。这些变量在那里使用并指示对 g++ 的调用。将我们新创建的 LIBUUID_CFLAGS 和 LIBUUID_LIBS 变量附加到 USRP_UHD_LDADD 和 USRP_UHD_CXXFLAGS 变量的末尾,就像我在下面所做的那样。
USRP_UHD_LDADD = $(PROJECTDEPS_LIBS) $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(INTERFACEDEPS_LIBS) $(redhawk_LDADD_auto) $(LIBUHD_LIBS) $(LIBUUID_LIBS)
USRP_UHD_CXXFLAGS = -Wall $(PROJECTDEPS_CFLAGS) $(BOOST_CPPFLAGS) $(INTERFACEDEPS_CFLAGS) $(redhawk_INCLUDES_auto) $(LIBUHD_FLAGS) $(LIBUUID_CFLAGS)
由于我们更改了 Makefile.am 文件,我们需要重新运行 ./configure。经验法则是 ./reconf 从 configure.* 文件创建您的配置脚本,而 ./configure 从您的 Makefile.* 文件创建 Makefile,因此如果您编辑下游文件,则需要重新运行上游脚本。
好吧,既然我们已经完成了,事情应该可以工作了!我们通过 pkg-config 使用 configure.ac 文件添加了对 libuuid 的系统检查,将结果存储在一个变量中并在我们的 makefile 模板中使用它。
这些都不是 redhawk 真正独有的,所以如果您想了解更多信息,可以在 autotools 构建系统和 pkg-config 上找到大量文档。