CMake不链接C和C ++静态库(对函数的未定义引用)

时间:2018-08-07 11:21:48

标签: c++ c cmake

我试图重现最小的问题。在Ubuntu上运行CMake + Make时出现错误

funccpp.cpp:(.text+0x5): undefined reference to `FuncC'

即在C ++库中导入时,找不到C库中的导出函数。当我尝试使用g++ main.cpp funcc.c funccpp.cpp进行手动编译时,它将成功编译最终程序。如何解决CMake问题?

作为参考,当我运行nm libfuncc_lib.a时,我得到了T FuncC行(因此符号在外部,并在“文本”部分中定义),当我运行nm libfunccpp_lib.a时,我得到了U FuncC(因此符号是未定义的,应该从外部链接。)

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

project(Test C CXX)

set (SRC_CPP funccpp.cpp)
set (SRC_C funcc.c)
set (SRC_MAIN main.cpp)

add_library(funcc_lib STATIC ${SRC_C})
add_library(funccpp_lib STATIC ${SRC_CPP})
add_executable(prog ${SRC_MAIN})
target_link_libraries(prog funcc_lib funccpp_lib)

main.cpp

#include "funccpp.h"

int main() {
    FuncCPP();
    return 0;
}

funccpp.h

#ifndef FUNCCPP_H
#define FUNCCPP_H

void FuncCPP();

#endif

funccpp.cpp

#include "funcc.h"

void FuncCPP() {
    FuncC();
}

funcc.h

#ifndef FUNCC_H
#define FUNCC_H

#ifdef __cplusplus
extern "C" {
#endif

void FuncC();

#ifdef __cplusplus
}
#endif

#endif // FUNCC_H

funcc.c

#include "funcc.h"
#include <stdio.h>

void FuncC() {
    printf("Hello, World!\n");
}

2 个答案:

答案 0 :(得分:2)

这里的问题是,链接器依赖于库的顺序。使用

target_link_libraries(prog funcc_lib funccpp_lib)

它首先链接funcc_lib,然后链接funccpp_lib。但是它永远不会回到funcc_lib。由于funccpp_lib依赖于funcc_lib,因此您必须更改库的顺序:

target_link_libraries(prog funccpp_lib funcc_lib)

For additional information, see this discussion.

答案 1 :(得分:0)

将cmake c link命令设为c ++逗号即可解决问题

java.lang.Exception: [worker-1-8] Blocking call: sun.misc.Unsafe#park
 at reactor.blockhound.BlockHound$Builder.lambda$install$6(BlockHound.java:318)
 at reactor.blockhound.BlockHoundRuntime.checkBlocking(BlockHoundRuntime.java:46)
 at sun.misc.Unsafe.park(Unsafe.java)
 at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
 at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
 at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
 at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
 at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
 at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
 at com.lmax.disruptor.TimeoutBlockingWaitStrategy.signalAllWhenBlocking(TimeoutBlockingWaitStrategy.java:62)
 at com.lmax.disruptor.MultiProducerSequencer.publish(MultiProducerSequencer.java:218)
 at com.lmax.disruptor.RingBuffer.translateAndPublish(RingBuffer.java:990)
 at com.lmax.disruptor.RingBuffer.tryPublishEvent(RingBuffer.java:538)
 at org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor.tryEnqueue(AsyncLoggerConfigDisruptor.java:392)
 at org.apache.logging.log4j.core.async.AsyncLoggerConfig.logToAsyncDelegate(AsyncLoggerConfig.java:135)
 at org.apache.logging.log4j.core.async.AsyncLoggerConfig.log(AsyncLoggerConfig.java:116)
 at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:460)
 at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:82)
 at org.apache.logging.log4j.core.Logger.log(Logger.java:162)
 at org.apache.logging.log4j.spi.AbstractLogger.tryLogMessage(AbstractLogger.java:2190)
 at org.apache.logging.log4j.spi.AbstractLogger.logMessageTrackRecursion(AbstractLogger.java:2144)
 at org.apache.logging.log4j.spi.AbstractLogger.logMessageSafely(AbstractLogger.java:2127)
 at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:2020)
 at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1891)
 at org.apache.logging.slf4j.Log4jLogger.info(Log4jLogger.java:184)