Note: I’m new to coding and CMake, so I might be missing something obvious. Please be patient with me!
I’m working on a C programming practice project in CLion where I have multiple independent .c files (q1.c, q2.c, q3.c, etc.) in a PRACTICE/ folder. Each file contains its own main() function and should compile into a separate, independent executable.
Problem: Every time I create a new .c file, CMake automatically links it with the previous file I was working on, causing “duplicate symbol ‘_main’” linker errors. For example:
-
When building
q12, it links bothq12.c.oandq13.c.o -
When building
q11, it linked bothq11.c.oandq10.c.o
Error Message:
FAILED: bin/q12
: && /usr/bin/cc -g -arch arm64 -Wl,-search_paths_first -Wl,-headerpad_max_install_names
CMakeFiles/q12.dir/PRACTICE/q12.c.o CMakeFiles/q12.dir/PRACTICE/q13.c.o -o bin/q12 && :
duplicate symbol '_main' in:
CMakeFiles/q12.dir/PRACTICE/q13.c.o
CMakeFiles/q12.dir/PRACTICE/q12.c.o
ld: 1 duplicate symbols
clang: error: linker command failed with exit code 1 (use -v to see invocation)
My CMakeLists.txt:
cmake
cmake_minimum_required(VERSION 3.16)
project(SEM_1 C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
file(GLOB PRACTICE_SOURCES "${CMAKE_SOURCE_DIR}/PRACTICE/*.c")
set(EXCLUDE_EXECUTABLES "common" "shared_helpers")
foreach(src IN LISTS PRACTICE_SOURCES)
get_filename_component(name ${src} NAME_WE)
list(FIND EXCLUDE_EXECUTABLES ${name} _idx)
if(_idx EQUAL -1)
add_executable(${name} ${src})
else()
message(STATUS "Skipping ${name} (excluded)")
endif()
endforeach()
What I’ve tried:
-
Deleted
cmake-build-debugfolder and reloaded CMake -
Used
Tools → CMake → Reset Cache and Reload Project -
Verified that
add_executable(${name} ${src})only references${src}with no hardcoded files -
Cleaned and rebuilt the project multiple times
-
Invalidated CLion caches and restarted
The frustrating part: These steps DO work and fix the issue temporarily, but I have to repeat this entire process (deleting cache, reloading CMake, cleaning build) for every single new file I create. When I create q14.c, it will link with q13.c again, and I’ll have to go through the whole cleanup process once more. This is extremely frustrating and time-consuming when I’m just trying to practice coding problems.
Environment:
-
IDE: CLion (macOS, Apple Silicon)
-
CMake version: 3.16+
-
Compiler: Apple Clang
-
Build system: Ninja
Expected behavior: Each executable should be built from only its own source file automatically. q12 should only link q12.c.o, not q13.c.o. And when I create a new file, it should just work without requiring manual cache deletion.
Question: Is there a way to configure CMake or CLion to automatically handle this properly so I don’t have to manually delete caches and reload for every single new file? Why does CMake keep persisting these incorrect file associations, and how can I make the build system truly independent for each source file without manual intervention each time?
I’m learning and would really appreciate any guidance on what I might be doing wrong or what steps I should take to automate this properly. Thank you!