【问题标题】:cmake add_library doesn't initialize static global variablecmake add_library 不初始化静态全局变量
【发布时间】:2019-09-06 20:19:17
【问题描述】:

我有两个源文件,main.cc,foo.cc。

#include <iostream>

using namespace std;

int main() {

    cout << "main\n";
}

foo.cc

#include <iostream>

using namespace std;

class foo {
public:
    foo() {
        cout << "foo ctor\n";
    }
};

static foo foo_obj;

当我像这样手动编译时:

$ g++ -c foo.cc -o libfoo.a

$ g++ main.cc libfoo.a -o main

$ ./main

foo ctor

主要

但是当我使用 cmake 时,它​​不会打印 foo ctor。这是 CMakeLists.txt:

cmake_minimum_required(VERSION 3.2)

set(CMAKE_CXX_FLAGS "-std=c++11")

add_library(foo STATIC foo.cc)

add_executable(main main.cc)
target_link_libraries(main foo)

显然 cmake 做了一些我没想到的事情。

【问题讨论】:

  • @πάντα ῥεῖ 我认为这不是同一个问题。我不是在询问整个 TU 的初始化顺序。我的问题与一些 cmake 问题有关,比较我的手动操作的结果。
  • 这不是同一个问题没关系,但你会在那里找到答案。不能保证std::cout 将在foo_obj 之前初始化。顺便说一句,与 CMake 无关。
  • @Lewis - 你将不得不检查 Cmake 生成的 makefile。没有其他方法可以调试它。
  • 原来cmake通过ar qc libfoo.a foo.cc生成libfoo.a,导致出现上述情况。 @StoryTeller @πάνταῥεῖ 谢谢。
  • 命令行g++ -c foo.cc -o libfoo.a 不会创建静态库。结果文件只是一个对象,因此最好将其命名为foo.o。但是使用命令add_library CMake 实际上使用ar 命令创建了一个静态库。 (使用完整的命令ar qc libfoo.a foo.o,而不是您在评论中提到的foo.cc)。

标签: c++ cmake


【解决方案1】:

事实证明,-Wl,--whole-archive 可以用来避免这种情况。比如这样写:

target_link_libraries(main 
  "-Wl,--whole-archive"
  foo
  "-Wl,--no-whole-archive"
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 2013-09-03
    • 2019-04-23
    相关资源
    最近更新 更多