0

我已经看到了一些答案,但其中大多数对我不起作用。所以我想通过添加一个新问题来澄清一切,我CMakeLists.txt是这样的:

cmake_minimum_required(VERSION 3.17)
project(example)

include_directories(./)
link_directories(./)

if (CMAKE_COMPILER_IS_GNUCXX)
    set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Os -g ${CMAKE_CXX_FLAGS}")
    message("CMAKE_COMPILER_IS_GNUCXX is True")
    message("option is: ${CMAKE_CXX_FLAGS}")
endif (CMAKE_COMPILER_IS_GNUCXX)




add_executable(main try.cpp)
target_link_libraries(main  fun)
set_property(TARGET main PROPERTY POSITION_INDEPENDENT_CODE 1 LINK_FLAGS -pie)

add_library(fun SHARED func.cpp)
# target_compile_options(fun PUBLIC "-pie")
target_link_libraries(fun PUBLIC "-pie")
set_property(TARGET fun PROPERTY POSITION_INDEPENDENT_CODE 1)

源代码try.cpp是:

#include<iostream>
#include "func.hpp"

int main() {
    using namespace std;
    cout << "hello from exe main" << endl;

    func();
    return 0;
}

fun.cpp和的代码fun.hpp是这样的:

// func.hpp
void func();

// func.cpp
#include <iostream>

using std::cout;
using std::endl;

void func() {
    cout << "hell from so func\n";
}


int main() {
    cout << "hello from so main\n";
    return 0;
}

我的问题是:使用 cmake 编译时出现以下链接错误:

Scanning dependencies of target fun
[ 25%] Building CXX object CMakeFiles/fun.dir/func.cpp.o
[ 50%] Linking CXX shared library libfun.so
[ 50%] Built target fun
Scanning dependencies of target main
[ 75%] Building CXX object CMakeFiles/main.dir/try.cpp.o
[100%] Linking CXX executable main
/usr/bin/ld: CMakeFiles/main.dir/try.cpp.o: in function `main':
/home/coin/learn-coding/projects/C/cmake/try.cpp:8: undefined reference to `func()'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/main.dir/build.make:105: main] Error 1
make[1]: *** [CMakeFiles/Makefile2:125: CMakeFiles/main.dir/all] Error 2
make: *** [Makefile:104: all] Error 2

配置有什么问题,我怎样才能让它工作?

顺便说一句,我尝试用命令行编译:

g++ -fPIC -pie  func.cpp -o libfun.so -shared
g++ try.cpp -o main -L. -lfun

当我运行 generated 时,它确实有效main,但生成的 so 文件无法运行:

$ ./main
hello from exe main
hell from so func
$ ./libfun.so
Segmentation fault (core dumped)

我在这里错过了什么?

4

1 回答 1

1

以下文件基于此答案

cat >CMakeLists.txt <<EOF
cmake_minimum_required(VERSION 3.17)
project(example)

if(CMAKE_COMPILER_IS_GNUCXX)
    add_compile_options(
        $<$<COMPILE_LANGUAGE:CXX>:-std=c++11>
        -Wall
        -Os
        -g
    )
endif()

add_executable(main try.cpp)
target_link_libraries(main PRIVATE fun)

add_library(fun SHARED func.cpp)
target_link_options(fun PRIVATE -Wl,-e,entry_point)


EOF

cat >func.cpp <<EOF
// func.hpp
void func();

// func.cpp
#include <iostream>

using std::cout;
using std::endl;

void func() {
    cout << "hell from so func\n";
}


static inline
int lib_main() {
    printf("hello from so main\n");
    return 0;
}

extern "C" const char interp_section[] __attribute__((section(".interp"))) = "/lib64/ld-linux-x86-64.so.2";

extern "C" void entry_point()
{
    lib_main();
    exit(0);
}

EOF

cat >try.cpp <<EOF
#include<iostream>
void func();
int main() {
    using namespace std;
    cout << "hello from exe main" << endl;

    func();
    return 0;
}
EOF

在我的 64 位系统上使用 glibc 编译时,它会生成两个可执行文件:

$ cmake -S . -B _build && cmake --build _build -- VERBOSE=1 
balbla compilation output
$ _build/main
hello from exe main
hell from so func
$ _build/libfun.so
hello from so main

我替换std::cout为,printf因为我收到了分段错误-我怀疑全局构造函数没有运行,并且 iostream 析构函数中的某些内容使其发生分段错误。

我认为添加并没有意义LINK_FLAGS -pie)target_link_libraries(fun PUBLIC "-pie")它是用POSITION_INDEPENDENT_CODE属性处理的,我想对于共享库来说TRUE无论如何都是这样(但我不确定)。

于 2020-07-07T08:40:01.590 回答