Cách thành ngữ trong CMAKE để thêm tùy chọn trình biên dịch -fPIC là gì?


119

Tôi đã xem qua ít nhất 3 cách để làm điều này và tôi đang tự hỏi đâu là cách thành ngữ. Điều này cần được thực hiện gần như phổ biến đối với bất kỳ thư viện tĩnh nào. Tôi ngạc nhiên rằng trình tạo Makefile trong CMake không tự động thêm nó vào các thư viện tĩnh. (trừ khi tôi thiếu thứ gì đó?)

target_compile_options(myLib PRIVATE -fPIC)

add_compile_options(-fPIC)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fpic")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpic")

Tôi tin rằng cũng có thể có các biến thể khác. (vui lòng chỉnh sửa câu hỏi của tôi nếu bạn tìm thấy)

Nếu bạn tình cờ biết câu trả lời cho câu hỏi này, bạn cũng biết liệu có cách nào khiến dự án CMake của bên thứ 3 được biên dịch với cờ này mà không sửa đổi tệp CMakeLists.txt của nó không? Tôi đã chạy qua các thư viện tĩnh thiếu cờ đó. Nó gây ra sự cố khi biên dịch thư viện tĩnh thành thư viện động.

Bạn lấy:

relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC

điều này set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpic")đã làm việc cho tôi.
Barracuda

Câu trả lời:


179

Bạn có thể đặt thuộc tính mã độc lập vị trí trên tất cả các mục tiêu:

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

hoặc trong một thư viện cụ thể:

add_library(lib1 lib1.cpp)
set_property(TARGET lib1 PROPERTY POSITION_INDEPENDENT_CODE ON)

Tham khảo: CMAKE_POSITION_INDEPENDENT_CODE hệ thống xây dựng cmake


Phương pháp thứ hai dường như cũng là cách phù hợp để thêm nó vào lib của bên thứ ba. Hoàn hảo.
010110110101

Hrm - Tôi tự hỏi làm thế nào bạn sẽ thêm nó vào một dự án được thêm bởi ExternalProject_Add?
010110110101

2
@ 010110110101 Tôi không biết nếu nó hoạt động, nhưng bạn có thể thử xác định, tại ExternalProject_Add với tùy chọnCMAKE_CACHE_ARGS "-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true"
Amadeus

12
Các CMAKE_POSITION_INDEPENDENT_CODEtài sản được thiết lập theo mặc định cho SHAREDmục tiêu, không có cần phải cài đặt nó một cách rõ ràng.
robert

1
@Carbon nếu bạn đang sử dụng setlệnh (phiên bản đầu tiên ở trên) thì không. Nếu bạn đang sử dụng phiên bản thứ hai, đó là trên mỗi thư viện, không phải cho mỗi thư mục.
Patrickvacek
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.