Different CMake linking behaviour in CLion and Visual Studio Code

I have a C++ project using CMake and QT. I have it running in CLion, but my license is ending and I wanted to run this in Visual Studio Code on Windows.
Project is structured

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>Proj
CMakeLists.txt
main.cpp
-- src
---- ...
---- ui
---- CMakeLists.txt
</code>
<code>Proj CMakeLists.txt main.cpp -- src ---- ... ---- ui ---- CMakeLists.txt </code>
Proj
CMakeLists.txt
main.cpp
-- src
---- ...
---- ui
---- CMakeLists.txt

Currently ui is independent of other modules thus they are skipped.
CMakeLists.txt have target library Proj_UI_LIB which includes QT.
Main CMakeLists.txt have target executable Proj and link it with Proj_UI_LIB.

Now this is working fine in CLion and I can run the whole project.
However in Visual Studio Code configuration, Proj_UI_LIB build successfully but when building Proj, it is displaying linking errors with QT functions.

! [build] Proj_UI_LIB.vcxproj -> D:DocumentsProgrammingProjbuildsrcuiDebugProj_UI_LIB.lib
[build] main.obj : error LNK2019: unresolved external symbol “__declspec(dllimport) public: __cdecl QApplication::QApplication(int &,char * *,int)” (_imp??0QApplication@@QEAA@AEAHPEAPEADH@Z) referenced in function main [D:DocumentsProgrammingProjbuildProj.vcxproj]
[build] main.obj : error LNK2019: unresolved external symbol “__declspec(dllimport) public: virtual __cdecl QApplication::~QApplication(void)” (_imp??1QApplication@@UEAA@XZ) referenced in function main [D:DocumentsProgrammingProjbuildProj.vcxproj]
[build] main.obj : error LNK2019: unresolved external symbol “__declspec(dllimport) public: static int __cdecl QApplication::exec(void)” (_imp?exec@QApplication@@SAHXZ) referenced in function main [D:DocumentsProgrammingProjbuildProj.vcxproj]
[build] main.obj : error LNK2019: unresolved external symbol “__declspec(dllimport) public: void __cdecl QWidget::show(void)” (_imp?show@QWidget@@QEAAXXZ) referenced in function main [D:DocumentsProgrammingProjbuildProj.vcxproj]
[build] Proj_UI_LIB.lib(mainwindow.obj) : error LNK2019: unresolved external symbol “__declspec(dllimport) void __cdecl qt_assert(char const *,char const *,int)” (_imp?qt_assert@@YAXPEBD0H@Z) referenced in function “private: static unsigned __int64 __cdecl QAnyStringView::encodeType(char const *,__int64)” (??$encodeType@D@QAnyStringView@@CA_KPEBD_J@Z) [D:DocumentsProgrammingProjbuildProj.vcxproj]

[build] Proj_UI_LIB.lib(OpenDialog.obj) : error LNK2019: unresolved external symbol “__declspec(dllimport) public: class QString & __cdecl QString::operator=(class QString &&)” (_imp??4QString@@QEAAAEAV0@$$QEAV0@@Z) referenced in function “public: __cdecl radui::OpenDialog::OpenDialog(class QWidget *,class std::basic_string<char,struct std::char_traits,class std::allocator > const &,class std::basic_string<char,struct std::char_traits,class std::allocator > const &)” (??0OpenDialog@radui@@QEAA@PEAVQWidget@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@1@Z) [D:DocumentsProgrammingProjbuildProj.vcxproj]
[build] Proj_UI_LIB.lib(OpenDialog.obj) : error LNK2019: unresolved external symbol “__declspec(dllimport) public: static class QString __cdecl QFileDialog::getOpenFileName(class QWidget *,class QString const &,class QString const &,class QString const &,class QString *,class QFlags)” (_imp?getOpenFileName@QFileDialog@@SA?AVQString@@PEAVQWidget@@AEBV2@11PEAV2@V?$QFlags@W4Option@QFileDialog@@@@@Z) referenced in function “public: class QString __cdecl radui::OpenDialog::openPhoto(void)” (?openPhoto@OpenDialog@radui@@QEAA?AVQString@@XZ) [D:DocumentsProgrammingProjbuildProj.vcxproj]
[build] Proj_UI_LIB.lib(OpenDialog.obj) : error LNK2019: unresolved external symbol “__declspec(dllimport) public: static class QString __cdecl QFileDialog::getExistingDirectory(class QWidget *,class QString const &,class QString const &,class QFlags)” (_imp?getExistingDirectory@QFileDialog@@SA?AVQString@@PEAVQWidget@@AEBV2@1V?$QFlags@W4Option@QFileDialog@@@@@Z) referenced in function “public: class QString __cdecl radui::OpenDialog::openDir(void)” (?openDir@OpenDialog@radui@@QEAA?AVQString@@XZ) [D:DocumentsProgrammingProjbuildProj.vcxproj]

Do you know what can be the differences in CLion cmake configuration and Visual Studio Code resulting in linking errors?

This is my main CMakeLists.txt

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>cmake_minimum_required(VERSION 3.14)
project(Proj)
set(CMAKE_CXX_STANDARD 23)
IF (WIN32)
set(CMAKE_PREFIX_PATH "D:\lib\Qt\6.6.0\mingw_64\lib\cmake")
ELSE()
set(CMAKE_PREFIX_PATH "/home/rad/lib/Qt/6.4.3/gcc_64/lib/cmake")
ENDIF()
add_subdirectory(src)
add_executable(Proj main.cpp)
# Ideally I don't want to add QT at this level but I am fine if it works
find_package(Qt6 COMPONENTS
Core
Gui
Widgets
LinguistTools
REQUIRED)
target_link_libraries(Proj
Proj_UI_LIB
Qt::Core
Qt::Gui
Qt::Widgets
)
if (WIN32)
set(DEBUG_SUFFIX)
if (MSVC AND CMAKE_BUILD_TYPE MATCHES "Debug")
set(DEBUG_SUFFIX "d")
endif ()
set(QT_INSTALL_PATH "${CMAKE_PREFIX_PATH}")
if (NOT EXISTS "${QT_INSTALL_PATH}/bin")
set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..")
if (NOT EXISTS "${QT_INSTALL_PATH}/bin")
set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..")
endif ()
endif ()
if (EXISTS "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory
"$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/platforms/")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll"
"$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/platforms/")
endif ()
foreach (QT_LIB Core Gui Widgets)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"${QT_INSTALL_PATH}/bin/Qt6${QT_LIB}${DEBUG_SUFFIX}.dll"
"$<TARGET_FILE_DIR:${PROJECT_NAME}>")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"${QT_INSTALL_PATH}/bin/Qt6${QT_LIB}${DEBUG_SUFFIX}.dll"
"$<TARGET_FILE_DIR:${PROJECT_NAME}>/test")
endforeach (QT_LIB)
if (NOT EXISTS "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/imageformats/")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/imageformats/")
endif()
foreach (PHOTO_LIB gif ico jpeg svg)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"${QT_INSTALL_PATH}/plugins/imageformats/q${PHOTO_LIB}.dll"
"$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/imageformats/")
endforeach (PHOTO_LIB)
endif ()
</code>
<code>cmake_minimum_required(VERSION 3.14) project(Proj) set(CMAKE_CXX_STANDARD 23) IF (WIN32) set(CMAKE_PREFIX_PATH "D:\lib\Qt\6.6.0\mingw_64\lib\cmake") ELSE() set(CMAKE_PREFIX_PATH "/home/rad/lib/Qt/6.4.3/gcc_64/lib/cmake") ENDIF() add_subdirectory(src) add_executable(Proj main.cpp) # Ideally I don't want to add QT at this level but I am fine if it works find_package(Qt6 COMPONENTS Core Gui Widgets LinguistTools REQUIRED) target_link_libraries(Proj Proj_UI_LIB Qt::Core Qt::Gui Qt::Widgets ) if (WIN32) set(DEBUG_SUFFIX) if (MSVC AND CMAKE_BUILD_TYPE MATCHES "Debug") set(DEBUG_SUFFIX "d") endif () set(QT_INSTALL_PATH "${CMAKE_PREFIX_PATH}") if (NOT EXISTS "${QT_INSTALL_PATH}/bin") set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..") if (NOT EXISTS "${QT_INSTALL_PATH}/bin") set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..") endif () endif () if (EXISTS "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll") add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/platforms/") add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll" "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/platforms/") endif () foreach (QT_LIB Core Gui Widgets) add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${QT_INSTALL_PATH}/bin/Qt6${QT_LIB}${DEBUG_SUFFIX}.dll" "$<TARGET_FILE_DIR:${PROJECT_NAME}>") add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${QT_INSTALL_PATH}/bin/Qt6${QT_LIB}${DEBUG_SUFFIX}.dll" "$<TARGET_FILE_DIR:${PROJECT_NAME}>/test") endforeach (QT_LIB) if (NOT EXISTS "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/imageformats/") add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/imageformats/") endif() foreach (PHOTO_LIB gif ico jpeg svg) add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${QT_INSTALL_PATH}/plugins/imageformats/q${PHOTO_LIB}.dll" "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/imageformats/") endforeach (PHOTO_LIB) endif () </code>
cmake_minimum_required(VERSION 3.14)
project(Proj)

set(CMAKE_CXX_STANDARD 23)

IF (WIN32)
    set(CMAKE_PREFIX_PATH "D:\lib\Qt\6.6.0\mingw_64\lib\cmake")
ELSE()
    set(CMAKE_PREFIX_PATH "/home/rad/lib/Qt/6.4.3/gcc_64/lib/cmake")
ENDIF()

add_subdirectory(src)


add_executable(Proj main.cpp)

# Ideally I don't want to add QT at this level but I am fine if it works
find_package(Qt6 COMPONENTS
        Core
        Gui
        Widgets
        LinguistTools
        REQUIRED)
target_link_libraries(Proj
        Proj_UI_LIB
        Qt::Core
        Qt::Gui
        Qt::Widgets
        )

if (WIN32)
    set(DEBUG_SUFFIX)
    if (MSVC AND CMAKE_BUILD_TYPE MATCHES "Debug")
        set(DEBUG_SUFFIX "d")
    endif ()
    set(QT_INSTALL_PATH "${CMAKE_PREFIX_PATH}")
    if (NOT EXISTS "${QT_INSTALL_PATH}/bin")
        set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..")
        if (NOT EXISTS "${QT_INSTALL_PATH}/bin")
            set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..")
        endif ()
    endif ()
    if (EXISTS "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll")
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                COMMAND ${CMAKE_COMMAND} -E make_directory
                "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/platforms/")
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                COMMAND ${CMAKE_COMMAND} -E copy
                "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll"
                "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/platforms/")
    endif ()
    foreach (QT_LIB Core Gui Widgets)
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                COMMAND ${CMAKE_COMMAND} -E copy
                "${QT_INSTALL_PATH}/bin/Qt6${QT_LIB}${DEBUG_SUFFIX}.dll"
                "$<TARGET_FILE_DIR:${PROJECT_NAME}>")
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                COMMAND ${CMAKE_COMMAND} -E copy
                "${QT_INSTALL_PATH}/bin/Qt6${QT_LIB}${DEBUG_SUFFIX}.dll"
                "$<TARGET_FILE_DIR:${PROJECT_NAME}>/test")
    endforeach (QT_LIB)
    if (NOT EXISTS "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/imageformats/")
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/imageformats/")
    endif()
    foreach (PHOTO_LIB gif ico jpeg svg)
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                COMMAND ${CMAKE_COMMAND} -E copy
                "${QT_INSTALL_PATH}/plugins/imageformats/q${PHOTO_LIB}.dll"
                "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/imageformats/")
    endforeach (PHOTO_LIB)
endif ()

And this is UI CMakeLists.txt

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
IF (WIN32)
set(CMAKE_PREFIX_PATH "D:\lib\Qt\6.6.0\mingw_64\lib\cmake")
ELSE()
set(CMAKE_PREFIX_PATH "/home/rad/lib/Qt/6.4.3/gcc_64/lib/cmake")
ENDIF()
find_package(Qt6 COMPONENTS
Core
Gui
Widgets
LinguistTools
REQUIRED)
set(TS_FILES
translations/Proj_pl_PL.ts)
qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
set(WIDGETS_SOURCES
widgets/dynamic/Action.h
widgets/static/mainwindow.cpp
widgets/static/mainwindow.h
widgets/static/mainwindow.ui
widgets/dynamic/dirtree.h
widgets/dynamic/dirtree.cpp
widgets/dynamic/dirtree.ui
)
set(UI_SOURCES
OpenDialog.cpp
OpenDialog.h
${TS_FILES}
)
set(MODEL_SOURCES
)
add_library(Proj_UI_LIB
${UI_SOURCES}
${MODEL_SOURCES}
${WIDGETS_SOURCES}
${QM_FILES}
)
# To use C++17 in VSC
if(MSVC)
target_compile_options(Proj_UI_LIB PUBLIC "/Zc:__cplusplus")
endif(MSVC)
target_include_directories(Proj_UI_LIB PUBLIC
../..)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/widgets/dynamic)
target_link_libraries(Proj_UI_LIB
Qt::Core
Qt::Gui
Qt::Widgets
)
</code>
<code> set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) IF (WIN32) set(CMAKE_PREFIX_PATH "D:\lib\Qt\6.6.0\mingw_64\lib\cmake") ELSE() set(CMAKE_PREFIX_PATH "/home/rad/lib/Qt/6.4.3/gcc_64/lib/cmake") ENDIF() find_package(Qt6 COMPONENTS Core Gui Widgets LinguistTools REQUIRED) set(TS_FILES translations/Proj_pl_PL.ts) qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES}) set(WIDGETS_SOURCES widgets/dynamic/Action.h widgets/static/mainwindow.cpp widgets/static/mainwindow.h widgets/static/mainwindow.ui widgets/dynamic/dirtree.h widgets/dynamic/dirtree.cpp widgets/dynamic/dirtree.ui ) set(UI_SOURCES OpenDialog.cpp OpenDialog.h ${TS_FILES} ) set(MODEL_SOURCES ) add_library(Proj_UI_LIB ${UI_SOURCES} ${MODEL_SOURCES} ${WIDGETS_SOURCES} ${QM_FILES} ) # To use C++17 in VSC if(MSVC) target_compile_options(Proj_UI_LIB PUBLIC "/Zc:__cplusplus") endif(MSVC) target_include_directories(Proj_UI_LIB PUBLIC ../..) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/widgets/dynamic) target_link_libraries(Proj_UI_LIB Qt::Core Qt::Gui Qt::Widgets ) </code>

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

IF (WIN32)
    set(CMAKE_PREFIX_PATH "D:\lib\Qt\6.6.0\mingw_64\lib\cmake")
ELSE()
    set(CMAKE_PREFIX_PATH "/home/rad/lib/Qt/6.4.3/gcc_64/lib/cmake")
ENDIF()

find_package(Qt6 COMPONENTS
        Core
        Gui
        Widgets
        LinguistTools
        REQUIRED)

set(TS_FILES
        translations/Proj_pl_PL.ts)

qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})

set(WIDGETS_SOURCES
        widgets/dynamic/Action.h
        widgets/static/mainwindow.cpp
        widgets/static/mainwindow.h
        widgets/static/mainwindow.ui
        widgets/dynamic/dirtree.h
        widgets/dynamic/dirtree.cpp
        widgets/dynamic/dirtree.ui
)

set(UI_SOURCES
        OpenDialog.cpp
        OpenDialog.h
        ${TS_FILES}
)

set(MODEL_SOURCES
        )
        
add_library(Proj_UI_LIB
        ${UI_SOURCES}
        ${MODEL_SOURCES}
        ${WIDGETS_SOURCES}
        ${QM_FILES}
)

# To use C++17 in VSC
if(MSVC)
        target_compile_options(Proj_UI_LIB PUBLIC "/Zc:__cplusplus")
endif(MSVC)

target_include_directories(Proj_UI_LIB PUBLIC
        ../..)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/widgets/dynamic)

target_link_libraries(Proj_UI_LIB
        Qt::Core
        Qt::Gui
        Qt::Widgets
        )

I am using target_link_libraries(Proj_UI_LIB Qt::Core Qt::Gui Qt::Widgets), I have instructions to copy .dll files to .exe location (I even copied them myself), and I don’t understand why this configuration has linking issues with VSC cmake but works fine with CLion.

How can I configure CMakeLists.txt to use the same kit for both instances as I suspect that’s the difference.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật