2016-03-23 31 views
11

Khi sử dụng CMake để biên dịch chéo, người ta thường chỉ định một tệp chuỗi công cụ thông qua tùy chọn CMAKE_TOOLCHAIN_FILE. Trong GNU terminology, người ta có thể chỉ định bộ công cụ kiến ​​trúc máy chủ lưu trữ bằng cách sử dụng tệp này. Tuy nhiên, người ta thường có thể không mong đợi để có thể thực hiện bất cứ điều gì được xây dựng với toolchain này. Vì vậy, thường xuyên, một số công cụ xây dựng cần phải được biên dịch cho kiến ​​trúc xây dựng.Làm thế nào để hướng dẫn CMake sử dụng trình biên dịch kiến ​​trúc xây dựng?

Hãy xem xét thiết lập sau. Tôi có hai tệp nguồn genfoo.cbar.c. Trong khi xây dựng, genfoo.c cần được biên dịch và chạy. Đầu ra của nó cần phải được ghi vào foo.h. Sau đó, tôi có thể biên dịch bar.c, trong đó #include "foo.h". Vì CMake mặc định sử dụng chuỗi công cụ kiến ​​trúc máy chủ, các hướng dẫn cho bar.c rất dễ dàng. Nhưng làm thế nào để tôi nói nó sử dụng chuỗi công cụ kiến ​​trúc xây dựng để biên dịch genfoo.c? Chỉ cần nói add_executable(genfoo genfoo.c) sẽ dẫn đến việc sử dụng trình biên dịch sai.

+0

Như bạn có đã nêu, trong thuật ngữ GNU bạn sẽ sử dụng lệnh 'configure' để chỉ định kiến ​​trúc máy chủ. Và bạn sẽ phải chạy 'configure' hai lần nếu bạn muốn xây dựng cho hai môi trường máy chủ khác nhau. Vì vậy, tôi thấy hai khả năng với CMake: sử dụng một kịch bản xây dựng để tạo và thực thi hai môi trường cần thiết (xem [ở đây] (http://stackoverflow.com/questions/30999130/cmake-build-multiple-targets-in-different- build-directories)) hoặc sử dụng [ExternalProject_Add()] (https://cmake.org/cmake/help/v3.2/module/ExternalProject.html) và chia 'CMakeLists.txt' của bạn thành các tiểu dự án chuyên dụng. – Florian

+0

Không, với autotools bạn chỉ cần sử dụng 'CC_FOR_BUILD'. Xem 'ax_cc_for_build'. – Helmut

+0

Ok, không biết điều đó. Nếu tôi hiểu chính xác, chúng ta đang nói về ca sử dụng được mô tả trong [Biên dịch ghép CMake - Sử dụng các tệp thi hành trong bản dựng được tạo trong khi xây dựng] (https://cmake.org/Wiki/CMake_Cross_Compiling#Using_executables_in_the_build_created_during_the_build)? – Florian

Trả lời

7

Biến ý kiến ​​của tôi vào một câu trả lời

CMake chỉ có thể xử lý một trình biên dịch tại một thời điểm. Vì vậy, nếu bạn không đi một chặng đường dài để thiết lập trình biên dịch khác như một ngôn ngữ mới - bạn sẽ kết thúc với hai chu kỳ cấu hình.

tôi thấy các phương pháp sau đây để tự động hóa quá trình này:

  1. Lấy ví dụ "CMake Cross Compiling - Using executables in the build created during the build?" từ các trang CMake như là một điểm khởi đầu, tôi sẽ nhận được:

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.0) 
    project(FooBarTest) 
    
    # when crosscompiling import the executable targets 
    if (CMAKE_CROSSCOMPILING) 
        set(IMPORT_PATH "IMPORTFILE-NOTFOUND" CACHE FILEPATH "Point it to the export file path from a native build") 
        file(TO_CMAKE_PATH "${IMPORT_PATH}" IMPORT_PATH_CMAKE) 
        include(${IMPORT_PATH_CMAKE}/genfooTargets.cmake) 
    
        # then use the target name as COMMAND, CMake >= 2.6 knows how to handle this 
        add_custom_command(
         OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.h 
         COMMAND genfoo 
        ) 
    
        add_executable(bar bar.cpp ${CMAKE_CURRENT_BINARY_DIR}/foo.h) 
        target_include_directories(bar PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) 
    endif() 
    
    # only build the generator if not crosscompiling 
    if (NOT CMAKE_CROSSCOMPILING) 
        add_executable(genfoo genfoo.cpp) 
        export(TARGETS genfoo FILE "${CMAKE_CURRENT_BINARY_DIR}/genfooTargets.cmake") 
    endif() 
    

    Sau đó, sử dụng tập lệnh như:

    build.sh

    #!/bin/bash 
    
    if [ ! -d hostBuild ]; then 
        cmake -E make_directory hostBuild 
        cmake -E chdir hostBuild cmake .. 
    fi 
    cmake --build hostBuild 
    
    if [ ! -d crossBuild ]; then 
        cmake -E make_directory crossBuild 
        cmake -E chdir crossBuild cmake .. -DIMPORT_PATH=${PWD}/hostBuild -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake 
    fi 
    cmake --build crossBuild 
    

    tôi sẽ có được kết quả mong muốn bằng cách gọi ./build.sh

  2. Splitting các CMakeLists.txt và thậm chí có thể thay thế các export()/include() với một cái gì đó mà tôi biết đường dẫn đầu ra của tôi xây dựng các công cụ ví dụ bằng cách sử dụng CMAKE_RUNTIME_OUTPUT_DIRECTORY sẽ đơn giản hóa mọi thứ:

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.0) 
    project(FooBarTest) 
    
    # then use the target name as COMMAND, CMake >= 2.6 knows how to handle this 
    add_custom_command(
        OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.h 
        COMMAND genfoo 
    ) 
    
    add_executable(bar bar.cpp ${CMAKE_CURRENT_BINARY_DIR}/foo.h) 
    target_include_directories(bar PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) 
    

    buildTools/CMakeLists.txt

    cmake_minimum_required(VERSION 3.0) 
    project(BuildTools) 
    
    add_executable(genfoo genfoo.cpp) 
    

    xây dựng.sh

    #!/bin/bash 
    
    if [ ! -d crossBuild ]; then 
        cmake -E make_directory crossBuild 
        cmake -E chdir crossBuild cmake .. -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake 
    fi 
    if [ ! -d hostBuild ]; then 
        cmake -E make_directory hostBuild 
        cmake -E chdir hostBuild cmake ../buildTools -DCMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=${PWD}/crossBuild 
    fi 
    cmake --build hostBuild 
    cmake --build crossBuild 
    

Tài liệu tham khảo

Các vấn đề liên quan