CMake Automatically Links Each New C File with Previous File - Have to Delete Cache for Every New File (CLion)

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 both q12.c.o and q13.c.o

  • When building q11, it linked both q11.c.o and q10.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:

  1. Deleted cmake-build-debug folder and reloaded CMake

  2. Used Tools → CMake → Reset Cache and Reload Project

  3. Verified that add_executable(${name} ${src}) only references ${src} with no hardcoded files

  4. Cleaned and rebuilt the project multiple times

  5. 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!

This is either a user issue or a clion issue.

First of all - globbing for sources is not recommended. I kinda understand why you do it here, but just so you know. It has problems when the files are added or removed without re-running cmake.

Anyway. I tried it with a command line only, and it works as expected. I does not seem possible (and I tried to break it, even with an in-source build), but I’m on Linux.

My advice would be to try with a command line only to elliminate at least one factor (CLion)