使用CMake编译测试可执行文件

时间:2015-11-10 17:42:08

标签: c unit-testing cmake

我正在使用CLion在C中编写一个程序,而CLion又将CMake用于其构建系统。虽然到目前为止我喜欢它,但我遇到了以下问题:我想要有两个可执行文件,一个“普通”,可以构建用于调试或发布,另一个用于测试。测试可执行文件将包括我的所有单元测试。为此,我编译并安装了一个名为cmocka的库,它似乎运行良好。但是,我的主要目标是允许人们使用CMakeLists.txt文件构建正常的可执行文件,而无需安装测试可执行文件。只有在想要编译单元测试时才需要CMocka安装。这是我无法弄清楚该怎么做的部分因为无论我做什么,如果我想让测试可执行文件都有libcmocka,那么我就无法在不使用libcmocka的情况下获得正常的可执行文件。

以下是我的CMakeLists.txt文件,它在允许我编译两个可执行文件的意义上起作用,但它不能完成上述要求。

cmake_minimum_required(VERSION 3.3)
project(Crypto_Project)

include_directories(/usr/local/include)
find_library(CMOCKA_LIBRARY libcmocka.so.0)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -lcmocka")

#Normal executable
set(SOURCE_FILES crypto_project.c ap_int.c ap_int.h)
add_executable(Crypto_Project ${SOURCE_FILES})
target_link_libraries(Crypto_Project ${CMOCKA_LIBRARY})

#Testing executable
set(TESTING_SOURCE_FILES ap_int_tests.c ap_int.c ap_int.h)
add_executable(Test_Crypto_Project ${TESTING_SOURCE_FILES})
target_link_libraries(Test_Crypto_Project ${CMOCKA_LIBRARY})

显然,为了不用cmocka编译,我需要从普通的可执行文件中删除target_link_libraries(Crypto_Project ${CMOCKA_LIBRARY})以及在没有-lcmocka标志的情况下进行编译,但是,我无法弄清楚如何进行编译测试使用-lcmocka和没有它的普通可执行文件。如果我从普通可执行文件中删除target_link_libraries(Crypto_Project ${CMOCKA_LIBRARY}),则会出现以下错误:~/.CLion12/system/cmake/generated/5c245747/5c245747/Debug/Crypto_Project: error while loading shared libraries: libcmocka.so.0: cannot open shared object file: No such file or directory

我发布到了CLion论坛,但截至尚未得到答复:https://devnet.jetbrains.com/thread/475277?tstart=0我希望有人可以提供帮助。

提前谢谢。

1 个答案:

答案 0 :(得分:1)

更改此行

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")

到这个

-lcmocka

当您致电

时,CMake应自动添加target_link_libraries(Test_Crypto_Project ${CMOCKA_LIBRARY}) 标志
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ItemHolder>{

   private ArrayList<Item> items;

    public MyAdapter(ArrayList<Item> items) {
        this.items = items;
    }

    @Override
    public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_item_layout, parent, false);
        view.setOnClickListener(mOnClickListener);
        ItemHolder orderObjectHolder = new ItemHolder(view);
        return orderObjectHolder;
    }

    @Override
    public void onBindViewHolder(ItemHolder holder, int position) {
        final Item item = items.get(position);
        holder.countText.setText("");
        holder.currentItem = item;
    }

    @Override
    public int getItemCount() {
        return items.size();
    }


    public static class ItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        public Item currentItem;
        TextView countText;
        Button AddBtn, SubBtn;

        public ItemHolder(View itemView) {
            super(itemView);
            countText = (TextView) itemView.findViewById(R.id.order_item_name);

            AddBtn = (Button) itemView.findViewById(R.id.order_service1_btn_add);
            SubBtn = (Button) itemView.findViewById(R.id.order_service1_btn_sub);

            AddBtn.setOnClickListener(this);
            SubBtn.setOnClickListener(this);
        }


    }
}