我正在为带有交叉工具链的嵌入式目标构建一个库。要生成这个库,我必须先用我的主机编译器创建另一个二进制文件。该二进制文件为我的库生成一些标头。我到处都发现我不能在同一个
CMakeLists.txt
文件中使用两个不同的编译器。 CMake 的设计初衷并非如此。
所以我试图用一个子目录和 2
CMakeLists.txt
来做到这一点。我有一个主要的 CMakeLists.txt
文件构建库。在这个主要的 add_subdirectory
文件中有一个 CMakeLists.txt
调用,用于在单独的 cmake 文件中生成我的二进制文件。问题是我不能告诉我的主 Cmake 在主 Cmake 之前构建子目录。
我的问题在一个非常简约的例子中:
[arthur ] ls
CMakeLists.txt my_subdir source.c
[arthur ] ls my_subdir/
CMakeLists.txt main.c
最上面的cmake文件:
[arthur ] cat CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
message("Invoke my_subdir/CMakeList.txt")
add_subdirectory (my_subdir)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_VERBOSE_MAKEFILE ON)
#set_property(GLOBAL PROPERTY GLOBAL_DEPENDS_DEBUG_MODE 1)
project(doing_test)
# Build the skblock library
set(MY_GREAT_LIBRARY_SOURCE source.c)
add_library(great_library STATIC ${MY_GREAT_LIBRARY_SOURCE})
target_include_directories(great_library PRIVATE PUBLIC ".")
set_target_properties(great_library PROPERTIES OUTPUT_NAME my_super_great_library)
子目录cmake文件:
[arthur ] cat my_subdir/CMakeLists.txt
project (coucou)
message("Building mysubdir sources...")
# add the executable
add_executable(my_needed_subbinary main.c)
建筑:
[arthur ] mkdir build && cd build
[arthur ] cmake .. && cmake --build .
Invoke my_subdir/CMakeList.txt
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
Building mysubdir sources...
-- Configuring done
-- Generating done
-- Build files have been written to: /home/arthur/work/repository/cmake_test/build
/usr/bin/cmake -S/home/arthur/work/repository/cmake_test -B/home/arthur/work/repository/cmake_test/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/arthur/work/repository/cmake_test/build/CMakeFiles /home/arthur/work/repository/cmake_test/build/CMakeFiles/progress.marks
/usr/bin/make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/arthur/work/repository/cmake_test/build'
/usr/bin/make -f CMakeFiles/great_library.dir/build.make CMakeFiles/great_library.dir/depend
make[2]: Entering directory '/home/arthur/work/repository/cmake_test/build'
cd /home/arthur/work/repository/cmake_test/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/arthur/work/repository/cmake_test /home/arthur/work/repository/cmake_test /home/arthur/work/repository/cmake_test/build /home/arthur/work/repository/cmake_test/build /home/arthur/work/repository/cmake_test/build/CMakeFiles/great_library.dir/DependInfo.cmake --color=
Scanning dependencies of target great_library
make[2]: Leaving directory '/home/arthur/work/repository/cmake_test/build'
/usr/bin/make -f CMakeFiles/great_library.dir/build.make CMakeFiles/great_library.dir/build
make[2]: Entering directory '/home/arthur/work/repository/cmake_test/build'
[ 25%] Building C object CMakeFiles/great_library.dir/source.c.o
/usr/bin/cc -I/home/arthur/work/repository/cmake_test/. -o CMakeFiles/great_library.dir/source.c.o -c /home/arthur/work/repository/cmake_test/source.c
[ 50%] Linking C static library libmy_super_great_library.a
/usr/bin/cmake -P CMakeFiles/great_library.dir/cmake_clean_target.cmake
/usr/bin/cmake -E cmake_link_script CMakeFiles/great_library.dir/link.txt --verbose=1
/usr/bin/ar qc libmy_super_great_library.a CMakeFiles/great_library.dir/source.c.o
/usr/bin/ranlib libmy_super_great_library.a
make[2]: Leaving directory '/home/arthur/work/repository/cmake_test/build'
[ 50%] Built target great_library
/usr/bin/make -f my_subdir/CMakeFiles/my_needed_subbinary.dir/build.make my_subdir/CMakeFiles/my_needed_subbinary.dir/depend
make[2]: Entering directory '/home/arthur/work/repository/cmake_test/build'
Scanning dependencies of target my_needed_subbinary
make[2]: Leaving directory '/home/arthur/work/repository/cmake_test/build'
/usr/bin/make -f my_subdir/CMakeFiles/my_needed_subbinary.dir/build.make my_subdir/CMakeFiles/my_needed_subbinary.dir/build
make[2]: Entering directory '/home/arthur/work/repository/cmake_test/build'
[ 75%] Building C object my_subdir/CMakeFiles/my_needed_subbinary.dir/main.c.o
[100%] Linking C executable my_needed_subbinary
make[2]: Leaving directory '/home/arthur/work/repository/cmake_test/build'
[100%] Built target my_needed_subbinary
make[1]: Leaving directory '/home/arthur/work/repository/cmake_test/build'
/usr/bin/cmake -E cmake_progress_start /home/arthur/work/repository/cmake_test/build/CMakeFiles 0
这是基本需求,但我无法解决我的问题。我想在构建主库之前构建我的
main.c
以生成我的子目录二进制文件。我们可以在输出中看到他先调用了子目录的CMakeLists.txt
但没有构建它。
我尝试在顶部 cmake 添加
add_dependencies
命令但没有成功。
add_dependencies(great_library my_subdir) -> don't know my_subdir project
add_dependencies(great_library coucou) -> don't know coucou project
完全不同cmake的子项目。所以运行一个完全不同的cmake。
# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(doing_test)
add_custom_command(
COMMENT "generate the includes that I wanna"
DEPENDS
my_subdir/main.c
my_subdir/CMakeLists.txt
OUTPUT
${CMAKE_CURRENT_BINARY_DIR}/my_subdir/genincludes/include1.h
${CMAKE_CURRENT_BINARY_DIR}/my_subdir/genincludes/include2.h
${CMAKE_CURRENT_BINARY_DIR}/my_subdir/genincludes/etc.h
COMMAND
${CMAKE_COMMAND}
-B ${CMAKE_CURRENT_BINARY_DIR}/my_subdir
-S ${CMAKE_CURRENT_SOURCE_DIR}/my_subdir
-D CMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_CURRENT_BINARY_DIR}/my_subdir/bin
COMMAND
${CMAKE_COMMAND}
--build ${CMAKE_CURRENT_BINARY_DIR}/my_subdir
COMMAND
${CMAKE_CURRENT_BINARY_DIR}/my_subdir/bin/my_needed_subbinary
--outputdir ${CMAKE_CURRENT_BINARY_DIR}/my_subdir/genincludes
)
add_library(great_library
source.c
# List the needed dependencies. ONE BY ONE
${CMAKE_CURRENT_BINARY_DIR}/my_subdir/genincludes/include1.h
${CMAKE_CURRENT_BINARY_DIR}/my_subdir/genincludes/include2.h
${CMAKE_CURRENT_BINARY_DIR}/my_subdir/genincludes/etc.h
)
target_include_directories(great_library PUBLIC
${CMAKE_CURRENT_BINARY_DIR}/my_subdir/genincludes
.
)