平臺
-
OS: Ubuntu 20.04
-
cmake: 3.16.3
-
IDE: Qt Creator 4.11.1
Based on Qt 5.14.1 (GCC 5.3.1 20160406 (Red Hat 5.3.1-6), 64 bit)
Built on Feb 5 2020 12:48:30
From revision b2ddeacfb5
Copyright 2008-2019 The Qt Company Ltd. All rights reserved.
The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -
GCC/G++
GCC: Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: …/src/configure -v --with-pkgversion=‘Ubuntu 9.4.0-1ubuntu1~20.04.2’ --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-9QDOt0/gcc-9-9.4.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2)G++ Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: …/src/configure -v --with-pkgversion=‘Ubuntu 9.4.0-1ubuntu1~20.04.2’ --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-9QDOt0/gcc-9-9.4.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2)
源碼
源碼結構
├── atool.c
├── atool.cpp
├── CMakeLists.txt
├── include
│ └── atool.h
└── main.cpp
-
CMakeLists.txt
cmake_minimum_required(VERSION 3.5) project(Test LANGUAGES CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_executable(test main.cpp atool.c )
-
atool.h
#ifndef ATOOL_H #define ATOOL_H #ifdef __cplusplus extern "C" { #endif //代碼部分 int atoolInfo(); #ifdef __cplusplus } #endif #endif // ATOOL_H
-
main.cpp
#include <stdio.h> #include "include/atool.h" int main(int argc, char** argv){ printf("%s argc=%d", __FUNCTION__, argc); if(argc > 0){ for(int i = 0; i < argc; i ++){ printf(" arg[%d]=%s", i, argv[i]); } } printf("\n"); atoolInfo(); }
-
atool.cpp
#include "include/atool.h" #include "stdio.h" int atoolInfo(){ printf("atoolInfo\n"); return 0; }
問題 1: undefined reference to `atoolInfo’
LOG
17:32:36: 為項目Test執(zhí)行步驟 …
17:32:36: 正在啟動 “/usr/bin/cmake” --build . --target all[ 50%] Linking CXX executable test
/usr/bin/ld: CMakeFiles/test.dir/main.cpp.o: in functionmain': /xxx/main.cpp:13: undefined reference to
atoolInfo’
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/test.dir/build.make:84: test] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/test.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
17:32:36: 進程"/usr/bin/cmake"退出,退出代碼 2 。
Error while building/deploying project Test (kit: Desktop Qt 5.14.2 GCC 64bit)
When executing step “CMake Build”
17:32:36: Elapsed time: 00:00.
一個很初級的問題, 檢查了文件名, 文件路徑, 函數(shù)申明等等… 沒發(fā)現(xiàn)問題所在, 轉悠了好久, 最終發(fā)現(xiàn)問題出在: project(Test LANGUAGES CXX), 解決方法是: project(Test LANGUAGES CXX C)
在CMake構建系統(tǒng)中,project()
命令是配置文件(CMakeLists.txt)中的一個關鍵指令,用于定義項目的基本屬性,如項目名稱、版本以及所使用的編程語言。給定的project(Test LANGUAGES CXX C)
行可以這樣解讀:
-
項目名稱:這里的項目名稱是“Test”,這意味著CMake將創(chuàng)建一個名為“Test”的項目,并且在內部變量
CMAKE_PROJECT_NAME
中存儲這個名稱。 - LANGUAGES:該選項指定了項目所使用的編程語言。在這個例子中,指定的語言包括C++(CXX)和C。這意味著CMake將在構建時準備相應的編譯器工具鏈,并為這兩種語言設置適當?shù)木幾g和鏈接規(guī)則。
-
含義:當CMake解析到這一行時,它會根據指定的語言來尋找并處理相關的源文件。例如,對于C++源碼(
.cpp
文件)和C源碼(.c
文件),CMake將會生成對應的編譯目標(對象文件或庫)。此外,如果后續(xù)CMakeLists.txt中有使用到特定語言的命令(如add_executable
或add_library
),CMake將知道應該處理哪些類型的源代碼文件。
總結來說,這行命令主要是初始化一個名為“Test”的CMake項目,同時告知CMake此項目涉及到C和C++兩種編程語言的源代碼編譯。
cmake_minimum_required(VERSION 3.5)
project(Test LANGUAGES CXX C)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(test
main.cpp
atool.c
)
另外, 在頭文件中, 函數(shù)的聲明需要使用 extern "C"
否則同樣會出現(xiàn)上述的問題.
#ifndef ATOOL_H
#define ATOOL_H
#ifdef __cplusplus
extern "C"
{
#endif
//代碼部分
int atoolInfo();
#ifdef __cplusplus
}
#endif
int funcNoExternC();
#endif // ATOOL_H
如以上源碼中, 函數(shù)funcNoExternC() 在此項目中編譯出錯
問題2:
LOG
18:08:33: 為項目Test執(zhí)行步驟 …
18:08:33: 正在啟動 “/usr/bin/cmake” --build . --target allScanning dependencies of target test
[ 33%] Building C object CMakeFiles/test.dir/main.c.o
[ 66%] Building C object CMakeFiles/test.dir/atool.c.o
[100%] Linking C executable test
gcc: warning: CMakeFiles/test.dir/main.c.o: linker input file unused because linking not done
gcc: warning: CMakeFiles/test.dir/atool.c.o: linker input file unused because linking not done
[100%] Built target test
18:08:33: 進程"/usr/bin/cmake"正常退出。
18:08:33: Elapsed time: 00:00.
這是什么錯誤: linker input file unused because linking not done ??
通用的解釋, “這個提示通常出現(xiàn)在構建過程中,特別是使用CMake、Makefile或者其他構建工具鏈時。
當一個項目在編譯階 段生成了某些目標文件(通常是.o
或.obj
這樣的對象文件),但隨后的鏈接步驟并未執(zhí)行時,就可能出現(xiàn)這個提示。
如果某個目標文件被傳遞給鏈接器作為輸入,但由于某種原因鏈接步驟未被執(zhí)行(例如,可能由于構建目標只涉及到了編譯特定模塊而沒有進一步鏈接到可執(zhí)行文件,或者在條件編譯下該模塊不參與最終鏈接等),
那么鏈接器就不會使用到這些目標文件,從而產生“l(fā)inker input file unused because linking not done”這樣的警告信息。
這通常意味著構建系統(tǒng)的配置需要進一步檢查和調整以確保所有的目標文件在適當?shù)臅r候都被正確地鏈接?!?/p>
原因:
-
CMakeLists.txt
cmake_minimum_required(VERSION 3.5) project(Test LANGUAGES CXX C) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) #原因: set(CMAKE_C_FLAGS "-c") add_executable(test main.c atool.c )
導致這個問題原因有2點:
-
set(CMAKE_C_FLAGS “-c”):
-c
參數(shù)在CFLAGS
或直接在GCC命令行中使用時,是一個編譯器標志,它告訴GCC只執(zhí)行編譯和匯編步驟,而不進行鏈接。CMAKE_C_FLAGS “-c”
在CMake中,
set(CMAKE_C_FLAGS "-c")
的作用是設置C語言編譯器的編譯選項。具體來說,這里設置了-c
選項,該選項通常用于告訴編譯器只進行編譯而不進行鏈接。-
c
選項的含義是生成目標文件而不是可執(zhí)行文件。當你編寫一個大型的程序時,通常會將源代碼文件分為多個文件,并通過編譯每個源文件生成對應的目標文件,最后再將這些目標文件鏈接到一起生成最終的可執(zhí)行文件。使用c
選項告訴編譯器只執(zhí)行編譯過程,生成目標文件,而不進行鏈接。
這通常用于加速編譯過程,特別是在修改了部分源文件但不需要重新鏈接整個項目時。然而,如果你使用了這個選項,你可能需要手動執(zhí)行鏈接步驟來生成最終的可執(zhí)行文件。
需要注意的是,直接設置
CMAKE_C_FLAGS
可能會覆蓋其他可能由CMake自動生成的編譯選項。更推薦的做法是使用target_compile_options
命令,它允許你為特定的目標設置編譯選項,而不是全局地設置CMAKE_C_FLAGS
。例如:target_compile_options(your_target_name PRIVATE -c)
這樣可以確保你的選項只應用于特定的目標。
-
-
main**.c** 而不是 main**.cpp**
在CMake中,設置
-c
選項僅編譯源文件而不進行鏈接。這意味著如果你只編譯了C源文件,而沒有鏈接生成可執(zhí)行文件,你可能會看到類似于"linker input file unused because linking not done"的錯誤。這個錯誤表明編譯器在鏈接階段沒有找到足夠的信息來生成可執(zhí)行文件,因為只有編譯了C文件而沒有鏈接。
解決這個問題的改法有兩種:
-
保留main**.c,** 刪除set(CMAKE_C_FLAGS “-c”)
-
改用main**.cpp,** 保留set(CMAKE_C_FLAGS “-c”)
參考
[C error: undefined reference to function, but it IS defined](https://stackoverflow.com/questions/5559250/c-error-undefined-reference-to-function-but-it-is-defined)文章來源:http://www.zghlxwxcb.cn/news/detail-806455.html
關于 C++ 中的 extern “C”文章來源地址http://www.zghlxwxcb.cn/news/detail-806455.html
到了這里,關于Ubuntu使用QtCreator + CMake 開發(fā)C/C++程序的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!