调用链接程序时是否可以强制CMake重新排列参数?

时间:2018-09-02 19:52:04

标签: c++ cmake

我有一个奇怪的行为,如果需要动态链接,CMake无法链接任何可执行文件。 g ++无法找到库中定义的任何符号。

我发现链接时可能与CMake传递给g ++的参数顺序有关。

这是构建过程的详细输出(链接失败):

g++   -std=c++11 CMakeFiles/test.dir/test.cpp.obj  -o mytest -lSDL2 

实际上,如果我尝试使用该命令进行链接,则会得到未定义的引用,但是如果我在末尾使用库标志进行编译:

cmake_minimum_required(VERSION 3.6)

project(mytest)

set(COMPILER_PATH "/usr/bin/")
set(CMAKE_MAKE_PROGRAM "make")
set(CMAKE_C_COMPILER   "gcc")
set(CMAKE_CXX_COMPILER "g++")

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lSDL2")
set(SOURCE_FILES test.cpp)
add_executable(mytest ${SOURCE_FILES})

它运行正常。我该如何强制CMake改用该顺序的参数?

CMakeLists.txt的内容:

@implementation AppDelegate
{
    UIDeviceOrientation _orientation;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    UIDevice *device = [UIDevice currentDevice];
    _orientation = device.orientation;
    [[NSNotificationCenter defaultCenter] addObserverForName:UIDeviceOrientationDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
        // setting _orientation happens on the main thread
        _orientation = device.orientation;
    }];

    return YES;
}

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
    // accessing _orientation on a background queue
    [self _doStuffWithBuffer:sampleBuffer orientation:_orientation];
}

@end

1 个答案:

答案 0 :(得分:0)

您可能已将 -lSDL2 添加到CMAKE_CXX_FLAGS中。在这种情况下,如您所显示的,它将在实际链接命令中的源文件名之前带有编译/链接标志。不要那样做。

您应使用_target_link_libraries_ cmake命令来定义要链接的库。简而言之,您的CMakeLists.txt的框架应如下所示:

project (project_name)

add_executable (mytest test.cpp)
target_link_libraries( mytest SDL2)

在这种情况下,cmake会将库放置在正确的位置。请注意,您可以在添加目标mytest之后使用target_link_libraries

[编辑]

看到您的CMakeLists后,很明显您的问题出在错误的CMAKE_EXE_LINKER_FLAGS上。只需删除设置它的行,然后在add_executable之后添加target_link_libraries。

关于处理静态库之间的循环依赖关系的问题,您可以使用sam方式来处理它,就像您不使用cmake一样:提两次:

target_link_libraries( 
    mytest 
    circular_dep1
    circular_dep2
    circular_dep1
    circular_dep2
)

关于特定链接器标志的问题,只需将它们放入target_link_libraries命令中,它也接受链接器标志。您可以在以下链接中找到文档:

https://cmake.org/cmake/help/latest/command/target_link_libraries.html